You can subscribe to this list here.
| 2002 |
Jan
|
Feb
(3) |
Mar
|
Apr
(12) |
May
(11) |
Jun
(2) |
Jul
(37) |
Aug
(3) |
Sep
(24) |
Oct
(31) |
Nov
|
Dec
(4) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2003 |
Jan
(3) |
Feb
(7) |
Mar
|
Apr
(11) |
May
(15) |
Jun
(7) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(4) |
Dec
|
| 2004 |
Jan
|
Feb
|
Mar
|
Apr
(1) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
|
From: Michael N. <mne...@us...> - 2002-10-02 18:08:39
|
Update of /cvsroot/ruby-dbi/src/lib/dbi/doc/html In directory usw-pr-cvs1:/tmp/cvs-serv14760/doc/html Removed Files: ChangeLog.html DBD_SPEC.html DBI_SPEC.html ToDo.html Log Message: removed --- ChangeLog.html DELETED --- --- DBD_SPEC.html DELETED --- --- DBI_SPEC.html DELETED --- --- ToDo.html DELETED --- |
|
From: Michael N. <mne...@us...> - 2002-10-02 18:08:39
|
Update of /cvsroot/ruby-dbi/src/lib/dbi/doc In directory usw-pr-cvs1:/tmp/cvs-serv14760/doc Removed Files: ChangeLog create_html Log Message: removed --- ChangeLog DELETED --- --- create_html DELETED --- |
|
From: Michael N. <mne...@us...> - 2002-10-02 18:08:12
|
Update of /cvsroot/ruby-dbi/src/lib/dbi/doc In directory usw-pr-cvs1:/tmp/cvs-serv14498 Removed Files: ToDo DBD_SPEC DBI_SPEC Log Message: moved into directory ../../../doc --- ToDo DELETED --- --- DBD_SPEC DELETED --- --- DBI_SPEC DELETED --- |
|
From: Michael N. <mne...@us...> - 2002-10-02 18:04:12
|
Update of /cvsroot/ruby-dbi/src/build
In directory usw-pr-cvs1:/tmp/cvs-serv13192/build
Added Files:
DBI-VERSIONS Makefile USER cl2html.sh create_changelog.rb
cvs2cl
Log Message:
initial import
--- NEW FILE: DBI-VERSIONS ---
# All times are in UCT
dbi-0-0-17
dbi-0-0-16 2002-07-03 20:10 UTC
dbi-0-0-15 2002-05-21 21:59 UTC
dbi-0-0-14 2002-05-14 18:16 UTC
dbi-0-0-13 2002-04-16 21:59 UTC
dbi-0-0-12 2001-12-28 13:08 UTC
dbi-0-0-11 2001-11-14 13:12 UTC
dbi-0-0-10 2001-10-22 16:09 UTC
dbi-0-0-9 2001-09-07 13:40 UTC
dbi-0-0-8 2001-07-28 12:08 UTC
dbi-0-0-7 2001-07-11 21:59 UTC
dbi-0-0-6 2001-07-06 19:42 UTC
dbi-0-0-5 2001-06-08 20:31 UTC
--- NEW FILE: Makefile ---
all: ChangeLog.html
ChangeLog:
ruby create_changelog.rb
ChangeLog.html: ChangeLog
./cl2html.sh
clean:
rm ChangeLog ChangeLog.html
--- NEW FILE: USER ---
mneumann:'Michael Neumann <mne...@fa...>'
michael:'Michael Neumann <mne...@fa...>'
rainer:'Rainer Perl'
--- NEW FILE: cl2html.sh ---
#!/bin/sh
VIM="/usr/local/bin/gvim -f"
${VIM} +"syn on" +"set nonumber" +"run! syntax/2html.vim" +"w! ChangeLog.html" +"q!" +"q!" ChangeLog
--- NEW FILE: create_changelog.rb ---
require "date"
Dir.chdir ".." # This script should be executed from directory src/ (of ruby-dbi cvs repository)
# modify if needed
FILE = "ChangeLog"
DBI_VERSIONS = "./build/DBI-VERSIONS"
USER = "./build/USER"
lines = File.readlines(DBI_VERSIONS)
START_DATE = "1980-01-01 00:00:00" # a date before all other dates
v = []
lines.each {|l|
l.strip!
next if l.empty? or l[0] == ?#
v << l.split(/\s+/, 2)
}
f = File.new(FILE, "w+")
for i in 0..(v.size-1)
to = v[i]
from = v[i+1] || ["none-tag", START_DATE]
if to[1] != nil
f << "\n\n"
f << "===============================================================================\n"
f << " Tag #{to[0]} (#{to[1]})\n"
f << "===============================================================================\n"
f << "\n\n"
end
to[1] ||= (Date.today + 3).to_s # a day in the future
f << `./build/cvs2cl -g -d:ext:mne...@cv...:/cvsroot/ruby-dbi -l "-d '#{from[1]}<#{to[1]}'" --stdout --prune --utc -U #{USER} --no-wrap -R '^\s*[*]\s*'`
end
f.close
--- NEW FILE: cvs2cl ---
#!/bin/sh
exec perl -w -x $0 ${1+"$@"} # -*- mode: perl; perl-indent-level: 2; -*-
#!perl -w
##############################################################
### ###
### cvs2cl.pl: produce ChangeLog(s) from `cvs log` output. ###
### ###
##############################################################
## $Revision: 1.1 $
## $Date: 2002/10/02 18:04:09 $
## $Author: mneumann $
##
## (C) 1999 Karl Fogel <kf...@re...>, under the GNU GPL.
##
## (Extensively hacked on by Melissa O'Neill <on...@cs...>.)
##
## cvs2cl.pl is free software; you can redistribute it and/or modify
[...1839 lines suppressed...]
happen. Interesting.
Anyway, rather than fix this in Text::Wrap, we might as well write a
new wrap() which has the following much-needed features:
* initial indentation, like current Text::Wrap()
* subsequent line indentation, like current Text::Wrap()
* user chooses among: force-break long words, leave them alone, or die()?
* preserve existing indentation: chopped chunks from an indented line
are indented by same (like this line, not counting the asterisk!)
* optional list of things to preserve on line starts, default ">"
Note that the last two are essentially the same concept, so unify in
implementation and give a good interface to controlling them.
And how about:
Optionally, when encounter a line pre-indented by same as previous
line, then strip the newline and refill, but indent by the same.
Yeah...
|
|
From: Michael N. <mne...@us...> - 2002-10-02 18:00:48
|
Update of /cvsroot/ruby-dbi/src/build In directory usw-pr-cvs1:/tmp/cvs-serv11938/build Log Message: Directory /cvsroot/ruby-dbi/src/build added to the repository |
|
From: Michael N. <mne...@us...> - 2002-10-02 17:53:43
|
Update of /cvsroot/ruby-dbi/src
In directory usw-pr-cvs1:/tmp/cvs-serv9378
Modified Files:
setup.rb
Log Message:
install on debian-unstable into /usr/local/lib/site_ruby/<version> (by Brad Hilton)
Index: setup.rb
===================================================================
RCS file: /cvsroot/ruby-dbi/src/setup.rb,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- setup.rb 26 Jul 2002 20:41:49 -0000 1.2
+++ setup.rb 2 Oct 2002 17:53:40 -0000 1.3
@@ -338,12 +338,17 @@
((minor >= 5) or
((minor == 4) and (teeny >= 4)))))
- if newpath_p then
+ if c['rubylibdir'] then
+ # 1.6.3 < V
+ stdlibdir = c['rubylibdir']
+ sitelibdir = c['sitelibdir']
+ elsif newpath_p then
+ stdlibdir = File.join( rubylib, version )
sitelibdir = File.join( rubylib, 'site_ruby', version )
else
+ stdlibdir = File.join( rubylib, version )
sitelibdir = File.join( rubylib, version, 'site_ruby' )
end
- stdlibdir = File.join( rubylib, version )
siterb = sitelibdir
siteso = File.join( sitelibdir, arch )
|
|
From: Michael N. <mne...@us...> - 2002-10-02 17:51:02
|
Update of /cvsroot/ruby-dbi/src/lib/dbi/doc In directory usw-pr-cvs1:/tmp/cvs-serv8452 Modified Files: ChangeLog Log Message: Index: ChangeLog =================================================================== RCS file: /cvsroot/ruby-dbi/src/lib/dbi/doc/ChangeLog,v retrieving revision 1.24 retrieving revision 1.25 diff -u -r1.24 -r1.25 --- ChangeLog 13 Sep 2002 09:13:28 -0000 1.24 +++ ChangeLog 2 Oct 2002 17:50:58 -0000 1.25 @@ -2,6 +2,14 @@ : 0.0.17 +* setup.rb: on debian-unstable install into /usr/local/lib/site_ruby/<version> (by Brad Hilton) + +* dbd_mysql: add support for coercing column values (patch by Brad Hilton) + +* dbd_pg: removed method send_sql and inlined it's code instead (little speed improvement) + +* dbd_pg: rewritten transaction handling (uses now Postgres "SET AUTOCOMMIT ON|OFF") + * dbd_pg: fixed back-slash quote bug (586785) (Brad Hilton) * contrib: added dbrc (Daniel Berger) |
|
From: Michael N. <mne...@us...> - 2002-10-02 17:15:46
|
Update of /cvsroot/ruby-dbi/maintaining In directory usw-pr-cvs1:/tmp/cvs-serv27518 Log Message: initial import Status: Vendor Tag: mneumann Release Tags: start N maintaining/USER N maintaining/DBI-VERSIONS N maintaining/cvs2cl N maintaining/create_changelog.rb N maintaining/cl2html.sh N maintaining/Makefile No conflicts created by this import ***** Bogus filespec: - ***** Bogus filespec: Imported ***** Bogus filespec: sources |
|
From: Michael N. <mne...@us...> - 2002-09-26 18:42:02
|
Update of /cvsroot/ruby-dbi/src/doc In directory usw-pr-cvs1:/tmp/cvs-serv2594 Modified Files: index.rd Log Message: * Index: index.rd =================================================================== RCS file: /cvsroot/ruby-dbi/src/doc/index.rd,v retrieving revision 1.23 retrieving revision 1.24 diff -u -r1.23 -r1.24 --- index.rd 26 Jul 2002 18:13:47 -0000 1.23 +++ index.rd 26 Sep 2002 18:41:59 -0000 1.24 @@ -66,6 +66,8 @@ Several enhancements. : Daniel J. Berger contrib/dbrc +: Brad Hilton + Column coercing patch for DBD Mysql. == Database Drivers (DBDs) |
|
From: Michael N. <mne...@us...> - 2002-09-26 18:37:31
|
Update of /cvsroot/ruby-dbi/src/lib/dbd_mysql
In directory usw-pr-cvs1:/tmp/cvs-serv1565
Modified Files:
Mysql.rb
Log Message:
add support for coercing column values (patch by Brad Hilton)
Index: Mysql.rb
===================================================================
RCS file: /cvsroot/ruby-dbi/src/lib/dbd_mysql/Mysql.rb,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- Mysql.rb 3 Jul 2002 16:48:35 -0000 1.15
+++ Mysql.rb 26 Sep 2002 18:37:27 -0000 1.16
@@ -156,6 +156,25 @@
nil => [SQL_OTHER, nil, nil]
}
+ TYPE_MAP = {}
+ MysqlField.constants.grep(/^TYPE_/).each do |const|
+ value = MysqlField.const_get(const)
+ case const
+ when 'TYPE_TINY', 'TYPE_INT24', 'TYPE_SHORT', 'TYPE_LONG', 'TYPE_LONGLONG'
+ TYPE_MAP[value] = :as_int
+ when 'TYPE_FLOAT'
+ TYPE_MAP[value] = :as_float
+ when 'TYPE_DATE'
+ TYPE_MAP[value] = :as_date
+ when 'TYPE_TIME'
+ TYPE_MAP[value] = :as_time
+ when 'TYPE_DATETIME'
+ TYPE_MAP[value] = :as_timestamp
+ else
+ TYPE_MAP[value] = :as_str
+ end
+ end
+
def initialize(handle, attr)
super
@mutex = Mutex.new
@@ -334,6 +353,8 @@
@mutex.synchronize {
@handle.query_with_result = true
@res_handle = @handle.query(sql)
+ @column_info = self.column_info
+ @coerce = DBI::SQL::BasicQuote::Coerce.new
@current_row = 0
@rows = @handle.affected_rows
}
@@ -347,9 +368,20 @@
raise DBI::DatabaseError.new(err.message)
end
+ def fill_array(rowdata)
+ return nil if rowdata.nil?
+ row = []
+ rowdata.each_with_index { |value, index|
+ type = @column_info[index]['_type']
+ type_symbol = Database::TYPE_MAP[type] || :as_str
+ row[index] = @coerce.coerce(type_symbol, value)
+ }
+ row
+ end
+
def fetch
@current_row += 1
- @res_handle.fetch_row
+ fill_array(@res_handle.fetch_row)
rescue MyError => err
raise DBI::DatabaseError.new(err.message)
end
@@ -358,26 +390,26 @@
case direction
when SQL_FETCH_NEXT
@current_row += 1
- @res_handle.fetch_row
+ fill_array(@res_handle.fetch_row)
when SQL_FETCH_PRIOR
@res_handle.data_seek(@current_row - 1)
- @res_handle.fetch_row
+ fill_array(@res_handle.fetch_row)
when SQL_FETCH_FIRST
@current_row = 1
@res_handle.data_seek(@current_row - 1)
- @res_handle.fetch_row
+ fill_array(@res_handle.fetch_row)
when SQL_FETCH_LAST
@current_row = @res_handle.num_rows
@res_handle.data_seek(@current_row - 1)
- @res_handle.fetch_row
+ fill_array(@res_handle.fetch_row)
when SQL_FETCH_ABSOLUTE
@current_row = offset + 1
@res_handle.data_seek(@current_row - 1)
- @res_handle.fetch_row
+ fill_array(@res_handle.fetch_row)
when SQL_FETCH_RELATIVE
@current_row += offset + 1
@res_handle.data_seek(@current_row - 1)
- @res_handle.fetch_row
+ fill_array(@res_handle.fetch_row)
else
raise NotSupportedError
end
|
|
From: Sean C. <se...@ch...> - 2002-09-26 16:55:04
|
> > Modified Files:
> > Pg.rb
> > Log Message:
> > rewritten transaction handling (uses now Postgres' "SET AUTOCOMMIT ON|OFF")
> >
> >
> > Index: Pg.rb
> > ===================================================================
> > RCS file: /cvsroot/ruby-dbi/src/lib/dbd_pg/Pg.rb,v
> > retrieving revision 1.24
> > retrieving revision 1.25
> > diff -u -r1.24 -r1.25
> > --- Pg.rb 13 Sep 2002 09:10:31 -0000 1.24
> > +++ Pg.rb 26 Sep 2002 13:28:12 -0000 1.25
> > @@ -290,21 +282,13 @@
> > @coerce.coerce(converter, obj)
> > end
> >
> > - def in_transaction?
> > - @in_transaction
> > - end
> > -
> > - def start_transaction
> > - send_sql("BEGIN WORK", 2)
> > - @in_transaction = true
> > - end
> > -
> > def send_sql(sql, level=1)
> > - puts "SQL TRACE: |#{sql}|" if @debug_level >= level
> > + #puts "SQL TRACE: |#{sql}|" if @debug_level >= level
> > @connection.exec(sql)
> > end
>
> Did you mean to comment this out? -sc
Nevermind, you just deep six'ed the send_sql() method. :-] My bad. -sc
--
Sean Chittenden
|
|
From: Sean C. <se...@ch...> - 2002-09-26 16:53:34
|
> Modified Files:
> Pg.rb
> Log Message:
> rewritten transaction handling (uses now Postgres' "SET AUTOCOMMIT ON|OFF")
>
>
> Index: Pg.rb
> ===================================================================
> RCS file: /cvsroot/ruby-dbi/src/lib/dbd_pg/Pg.rb,v
> retrieving revision 1.24
> retrieving revision 1.25
> diff -u -r1.24 -r1.25
> --- Pg.rb 13 Sep 2002 09:10:31 -0000 1.24
> +++ Pg.rb 26 Sep 2002 13:28:12 -0000 1.25
> @@ -290,21 +282,13 @@
> @coerce.coerce(converter, obj)
> end
>
> - def in_transaction?
> - @in_transaction
> - end
> -
> - def start_transaction
> - send_sql("BEGIN WORK", 2)
> - @in_transaction = true
> - end
> -
> def send_sql(sql, level=1)
> - puts "SQL TRACE: |#{sql}|" if @debug_level >= level
> + #puts "SQL TRACE: |#{sql}|" if @debug_level >= level
> @connection.exec(sql)
> end
Did you mean to comment this out? -sc
--
Sean Chittenden
|
|
From: Michael N. <mne...@us...> - 2002-09-26 13:40:36
|
Update of /cvsroot/ruby-dbi/src/lib/dbd_pg
In directory usw-pr-cvs1:/tmp/cvs-serv7587
Modified Files:
Pg.rb
Log Message:
removed method send_sql and inlined it's code instead (little speed improvement)
Index: Pg.rb
===================================================================
RCS file: /cvsroot/ruby-dbi/src/lib/dbd_pg/Pg.rb,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -r1.26 -r1.27
--- Pg.rb 26 Sep 2002 13:32:58 -0000 1.26
+++ Pg.rb 26 Sep 2002 13:40:32 -0000 1.27
@@ -36,7 +36,7 @@
module DBD
module Pg
- VERSION = "0.3.1"
+ VERSION = "0.3.2"
USED_DBD_VERSION = "0.2"
class Driver < DBI::BaseDriver
@@ -110,13 +110,13 @@
def disconnect
unless @attr['AutoCommit']
- send_sql("ROLLBACK", 2) # rollback outstanding transactions
+ @connection.exec("ROLLBACK") # rollback outstanding transactions
end
@connection.close
end
def ping
- answer = send_sql("SELECT 1", 3)
+ answer = @connection.exec("SELECT 1")
if answer
return answer.num_tuples == 1
else
@@ -250,7 +250,7 @@
case attr
when 'AutoCommit'
# TODO: Are outstanding transactions committed?
- send_sql("SET AUTOCOMMIT TO " + (value ? "ON" : "OFF"), 2)
+ @connection.exec("SET AUTOCOMMIT TO " + (value ? "ON" : "OFF"))
when 'pg_client_encoding'
@connection.set_client_encoding(value)
else
@@ -265,12 +265,12 @@
def commit
# TODO: what if in autocommit mode?
- send_sql("COMMIT", 2)
+ @connection.exec("COMMIT")
end
def rollback
# TODO: what if in autocommit mode?
- send_sql("ROLLBACK", 2)
+ @connection.exec("ROLLBACK")
end
# Other Public Methods ---------------------------------------
@@ -282,11 +282,6 @@
@coerce.coerce(converter, obj)
end
- def send_sql(sql, level=1)
- #puts "SQL TRACE: |#{sql}|" if @debug_level >= level
- @connection.exec(sql)
- end
-
def quote(value)
# TODO: new quote function of Pg driver
case value
@@ -304,7 +299,7 @@
@type_map = Hash.new
@coerce = PgCoerce.new
- res = send_sql("SELECT typname, typelem FROM pg_type")
+ res = @connection.exec("SELECT typname, typelem FROM pg_type")
res.result.each { |name, idstr|
@type_map[idstr.to_i] =
@@ -423,7 +418,7 @@
boundsql = @prep_sql.bind(@bindvars)
- pg_result = @db.send_sql(boundsql)
+ pg_result = @db.connection.exec(boundsql)
@result = Tuples.new(@db, pg_result)
rescue PGError, RuntimeError => err
|
|
From: Michael N. <mne...@us...> - 2002-09-26 13:33:03
|
Update of /cvsroot/ruby-dbi/src/lib/dbd_pg
In directory usw-pr-cvs1:/tmp/cvs-serv5186
Modified Files:
Pg.rb
Log Message:
converted tabs to spaces
Index: Pg.rb
===================================================================
RCS file: /cvsroot/ruby-dbi/src/lib/dbd_pg/Pg.rb,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -r1.25 -r1.26
--- Pg.rb 26 Sep 2002 13:28:12 -0000 1.25
+++ Pg.rb 26 Sep 2002 13:32:58 -0000 1.26
@@ -40,20 +40,20 @@
USED_DBD_VERSION = "0.2"
class Driver < DBI::BaseDriver
-
- def initialize
- super(USED_DBD_VERSION)
- end
-
- ## List of datasources for this database.
- def data_sources
- []
- end
-
- ## Connect to a database.
- def connect(dbname, user, auth, attr)
- Database.new(dbname, user, auth, attr)
- end
+
+ def initialize
+ super(USED_DBD_VERSION)
+ end
+
+ ## List of datasources for this database.
+ def data_sources
+ []
+ end
+
+ ## Connect to a database.
+ def connect(dbname, user, auth, attr)
+ Database.new(dbname, user, auth, attr)
+ end
end
@@ -81,10 +81,10 @@
"text" => [SQL_VARCHAR, nil, nil],
nil => [SQL_OTHER, nil, nil]
}
-
- attr_reader :connection
+
+ attr_reader :connection
- def initialize(dbname, user, auth, attr)
+ def initialize(dbname, user, auth, attr)
hash = Utils.parse_params(dbname)
if hash['dbname'].nil? and hash['database'].nil?
@@ -98,35 +98,35 @@
@connection = PGconn.new(hash['host'], hash['port'], hash['options'], hash['tty'],
hash['dbname'] || hash['database'], user, auth)
- @attr = attr
- @attr.each { |k,v| self[k] = v}
+ @attr = attr
+ @attr.each { |k,v| self[k] = v}
- load_type_map
- rescue PGError => err
- raise DBI::OperationalError.new(err.message)
- end
-
- # DBD Protocol -----------------------------------------------
-
- def disconnect
- unless @attr['AutoCommit']
- send_sql("ROLLBACK", 2) # rollback outstanding transactions
- end
- @connection.close
- end
-
- def ping
- answer = send_sql("SELECT 1", 3)
+ load_type_map
+ rescue PGError => err
+ raise DBI::OperationalError.new(err.message)
+ end
+
+ # DBD Protocol -----------------------------------------------
+
+ def disconnect
+ unless @attr['AutoCommit']
+ send_sql("ROLLBACK", 2) # rollback outstanding transactions
+ end
+ @connection.close
+ end
+
+ def ping
+ answer = send_sql("SELECT 1", 3)
if answer
return answer.num_tuples == 1
else
return false
end
- rescue PGError
- return false
- ensure
- answer.clear if answer
- end
+ rescue PGError
+ return false
+ ensure
+ answer.clear if answer
+ end
def tables
stmt = execute("SELECT relname FROM pg_class WHERE relkind='r'")
@@ -164,7 +164,7 @@
]
dbh = DBI::DatabaseHandle.new(self)
- indices = {}
+ indices = {}
default_values = {}
dbh.select_all(sql3, table) do |default, name|
@@ -232,10 +232,10 @@
return ret
end
- def prepare(statement)
- Statement.new(self, statement)
- end
-
+ def prepare(statement)
+ Statement.new(self, statement)
+ end
+
# Note: 'AutoCommit' returns nil <=> Postgres' default mode
def [](attr)
case attr
@@ -246,49 +246,49 @@
end
end
- def []=(attr, value)
- case attr
- when 'AutoCommit'
- # TODO: Are outstanding transactions committed?
- send_sql("SET AUTOCOMMIT TO " + (value ? "ON" : "OFF"), 2)
+ def []=(attr, value)
+ case attr
+ when 'AutoCommit'
+ # TODO: Are outstanding transactions committed?
+ send_sql("SET AUTOCOMMIT TO " + (value ? "ON" : "OFF"), 2)
when 'pg_client_encoding'
@connection.set_client_encoding(value)
- else
+ else
if attr =~ /^pg_/ or attr != /_/
raise DBI::NotSupportedError, "Option '#{attr}' not supported"
else # option for some other driver - quitly ignore
return
end
- end
- @attr[attr] = value
- end
-
- def commit
- # TODO: what if in autocommit mode?
- send_sql("COMMIT", 2)
- end
-
- def rollback
- # TODO: what if in autocommit mode?
- send_sql("ROLLBACK", 2)
- end
-
- # Other Public Methods ---------------------------------------
-
- def convert(obj,typeid)
- return nil if obj.nil?
- converter = @type_map[typeid] || :as_str
+ end
+ @attr[attr] = value
+ end
+
+ def commit
+ # TODO: what if in autocommit mode?
+ send_sql("COMMIT", 2)
+ end
+
+ def rollback
+ # TODO: what if in autocommit mode?
+ send_sql("ROLLBACK", 2)
+ end
+
+ # Other Public Methods ---------------------------------------
+
+ def convert(obj,typeid)
+ return nil if obj.nil?
+ converter = @type_map[typeid] || :as_str
#raise DBI::InterfaceError, "Unsupported Type (typeid=#{typeid})" if converter.nil?
- @coerce.coerce(converter, obj)
- end
+ @coerce.coerce(converter, obj)
+ end
- def send_sql(sql, level=1)
- #puts "SQL TRACE: |#{sql}|" if @debug_level >= level
- @connection.exec(sql)
- end
+ def send_sql(sql, level=1)
+ #puts "SQL TRACE: |#{sql}|" if @debug_level >= level
+ @connection.exec(sql)
+ end
def quote(value)
- # TODO: new quote function of Pg driver
+ # TODO: new quote function of Pg driver
case value
when String
"'#{ value.gsub(/\\/){ '\\\\' }.gsub(/'/){ '\\\'' } }'"
@@ -297,33 +297,33 @@
end
end
-
+
private # ----------------------------------------------------
- def load_type_map
- @type_map = Hash.new
+ def load_type_map
+ @type_map = Hash.new
@coerce = PgCoerce.new
- res = send_sql("SELECT typname, typelem FROM pg_type")
+ res = send_sql("SELECT typname, typelem FROM pg_type")
- res.result.each { |name, idstr|
- @type_map[idstr.to_i] =
+ res.result.each { |name, idstr|
+ @type_map[idstr.to_i] =
case name
when '_bool' then :as_bool
- when '_int8', '_int4', '_int2' then :as_int
- when '_varchar' then :as_str
- when '_float4','_float8' then :as_float
+ when '_int8', '_int4', '_int2' then :as_int
+ when '_varchar' then :as_str
+ when '_float4','_float8' then :as_float
when '_timestamp', '_timestamptz' then :as_timestamp
when '_date' then :as_date
when '_bytea' then :as_bytea
else :as_str
- end
- }
+ end
+ }
# additional conversions
@type_map[705] ||= :as_str # select 'hallo'
@type_map[1114] ||= :as_timestamp # TIMESTAMP WITHOUT TIME ZONE
- end
+ end
# Driver-specific functions ------------------------------------------------
@@ -332,31 +332,31 @@
def __blob_import(file)
@connection.lo_import(file)
- rescue PGError => err
+ rescue PGError => err
raise DBI::DatabaseError.new(err.message)
end
def __blob_export(oid, file)
@connection.lo_export(oid.to_i, file)
- rescue PGError => err
+ rescue PGError => err
raise DBI::DatabaseError.new(err.message)
end
def __blob_create(mode=PGlarge::INV_READ)
@connection.lo_create(mode)
- rescue PGError => err
+ rescue PGError => err
raise DBI::DatabaseError.new(err.message)
end
def __blob_open(oid, mode=PGlarge::INV_READ)
@connection.lo_open(oid.to_i, mode)
- rescue PGError => err
+ rescue PGError => err
raise DBI::DatabaseError.new(err.message)
end
def __blob_unlink(oid)
@connection.lo_unlink(oid.to_i)
- rescue PGError => err
+ rescue PGError => err
raise DBI::DatabaseError.new(err.message)
end
@@ -370,7 +370,7 @@
end
blob.close
data
- rescue PGError => err
+ rescue PGError => err
raise DBI::DatabaseError.new(err.message)
end
@@ -381,7 +381,7 @@
# http://www.postgresql.org/idocs/index.php?datatype-binary.html
#
def __encode_bytea(str)
- # TODO: use quote function of Pg driver
+ # TODO: use quote function of Pg driver
a = str.split(/\\/, -1).collect! {|s|
s.gsub!(/'/, "\\\\047") # ' => \\047
s.gsub!(/\000/, "\\\\000") # \0 => \\000
@@ -394,19 +394,19 @@
################################################################
class Statement < DBI::BaseStatement
-
- def initialize(db, sql)
- @db = db
+
+ def initialize(db, sql)
+ @db = db
@prep_sql = DBI::SQL::PreparedStatement.new(@db, sql)
- @result = nil
- @bindvars = []
- end
-
- def bind_param(index, value, options)
- @bindvars[index-1] = value
- end
+ @result = nil
+ @bindvars = []
+ end
+
+ def bind_param(index, value, options)
+ @bindvars[index-1] = value
+ end
- def execute
+ def execute
# replace DBI::Binary object by oid returned by lo_import
@bindvars.collect! do |var|
if var.is_a? DBI::Binary then
@@ -421,42 +421,42 @@
end
end
- boundsql = @prep_sql.bind(@bindvars)
+ boundsql = @prep_sql.bind(@bindvars)
pg_result = @db.send_sql(boundsql)
@result = Tuples.new(@db, pg_result)
- rescue PGError, RuntimeError => err
- raise DBI::ProgrammingError.new(err.message)
- end
-
- def fetch
- @result.fetchrow
- end
-
- def fetch_scroll(direction, offset)
- @result.fetch_scroll(direction, offset)
- end
-
- def finish
- @result.finish if @result
- @result = nil
- @db = nil
- end
-
- # returns result-set column informations
- def column_info
- @result.column_info
- end
-
- # Return the row processed count (or nil if RPC not available)
- def rows
- if @result
+ rescue PGError, RuntimeError => err
+ raise DBI::ProgrammingError.new(err.message)
+ end
+
+ def fetch
+ @result.fetchrow
+ end
+
+ def fetch_scroll(direction, offset)
+ @result.fetch_scroll(direction, offset)
+ end
+
+ def finish
+ @result.finish if @result
+ @result = nil
+ @db = nil
+ end
+
+ # returns result-set column informations
+ def column_info
+ @result.column_info
+ end
+
+ # Return the row processed count (or nil if RPC not available)
+ def rows
+ if @result
@result.rows_affected
- else
- nil
- end
- end
+ else
+ nil
+ end
+ end
def [](attr)
case attr
@@ -472,59 +472,59 @@
end
- private # ----------------------------------------------------
+ private # ----------------------------------------------------
end # Statement
################################################################
class Tuples
- def initialize(db,pg_result)
- @db = db
- @pg_result = pg_result
- @index = -1
+ def initialize(db,pg_result)
+ @db = db
+ @pg_result = pg_result
+ @index = -1
@result = @pg_result.result
- @row = Array.new
- end
+ @row = Array.new
+ end
+
+ def column_info
+ @pg_result.fields.collect do |str| {'name'=>str} end
+ end
+
+ def fetchrow
+ @index += 1
+ if @index < @result.size && @index >= 0
+ fill_array(@result[@index])
+ @row
+ else
+ nil
+ end
+ end
- def column_info
- @pg_result.fields.collect do |str| {'name'=>str} end
- end
-
- def fetchrow
- @index += 1
- if @index < @result.size && @index >= 0
- fill_array(@result[@index])
- @row
- else
- nil
- end
- end
-
- def fetch_scroll(direction, offset)
- # Exact semantics aren't too closely defined. I attempted to follow the DBI:Mysql example.
- case direction
- when SQL_FETCH_NEXT
- # Nothing special to do, besides the fetchrow
- when SQL_FETCH_PRIOR
- @index -= 2
- when SQL_FETCH_FIRST
- @index = -1
- when SQL_FETCH_LAST
- @index = @result.size - 2
- when SQL_FETCH_ABSOLUTE
- # Note: if you go "out of range", all fetches will give nil until you get back
- # into range, this doesn't raise an error.
- @index = offset-1
- when SQL_FETCH_RELATIVE
- # Note: if you go "out of range", all fetches will give nil until you get back
- # into range, this doesn't raise an error.
- @index += offset - 1
- else
- raise NotSupportedError
- end
- self.fetchrow
- end
+ def fetch_scroll(direction, offset)
+ # Exact semantics aren't too closely defined. I attempted to follow the DBI:Mysql example.
+ case direction
+ when SQL_FETCH_NEXT
+ # Nothing special to do, besides the fetchrow
+ when SQL_FETCH_PRIOR
+ @index -= 2
+ when SQL_FETCH_FIRST
+ @index = -1
+ when SQL_FETCH_LAST
+ @index = @result.size - 2
+ when SQL_FETCH_ABSOLUTE
+ # Note: if you go "out of range", all fetches will give nil until you get back
+ # into range, this doesn't raise an error.
+ @index = offset-1
+ when SQL_FETCH_RELATIVE
+ # Note: if you go "out of range", all fetches will give nil until you get back
+ # into range, this doesn't raise an error.
+ @index += offset - 1
+ else
+ raise NotSupportedError
+ end
+ self.fetchrow
+ end
def row_count
@pg_result.num_tuples
@@ -534,17 +534,17 @@
@pg_result.cmdtuples
end
- def finish
- @pg_result.clear
- end
-
- private # ----------------------------------------------------
-
- def fill_array(rowdata)
- rowdata.each_with_index { |value, index|
- @row[index] = @db.convert(rowdata[index],@pg_result.type(index))
- }
- end
+ def finish
+ @pg_result.clear
+ end
+
+ private # ----------------------------------------------------
+
+ def fill_array(rowdata)
+ rowdata.each_with_index { |value, index|
+ @row[index] = @db.convert(rowdata[index],@pg_result.type(index))
+ }
+ end
end # Tuples
@@ -555,7 +555,7 @@
# http://www.postgresql.org/idocs/index.php?datatype-binary.html
#
def as_bytea(str)
- # TODO: Use quote function of Pg driver
+ # TODO: Use quote function of Pg driver
a = str.split(/\\\\/, -1).collect! {|s|
s.gsub!(/\\[0-7][0-7][0-7]/) {|o| o[1..-1].oct.chr} # \### => chr(###)
s
|
|
From: Michael N. <mne...@us...> - 2002-09-26 13:28:17
|
Update of /cvsroot/ruby-dbi/src/lib/dbd_pg
In directory usw-pr-cvs1:/tmp/cvs-serv3492
Modified Files:
Pg.rb
Log Message:
rewritten transaction handling (uses now Postgres' "SET AUTOCOMMIT ON|OFF")
Index: Pg.rb
===================================================================
RCS file: /cvsroot/ruby-dbi/src/lib/dbd_pg/Pg.rb,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -r1.24 -r1.25
--- Pg.rb 13 Sep 2002 09:10:31 -0000 1.24
+++ Pg.rb 26 Sep 2002 13:28:12 -0000 1.25
@@ -36,7 +36,7 @@
module DBD
module Pg
- VERSION = "0.3.0"
+ VERSION = "0.3.1"
USED_DBD_VERSION = "0.2"
class Driver < DBI::BaseDriver
@@ -83,15 +83,8 @@
}
attr_reader :connection
- attr_accessor :autocommit
def initialize(dbname, user, auth, attr)
- @debug_level = 0
-
-
- @attr = attr
- @attr.each { |k,v| self[k] = v}
-
hash = Utils.parse_params(dbname)
if hash['dbname'].nil? and hash['database'].nil?
@@ -102,12 +95,13 @@
hash['tty'] ||= ''
hash['port'] = hash['port'].to_i unless hash['port'].nil?
- @connection = PGconn.new(hash['host'], hash['port'], hash['options'], hash['tty'],
+ @connection = PGconn.new(hash['host'], hash['port'], hash['options'], hash['tty'],
hash['dbname'] || hash['database'], user, auth)
+ @attr = attr
+ @attr.each { |k,v| self[k] = v}
+
load_type_map
- @in_transaction = false
- initialize_autocommit
rescue PGError => err
raise DBI::OperationalError.new(err.message)
end
@@ -115,8 +109,8 @@
# DBD Protocol -----------------------------------------------
def disconnect
- if not @autocommit and @in_transaction then
- send_sql("COMMIT WORK", 2)
+ unless @attr['AutoCommit']
+ send_sql("ROLLBACK", 2) # rollback outstanding transactions
end
@connection.close
end
@@ -242,6 +236,7 @@
Statement.new(self, statement)
end
+ # Note: 'AutoCommit' returns nil <=> Postgres' default mode
def [](attr)
case attr
when 'pg_client_encoding'
@@ -254,7 +249,8 @@
def []=(attr, value)
case attr
when 'AutoCommit'
- @autocommit = value
+ # TODO: Are outstanding transactions committed?
+ send_sql("SET AUTOCOMMIT TO " + (value ? "ON" : "OFF"), 2)
when 'pg_client_encoding'
@connection.set_client_encoding(value)
else
@@ -268,17 +264,13 @@
end
def commit
- if @in_transaction
- send_sql("COMMIT WORK", 2)
- @in_transaction = false
- end
+ # TODO: what if in autocommit mode?
+ send_sql("COMMIT", 2)
end
def rollback
- if @in_transaction
- send_sql("ROLLBACK WORK", 2)
- @in_transaction = false
- end
+ # TODO: what if in autocommit mode?
+ send_sql("ROLLBACK", 2)
end
# Other Public Methods ---------------------------------------
@@ -290,21 +282,13 @@
@coerce.coerce(converter, obj)
end
- def in_transaction?
- @in_transaction
- end
-
- def start_transaction
- send_sql("BEGIN WORK", 2)
- @in_transaction = true
- end
-
def send_sql(sql, level=1)
- puts "SQL TRACE: |#{sql}|" if @debug_level >= level
+ #puts "SQL TRACE: |#{sql}|" if @debug_level >= level
@connection.exec(sql)
end
def quote(value)
+ # TODO: new quote function of Pg driver
case value
when String
"'#{ value.gsub(/\\/){ '\\\\' }.gsub(/'/){ '\\\'' } }'"
@@ -316,11 +300,6 @@
private # ----------------------------------------------------
- def initialize_autocommit
- @autocommit = true
- @attr['AutoCommit'] = @autocommit
- end
-
def load_type_map
@type_map = Hash.new
@coerce = PgCoerce.new
@@ -352,42 +331,36 @@
public
def __blob_import(file)
- start_transaction unless in_transaction?
@connection.lo_import(file)
rescue PGError => err
raise DBI::DatabaseError.new(err.message)
end
def __blob_export(oid, file)
- start_transaction unless in_transaction?
@connection.lo_export(oid.to_i, file)
rescue PGError => err
raise DBI::DatabaseError.new(err.message)
end
def __blob_create(mode=PGlarge::INV_READ)
- start_transaction unless in_transaction?
@connection.lo_create(mode)
rescue PGError => err
raise DBI::DatabaseError.new(err.message)
end
def __blob_open(oid, mode=PGlarge::INV_READ)
- start_transaction unless in_transaction?
@connection.lo_open(oid.to_i, mode)
rescue PGError => err
raise DBI::DatabaseError.new(err.message)
end
def __blob_unlink(oid)
- start_transaction unless in_transaction?
@connection.lo_unlink(oid.to_i)
rescue PGError => err
raise DBI::DatabaseError.new(err.message)
end
def __blob_read(oid, length=nil)
- start_transaction unless in_transaction?
blob = @connection.lo_open(oid.to_i, PGlarge::INV_READ)
blob.open
if length.nil?
@@ -408,6 +381,7 @@
# http://www.postgresql.org/idocs/index.php?datatype-binary.html
#
def __encode_bytea(str)
+ # TODO: use quote function of Pg driver
a = str.split(/\\/, -1).collect! {|s|
s.gsub!(/'/, "\\\\047") # ' => \\047
s.gsub!(/\000/, "\\\\000") # \0 => \\000
@@ -449,17 +423,9 @@
boundsql = @prep_sql.bind(@bindvars)
- if SQL.query?(boundsql) then
- pg_result = @db.send_sql(boundsql)
- @result = Tuples.new(@db, pg_result)
- elsif @db.autocommit then
- pg_result = @db.send_sql(boundsql)
- @result = Tuples.new(@db, pg_result)
- else
- @db.start_transaction if not @db.in_transaction?
- pg_result = @db.send_sql(boundsql)
- @result = Tuples.new(@db, pg_result)
- end
+ pg_result = @db.send_sql(boundsql)
+ @result = Tuples.new(@db, pg_result)
+
rescue PGError, RuntimeError => err
raise DBI::ProgrammingError.new(err.message)
end
@@ -589,6 +555,7 @@
# http://www.postgresql.org/idocs/index.php?datatype-binary.html
#
def as_bytea(str)
+ # TODO: Use quote function of Pg driver
a = str.split(/\\\\/, -1).collect! {|s|
s.gsub!(/\\[0-7][0-7][0-7]/) {|o| o[1..-1].oct.chr} # \### => chr(###)
s
|
|
From: Michael N. <mne...@us...> - 2002-09-13 09:13:30
|
Update of /cvsroot/ruby-dbi/src/lib/dbi/doc In directory usw-pr-cvs1:/tmp/cvs-serv1111 Modified Files: ChangeLog Log Message: * Index: ChangeLog =================================================================== RCS file: /cvsroot/ruby-dbi/src/lib/dbi/doc/ChangeLog,v retrieving revision 1.23 retrieving revision 1.24 diff -u -r1.23 -r1.24 --- ChangeLog 1 Aug 2002 19:02:25 -0000 1.23 +++ ChangeLog 13 Sep 2002 09:13:28 -0000 1.24 @@ -2,6 +2,8 @@ : 0.0.17 +* dbd_pg: fixed back-slash quote bug (586785) (Brad Hilton) + * contrib: added dbrc (Daniel Berger) * dbd_pg: enhanced conversion: default is to_str, added timestamp |
|
From: Michael N. <mne...@us...> - 2002-09-13 09:10:35
|
Update of /cvsroot/ruby-dbi/src/lib/dbd_pg
In directory usw-pr-cvs1:/tmp/cvs-serv32532
Modified Files:
Pg.rb
Log Message:
fix quoting backslashes bug (Brad Hilton)
Index: Pg.rb
===================================================================
RCS file: /cvsroot/ruby-dbi/src/lib/dbd_pg/Pg.rb,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -r1.23 -r1.24
--- Pg.rb 26 Jul 2002 17:56:43 -0000 1.23
+++ Pg.rb 13 Sep 2002 09:10:31 -0000 1.24
@@ -303,8 +303,18 @@
puts "SQL TRACE: |#{sql}|" if @debug_level >= level
@connection.exec(sql)
end
+
+ def quote(value)
+ case value
+ when String
+ "'#{ value.gsub(/\\/){ '\\\\' }.gsub(/'/){ '\\\'' } }'"
+ else
+ super
+ end
+ end
+
- private # ----------------------------------------------------
+ private # ----------------------------------------------------
def initialize_autocommit
@autocommit = true
@@ -411,11 +421,9 @@
################################################################
class Statement < DBI::BaseStatement
- include SQL::BasicQuote
-
def initialize(db, sql)
@db = db
- @prep_sql = DBI::SQL::PreparedStatement.new(self, sql)
+ @prep_sql = DBI::SQL::PreparedStatement.new(@db, sql)
@result = nil
@bindvars = []
end
|
|
From: Michael N. <mne...@us...> - 2002-09-05 09:57:17
|
Update of /cvsroot/ruby-dbi/subprojects/ruby-db2/lib/db2
In directory usw-pr-cvs1:/tmp/cvs-serv2947/ruby-db2/lib/db2
Added Files:
db2cli.rb
Log Message:
initial import from local CVS repository
--- NEW FILE: db2cli.rb ---
#
# $Id: db2cli.rb,v 1.1 2002/09/05 09:57:13 mneumann Exp $
#
require "singleton"
module DB2CLI
class Date
attr_accessor :year, :month, :day
def initialize(year=0, month=0, day=0)
@year, @month, @day = year, month, day
end
def to_s
"#{@year}-#{@month}-#{@day}"
end
end
class Time
attr_accessor :hour, :minute, :second
def initialize(hour=0, minute=0, second=0)
@hour, @minute, @second = hour, minute, second
end
def to_s
"#{@hour}:#{@minute}:#{@second}"
end
end
class Timestamp
attr_accessor :year, :month, :day
attr_accessor :hour, :minute, :second, :fraction
def initialize(year=0, month=0, day=0, hour=0, minute=0, second=0, fraction=0)
@year, @month, @day = year, month, day
@hour, @minute, @second, @fraction = hour, minute, second, fraction
end
def to_s
"#{@year}-#{@month}-#{@day} #{@hour}:#{@minute}:#{@second}.#{@fraction}"
end
end
class NullClass
include Singleton
def to_s
"NULL"
end
end
Null = NullClass.instance
end # module DB2CLI
require "db2/db2cli.so"
|
|
From: Michael N. <mne...@us...> - 2002-09-05 09:57:17
|
Update of /cvsroot/ruby-dbi/subprojects/ruby-db2/ext/db2
In directory usw-pr-cvs1:/tmp/cvs-serv2947/ruby-db2/ext/db2
Added Files:
constants.h db2cli.c extconf.rb
Log Message:
initial import from local CVS repository
--- NEW FILE: constants.h ---
rb_define_const(mDB2CLI, "SQL_SUCCESS", INT2NUM(SQL_SUCCESS));
rb_define_const(mDB2CLI, "SQL_SUCCESS_WITH_INFO", INT2NUM(SQL_SUCCESS_WITH_INFO));
rb_define_const(mDB2CLI, "SQL_INVALID_HANDLE", INT2NUM(SQL_INVALID_HANDLE));
rb_define_const(mDB2CLI, "SQL_STILL_EXECUTING", INT2NUM(SQL_STILL_EXECUTING));
rb_define_const(mDB2CLI, "SQL_ERROR", INT2NUM(SQL_ERROR));
rb_define_const(mDB2CLI, "SQL_NO_DATA_FOUND", INT2NUM(SQL_NO_DATA_FOUND));
rb_define_const(mDB2CLI, "SQL_NULL_DATA", INT2NUM(SQL_NULL_DATA));
rb_define_const(mDB2CLI, "SQL_HANDLE_ENV", INT2NUM(SQL_HANDLE_ENV));
rb_define_const(mDB2CLI, "SQL_HANDLE_DBC", INT2NUM(SQL_HANDLE_DBC));
rb_define_const(mDB2CLI, "SQL_HANDLE_STMT", INT2NUM(SQL_HANDLE_STMT));
rb_define_const(mDB2CLI, "SQL_HANDLE_DESC", INT2NUM(SQL_HANDLE_DESC));
rb_define_const(mDB2CLI, "SQL_NULL_HANDLE", INT2NUM(SQL_NULL_HANDLE));
rb_define_const(mDB2CLI, "SQL_NULL_HENV", INT2NUM(SQL_NULL_HENV));
rb_define_const(mDB2CLI, "SQL_NULL_HDBC", INT2NUM(SQL_NULL_HDBC));
rb_define_const(mDB2CLI, "SQL_NULL_HSTMT", INT2NUM(SQL_NULL_HSTMT));
rb_define_const(mDB2CLI, "SQL_NULL_HDESC", INT2NUM(SQL_NULL_HDESC));
rb_define_const(mDB2CLI, "SQL_NO_NULLS", INT2NUM(SQL_NO_NULLS));
rb_define_const(mDB2CLI, "SQL_NULLABLE", INT2NUM(SQL_NULLABLE));
rb_define_const(mDB2CLI, "SQL_COMMIT", INT2NUM(SQL_COMMIT));
rb_define_const(mDB2CLI, "SQL_ROLLBACK", INT2NUM(SQL_ROLLBACK));
rb_define_const(mDB2CLI, "SQL_TRUE", INT2NUM(SQL_TRUE));
rb_define_const(mDB2CLI, "SQL_FALSE", INT2NUM(SQL_FALSE));
rb_define_const(mDB2CLI, "SQL_MAX_DSN_LENGTH", INT2NUM(SQL_MAX_DSN_LENGTH));
rb_define_const(mDB2CLI, "SQL_BIGINT", INT2NUM(SQL_BIGINT));
rb_define_const(mDB2CLI, "SQL_BLOB", INT2NUM(SQL_BLOB));
rb_define_const(mDB2CLI, "SQL_BLOB_LOCATOR", INT2NUM(SQL_BLOB_LOCATOR));
rb_define_const(mDB2CLI, "SQL_CHAR", INT2NUM(SQL_CHAR));
rb_define_const(mDB2CLI, "SQL_BINARY", INT2NUM(SQL_BINARY));
rb_define_const(mDB2CLI, "SQL_CLOB", INT2NUM(SQL_CLOB));
rb_define_const(mDB2CLI, "SQL_CLOB_LOCATOR", INT2NUM(SQL_CLOB_LOCATOR));
rb_define_const(mDB2CLI, "SQL_TYPE_DATE", INT2NUM(SQL_TYPE_DATE));
rb_define_const(mDB2CLI, "SQL_DBCLOB", INT2NUM(SQL_DBCLOB));
rb_define_const(mDB2CLI, "SQL_DBCLOB_LOCATOR", INT2NUM(SQL_DBCLOB_LOCATOR));
rb_define_const(mDB2CLI, "SQL_DECIMAL", INT2NUM(SQL_DECIMAL));
rb_define_const(mDB2CLI, "SQL_DOUBLE", INT2NUM(SQL_DOUBLE));
rb_define_const(mDB2CLI, "SQL_FLOAT", INT2NUM(SQL_FLOAT));
rb_define_const(mDB2CLI, "SQL_GRAPHIC", INT2NUM(SQL_GRAPHIC));
rb_define_const(mDB2CLI, "SQL_INTEGER", INT2NUM(SQL_INTEGER));
rb_define_const(mDB2CLI, "SQL_LONGVARCHAR", INT2NUM(SQL_LONGVARCHAR));
rb_define_const(mDB2CLI, "SQL_LONGVARBINARY", INT2NUM(SQL_LONGVARBINARY));
rb_define_const(mDB2CLI, "SQL_LONGVARGRAPHIC", INT2NUM(SQL_LONGVARGRAPHIC));
rb_define_const(mDB2CLI, "SQL_NUMERIC", INT2NUM(SQL_NUMERIC));
rb_define_const(mDB2CLI, "SQL_REAL", INT2NUM(SQL_REAL));
rb_define_const(mDB2CLI, "SQL_SMALLINT", INT2NUM(SQL_SMALLINT));
rb_define_const(mDB2CLI, "SQL_TYPE_TIME", INT2NUM(SQL_TYPE_TIME));
rb_define_const(mDB2CLI, "SQL_TYPE_TIMESTAMP", INT2NUM(SQL_TYPE_TIMESTAMP));
rb_define_const(mDB2CLI, "SQL_VARCHAR", INT2NUM(SQL_VARCHAR));
rb_define_const(mDB2CLI, "SQL_VARBINARY", INT2NUM(SQL_VARBINARY));
rb_define_const(mDB2CLI, "SQL_VARGRAPHIC", INT2NUM(SQL_VARGRAPHIC));
rb_define_const(mDB2CLI, "SQL_FETCH_NEXT", INT2NUM(SQL_FETCH_NEXT));
rb_define_const(mDB2CLI, "SQL_FETCH_PRIOR", INT2NUM(SQL_FETCH_PRIOR));
rb_define_const(mDB2CLI, "SQL_FETCH_RELATIVE", INT2NUM(SQL_FETCH_RELATIVE));
rb_define_const(mDB2CLI, "SQL_FETCH_ABSOLUTE", INT2NUM(SQL_FETCH_ABSOLUTE));
rb_define_const(mDB2CLI, "SQL_FETCH_FIRST", INT2NUM(SQL_FETCH_FIRST));
rb_define_const(mDB2CLI, "SQL_FETCH_LAST", INT2NUM(SQL_FETCH_LAST));
rb_define_const(mDB2CLI, "SQL_FETCH_BOOKMARK", INT2NUM(SQL_FETCH_BOOKMARK));
rb_define_const(mDB2CLI, "SQL_CLOSE", INT2NUM(SQL_CLOSE));
rb_define_const(mDB2CLI, "SQL_DROP", INT2NUM(SQL_DROP));
rb_define_const(mDB2CLI, "SQL_UNBIND", INT2NUM(SQL_UNBIND));
rb_define_const(mDB2CLI, "SQL_RESET_PARAMS", INT2NUM(SQL_RESET_PARAMS));
rb_define_const(mDB2CLI, "SQL_DESC_AUTO_UNIQUE_VALUE", INT2NUM(SQL_DESC_AUTO_UNIQUE_VALUE));
rb_define_const(mDB2CLI, "SQL_DESC_CASE_SENSITIVE", INT2NUM(SQL_DESC_CASE_SENSITIVE));
rb_define_const(mDB2CLI, "SQL_DESC_CATALOG_NAME", INT2NUM(SQL_DESC_CATALOG_NAME));
rb_define_const(mDB2CLI, "SQL_DESC_COUNT", INT2NUM(SQL_DESC_COUNT));
rb_define_const(mDB2CLI, "SQL_DESC_DISPLAY_SIZE", INT2NUM(SQL_DESC_DISPLAY_SIZE));
rb_define_const(mDB2CLI, "SQL_DESC_LABEL", INT2NUM(SQL_DESC_LABEL));
rb_define_const(mDB2CLI, "SQL_DESC_DISTINCT_TYPE", INT2NUM(SQL_DESC_DISTINCT_TYPE));
rb_define_const(mDB2CLI, "SQL_DESC_OCTET_LENGTH", INT2NUM(SQL_DESC_OCTET_LENGTH));
rb_define_const(mDB2CLI, "SQL_DESC_FIXED_PREC_SCALE", INT2NUM(SQL_DESC_FIXED_PREC_SCALE));
rb_define_const(mDB2CLI, "SQL_DESC_NAME", INT2NUM(SQL_DESC_NAME));
rb_define_const(mDB2CLI, "SQL_DESC_NULLABLE", INT2NUM(SQL_DESC_NULLABLE));
rb_define_const(mDB2CLI, "SQL_DESC_SCHEMA_NAME", INT2NUM(SQL_DESC_SCHEMA_NAME));
rb_define_const(mDB2CLI, "SQL_DESC_PRECISION", INT2NUM(SQL_DESC_PRECISION));
rb_define_const(mDB2CLI, "SQL_DESC_SCALE", INT2NUM(SQL_DESC_SCALE));
rb_define_const(mDB2CLI, "SQL_DESC_SEARCHABLE", INT2NUM(SQL_DESC_SEARCHABLE));
rb_define_const(mDB2CLI, "SQL_DESC_TABLE_NAME", INT2NUM(SQL_DESC_TABLE_NAME));
rb_define_const(mDB2CLI, "SQL_DESC_TYPE", INT2NUM(SQL_DESC_TYPE));
rb_define_const(mDB2CLI, "SQL_DESC_TYPE_NAME", INT2NUM(SQL_DESC_TYPE_NAME));
rb_define_const(mDB2CLI, "SQL_DESC_UNSIGNED", INT2NUM(SQL_DESC_UNSIGNED));
rb_define_const(mDB2CLI, "SQL_DESC_UPDATABLE", INT2NUM(SQL_DESC_UPDATABLE));
rb_define_const(mDB2CLI, "SQL_DESC_BASE_COLUMN_NAME", INT2NUM(SQL_DESC_BASE_COLUMN_NAME));
rb_define_const(mDB2CLI, "SQL_DESC_BASE_TABLE_NAME", INT2NUM(SQL_DESC_BASE_TABLE_NAME));
rb_define_const(mDB2CLI, "SQL_DESC_CONCISE_TYPE", INT2NUM(SQL_DESC_CONCISE_TYPE));
rb_define_const(mDB2CLI, "SQL_DESC_LENGTH", INT2NUM(SQL_DESC_LENGTH));
rb_define_const(mDB2CLI, "SQL_DESC_LITERAL_PREFIX", INT2NUM(SQL_DESC_LITERAL_PREFIX));
rb_define_const(mDB2CLI, "SQL_DESC_LITERAL_SUFFIX", INT2NUM(SQL_DESC_LITERAL_SUFFIX));
rb_define_const(mDB2CLI, "SQL_DESC_LOCAL_TYPE_NAME", INT2NUM(SQL_DESC_LOCAL_TYPE_NAME));
rb_define_const(mDB2CLI, "SQL_DESC_NUM_PREC_RADIX", INT2NUM(SQL_DESC_NUM_PREC_RADIX));
rb_define_const(mDB2CLI, "SQL_DESC_UNNAMED", INT2NUM(SQL_DESC_UNNAMED));
--- NEW FILE: db2cli.c ---
/*
* IBM DB2 CLI 5.0 (Call Level Interface) Module for Ruby
*
* file: db2cli.c
* author: Michael Neumann (ne...@s-...)
* id: $Id: db2cli.c,v 1.1 2002/09/05 09:57:13 mneumann Exp $
*
* Copyright (C) 2001 by Michael Neumann.
* Released under the same terms as Ruby itself.
*
*/
/**********************************************************************
Description:
======================================================================
- SQLRETURN is always returned as Ruby-Integer (Fixnum or Bignum)
- any SQLHANDLE-type (SQLHENV, SQLHDBC, SQLHSTMT, SQLHDESC) is given
or returned as Ruby-Integer (Fixnum or Bignum)
- SQLSMALLINT etc. are all Ruby-Integer
**********************************************************************/
/**********************************************************************
Strange Things:
======================================================================
- after allocating an Environment-Handle "p 5.7" gives "5,7.0" on my
system (in Germany correct would be "5,7"). Fault of Linux ????
**********************************************************************/
/* Includes */
#include <stdio.h>
#include <stdlib.h>
#include "sqlcli1.h"
#include "ruby.h"
/* Macros */
#define TO_C_INT(val) NUM2INT(val)
#define TO_RUBY_INT(val) INT2NUM(val)
#define MUST_BE_STRING(val) Check_Type(val, T_STRING)
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#define MIN(a,b) ((a) < (b) ? (a) : (b))
/* Global Variables */
static VALUE mDB2CLI;
static VALUE cDate, cTime, cTimestamp;
static VALUE objNull; /* object for a SQL NULL value */
/* Functions */
/*******************************************************
SQLAllocHandle
=======================================================
PARAMS: handle_type, input_handle : Integer
RETURNS: rc, output_handle : Integer
********************************************************/
static VALUE
db2_SQLAllocHandle(self, handle_type, input_handle)
VALUE self;
VALUE handle_type, input_handle;
{
SQLRETURN rc;
SQLHANDLE output_handle;
rc = SQLAllocHandle(
(SQLSMALLINT) TO_C_INT(handle_type),
(SQLHANDLE) TO_C_INT(input_handle),
(SQLHANDLE*) &output_handle
);
return rb_ary_new3(2, TO_RUBY_INT(rc), TO_RUBY_INT(output_handle));
}
/*******************************************************
SQLFreeHandle
=======================================================
PARAMS: handle_type, handle : Integer
RETURNS: rc : Integer
********************************************************/
static VALUE
db2_SQLFreeHandle(self, handle_type, handle)
VALUE self;
VALUE handle_type, handle;
{
SQLRETURN rc;
rc = SQLFreeHandle(
(SQLSMALLINT) TO_C_INT(handle_type),
(SQLHANDLE) TO_C_INT(handle)
);
return TO_RUBY_INT(rc);
}
/*******************************************************
SQLFreeStmt
=======================================================
PARAMS: statement_handle, option : Integer
RETURNS: rc : Integer
********************************************************/
static VALUE
db2_SQLFreeStmt(self, statement_handle, option)
VALUE self;
VALUE statement_handle, option;
{
SQLRETURN rc;
rc = SQLFreeStmt(
(SQLHSTMT) TO_C_INT(statement_handle),
(SQLUSMALLINT) TO_C_INT(option)
);
return TO_RUBY_INT(rc);
}
/*******************************************************
SQLDataSources
=======================================================
PARAMS: environment_handle : Integer,
direction : Integer,
server_name_length : Integer, (buffer-length)
description_length : Integer (buffer-length)
RETURNS: rc : Integer,
server_name : String,
server_name_length : Integer, (bytes available)
description : String,
description_length : Integer (bytes available)
********************************************************/
static VALUE
db2_SQLDataSources(self, environment_handle, direction,
server_name_length, description_length)
VALUE self;
VALUE environment_handle, direction;
VALUE server_name_length, description_length;
{
SQLRETURN rc;
SQLCHAR* server_name;
SQLCHAR* description;
SQLSMALLINT sl; /* server_name_length */
SQLSMALLINT dl; /* description_length */
SQLSMALLINT sn_length; /* real server_name_length */
SQLSMALLINT ds_length; /* real description_length */
VALUE retval;
sl = TO_C_INT(server_name_length);
dl = TO_C_INT(description_length);
server_name = (SQLCHAR*) ALLOC_N(SQLCHAR, sl);
description = (SQLCHAR*) ALLOC_N(SQLCHAR, dl);
rc = SQLDataSources(
(SQLHENV) TO_C_INT(environment_handle),
(SQLUSMALLINT) TO_C_INT(direction),
(SQLCHAR*) server_name,
(SQLSMALLINT) sl,
(SQLSMALLINT*) &sn_length,
(SQLCHAR*) description,
(SQLSMALLINT) dl,
(SQLSMALLINT*) &ds_length
);
retval = rb_ary_new3(
5,
TO_RUBY_INT(rc),
rb_str_new(server_name, MIN(sl, sn_length)),
TO_RUBY_INT(sn_length),
rb_str_new(description, MIN(dl, ds_length)),
TO_RUBY_INT(ds_length)
);
free((void*)description);
free((void*)server_name);
return retval;
}
/*******************************************************
SQLConnect
=======================================================
PARAMS: connection_handle : Integer,
server_name, user_name, auth : String
RETURNS: rc : Integer
********************************************************/
static VALUE
db2_SQLConnect(self, connection_handle, server_name, user_name, auth)
VALUE self;
VALUE connection_handle, server_name, user_name, auth;
{
SQLRETURN rc;
MUST_BE_STRING(server_name);
MUST_BE_STRING(user_name);
MUST_BE_STRING(auth);
rc = SQLConnect(
(SQLHDBC) TO_C_INT(connection_handle),
(SQLCHAR *FAR) RSTRING(server_name)->ptr,
(SQLSMALLINT) RSTRING(server_name)->len,
(SQLCHAR *FAR) RSTRING(user_name)->ptr,
(SQLSMALLINT) RSTRING(user_name)->len,
(SQLCHAR *FAR) RSTRING(auth)->ptr,
(SQLSMALLINT) RSTRING(auth)->len
);
return TO_RUBY_INT(rc);
}
/*******************************************************
SQLDisconnect
=======================================================
PARAMS: connection_handle : Integer
RETURNS: rc : Integer
********************************************************/
static VALUE
db2_SQLDisconnect(self, connection_handle)
VALUE self;
VALUE connection_handle;
{
SQLRETURN rc;
rc = SQLDisconnect(
(SQLHDBC) TO_C_INT(connection_handle)
);
return TO_RUBY_INT(rc);
}
/*******************************************************
SQLPrepare
=======================================================
PARAMS: statement_handle : Integer,
statement_text : String
RETURNS: rc : Integer
********************************************************/
static VALUE
db2_SQLPrepare(self, statement_handle, statement_text)
VALUE self;
VALUE statement_handle, statement_text;
{
SQLRETURN rc;
MUST_BE_STRING(statement_text);
rc = SQLPrepare(
(SQLHSTMT) TO_C_INT(statement_handle),
(SQLCHAR *FAR) RSTRING(statement_text)->ptr,
(SQLINTEGER) RSTRING(statement_text)->len
);
return TO_RUBY_INT(rc);
}
/*******************************************************
SQLNumResultCols
=======================================================
PARAMS: statement_handle : Integer
RETURNS: rc, column_count : Integer
********************************************************/
static VALUE
db2_SQLNumResultCols(self, statement_handle)
VALUE self;
VALUE statement_handle;
{
SQLRETURN rc;
SQLSMALLINT column_count;
rc = SQLNumResultCols(
(SQLHSTMT) TO_C_INT(statement_handle),
(SQLSMALLINT*) &column_count
);
return rb_ary_new3(2, TO_RUBY_INT(rc), TO_RUBY_INT(column_count));
}
/*******************************************************
SQLDescribeCol
=======================================================
PARAMS: statement_handle : Integer,
column_number : Integer,
buffer_length : Integer (for column_name)
RETURNS: rc : Integer,
column_name : String | nil,
name_length : Integer,
data_type : Integer,
column_size : Integer,
decimal_digits : Integer,
nullable : Integer
********************************************************/
static VALUE
db2_SQLDescribeCol(self, statement_handle, column_number, buffer_length)
VALUE self;
VALUE statement_handle, column_number, buffer_length;
{
SQLRETURN rc;
SQLCHAR* colname_ptr;
SQLSMALLINT name_length, data_type, decimal_digits, nullable;
SQLUINTEGER column_size;
SQLSMALLINT bl; /* buffer_length */
VALUE retval;
bl = TO_C_INT(buffer_length);
colname_ptr = (SQLCHAR*) ALLOC_N(SQLCHAR, bl);
rc = SQLDescribeCol(
(SQLHSTMT) TO_C_INT(statement_handle),
(SQLUSMALLINT) TO_C_INT(column_number),
(SQLCHAR *) colname_ptr,
(SQLSMALLINT) bl,
(SQLSMALLINT*) &name_length,
(SQLSMALLINT*) &data_type,
(SQLUINTEGER*) &column_size,
(SQLSMALLINT*) &decimal_digits,
(SQLSMALLINT*) &nullable
);
retval = rb_ary_new3(
7,
TO_RUBY_INT(rc),
colname_ptr == NULL ? Qnil : rb_str_new(colname_ptr, MIN(name_length, bl)),
TO_RUBY_INT(name_length),
TO_RUBY_INT(data_type),
TO_RUBY_INT(column_size),
TO_RUBY_INT(decimal_digits),
TO_RUBY_INT(nullable)
);
free(colname_ptr);
return retval;
}
/*******************************************************
SQLColAttribute
=======================================================
PARAMS: statement_handle : Integer,
column_number : Integer,
field_identifier : Integer,
buffer_length : Integer | nil (nil == numeric_attribute)
RETURNS: if numeric_attribute (buffer_length==nil):
rc : Integer,
numeric_attribute : Integer
elsif character_attribute (buffer_length != nil):
rc : Integer,
character_attribute : String,
string_length : Integer
********************************************************/
static VALUE
db2_SQLColAttribute(self, statement_handle, column_number, field_identifier, buffer_length)
VALUE self;
VALUE statement_handle, column_number, field_identifier, buffer_length;
{
SQLRETURN rc;
SQLSMALLINT bl; /* buffer_length */
SQLPOINTER character_attr_ptr;
SQLSMALLINT string_length;
signed long numeric_attribute;
VALUE retval;
if (NIL_P(buffer_length) != 0) {
/* numeric_attribute */
bl = 0;
character_attr_ptr = NULL;
}
else {
/* character_attribute */
bl = TO_C_INT(buffer_length);
character_attr_ptr = (SQLPOINTER) ALLOC_N(char, bl);
}
rc = SQLColAttribute(
(SQLHSTMT) TO_C_INT(statement_handle),
(SQLUSMALLINT) TO_C_INT(column_number),
(SQLSMALLINT) TO_C_INT(field_identifier),
(SQLPOINTER) character_attr_ptr,
(SQLSMALLINT) bl,
(SQLSMALLINT*) &string_length,
(SQLPOINTER) &numeric_attribute
);
if (NIL_P(buffer_length) != 0) {
/* numeric_attribute */
retval = rb_ary_new3(
2,
TO_RUBY_INT(rc),
TO_RUBY_INT(numeric_attribute)
);
}
else {
/* character_attribute */
retval = rb_ary_new3(
3,
TO_RUBY_INT(rc),
rb_str_new(character_attr_ptr, MIN(string_length, bl)),
TO_RUBY_INT(string_length)
);
free(character_attr_ptr);
}
return retval;
}
/*******************************************************
SQLExecDirect
=======================================================
PARAMS: statement_handle : Integer,
statement_text : String
RETURNS: rc : Integer
********************************************************/
static VALUE
db2_SQLExecDirect(self, statement_handle, statement_text)
VALUE self;
VALUE statement_handle, statement_text;
{
SQLRETURN rc;
MUST_BE_STRING(statement_text);
rc = SQLExecDirect(
(SQLHSTMT) TO_C_INT(statement_handle),
(SQLCHAR *FAR) RSTRING(statement_text)->ptr,
(SQLINTEGER) RSTRING(statement_text)->len
);
return TO_RUBY_INT(rc);
}
/*******************************************************
SQLExecute
=======================================================
PARAMS: statement_handle : Integer
RETURNS: rc : Integer
********************************************************/
static VALUE
db2_SQLExecute(self, statement_handle)
VALUE self;
VALUE statement_handle;
{
SQLRETURN rc;
rc = SQLExecute(
(SQLHSTMT) TO_C_INT(statement_handle)
);
return TO_RUBY_INT(rc);
}
/*******************************************************
SQLRowCount
=======================================================
PARAMS: statement_handle : Integer
RETURNS: rc, row_count : Integer
********************************************************/
static VALUE
db2_SQLRowCount(self, statement_handle)
VALUE self;
VALUE statement_handle;
{
SQLRETURN rc;
SQLINTEGER row_count;
rc = SQLRowCount(
(SQLHSTMT) TO_C_INT(statement_handle),
(SQLINTEGER*) &row_count
);
return rb_ary_new3(2, TO_RUBY_INT(rc), TO_RUBY_INT(row_count));
}
/*******************************************************
SQLFetch
=======================================================
PARAMS: statement_handle : Integer
RETURNS: rc : Integer
********************************************************/
static VALUE
db2_SQLFetch(self, statement_handle)
VALUE self;
VALUE statement_handle;
{
SQLRETURN rc;
rc = SQLFetch(
(SQLHSTMT) TO_C_INT(statement_handle)
);
return TO_RUBY_INT(rc);
}
/*******************************************************
SQLFetchScroll
=======================================================
PARAMS: statement_handle : Integer,
fetch_orientation : Integer,
fetch_offset : Integer
RETURNS: rc : Integer
********************************************************/
static VALUE
db2_SQLFetchScroll(self, statement_handle, fetch_orientation, fetch_offset)
VALUE self;
VALUE statement_handle, fetch_orientation, fetch_offset;
{
SQLRETURN rc;
rc = SQLFetchScroll(
(SQLHSTMT) TO_C_INT(statement_handle),
(SQLSMALLINT) TO_C_INT(fetch_orientation),
(SQLINTEGER) TO_C_INT(fetch_offset)
);
return TO_RUBY_INT(rc);
}
/*******************************************************
SQLGetData
=======================================================
PARAMS: statement_handle : Integer,
column_number : Integer,
target_type : Integer, (e.g. SQL_BLOB)
buffer_length = nil : Integer (nil for e.g. SQL_INTEGER)
RETURNS: rc : Integer,
column : ?,
strlen_or_indptr :
********************************************************/
static VALUE
db2_SQLGetData(argc, argv, self)
int argc;
VALUE *argv;
VALUE self;
{
VALUE statement_handle, column_number, target_type, buffer_length;
SQLRETURN rc;
SQLINTEGER strlen_or_indptr;
SQLHSTMT sh; /* statement_handle */
SQLUSMALLINT cn; /* column_number */
SQLINTEGER bl; /* buffer_length */
VALUE retval;
union {
SQLDOUBLE dbl;
SQLREAL real;
SQLINTEGER integer;
SQLSMALLINT smallint;
DATE_STRUCT date;
TIME_STRUCT time;
TIMESTAMP_STRUCT timestamp;
} ptr_value;
SQLPOINTER ptr;
rb_scan_args(argc, argv, "31", &statement_handle, &column_number,
&target_type, &buffer_length);
sh = TO_C_INT(statement_handle);
cn = TO_C_INT(column_number);
if (NIL_P(buffer_length) != 0) {
bl = 0;
}
else {
bl = TO_C_INT(buffer_length);
}
#define CALL_SQL_GET_DATA(ptr, type, len) \
rc = SQLGetData( \
(SQLHSTMT) sh, \
(SQLUSMALLINT) cn, \
(SQLSMALLINT) type, \
(SQLPOINTER) ptr, \
(SQLINTEGER) len, \
(SQLINTEGER*) &strlen_or_indptr \
);
#define RETVAL(val) \
if (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO) \
retval = \
(strlen_or_indptr == SQL_NULL_DATA) ? objNull : val; \
else \
retval = Qnil; \
switch (TO_C_INT(target_type)) {
case SQL_DOUBLE:
case SQL_FLOAT:
CALL_SQL_GET_DATA(&ptr_value, SQL_C_DOUBLE, sizeof(SQLDOUBLE));
RETVAL( rb_float_new(ptr_value.dbl) );
break;
case SQL_REAL:
CALL_SQL_GET_DATA(&ptr_value, SQL_C_FLOAT, sizeof(SQLREAL));
RETVAL( rb_float_new(ptr_value.real) );
break;
case SQL_INTEGER:
CALL_SQL_GET_DATA(&ptr_value, SQL_C_LONG, sizeof(SQLINTEGER));
RETVAL( TO_RUBY_INT(ptr_value.integer) );
break;
case SQL_SMALLINT:
CALL_SQL_GET_DATA(&ptr_value, SQL_C_SHORT, sizeof(SQLSMALLINT));
RETVAL( TO_RUBY_INT(ptr_value.smallint) );
break;
case SQL_TYPE_DATE:
CALL_SQL_GET_DATA(&ptr_value, SQL_C_TYPE_DATE, sizeof(DATE_STRUCT));
RETVAL( rb_funcall( cDate, rb_intern("new"), 3,
TO_RUBY_INT(ptr_value.date.year),
TO_RUBY_INT(ptr_value.date.month),
TO_RUBY_INT(ptr_value.date.day) ) );
break;
case SQL_TYPE_TIME:
CALL_SQL_GET_DATA(&ptr_value, SQL_C_TYPE_TIME, sizeof(TIME_STRUCT));
RETVAL( rb_funcall( cTime, rb_intern("new"), 3,
TO_RUBY_INT(ptr_value.time.hour),
TO_RUBY_INT(ptr_value.time.minute),
TO_RUBY_INT(ptr_value.time.second) ) );
break;
case SQL_TYPE_TIMESTAMP:
CALL_SQL_GET_DATA(&ptr_value, SQL_C_TYPE_TIMESTAMP, sizeof(TIMESTAMP_STRUCT));
RETVAL( rb_funcall( cTimestamp, rb_intern("new"), 7,
TO_RUBY_INT(ptr_value.timestamp.year),
TO_RUBY_INT(ptr_value.timestamp.month),
TO_RUBY_INT(ptr_value.timestamp.day),
TO_RUBY_INT(ptr_value.timestamp.hour),
TO_RUBY_INT(ptr_value.timestamp.minute),
TO_RUBY_INT(ptr_value.timestamp.second),
TO_RUBY_INT(ptr_value.timestamp.fraction) ) );
break;
case SQL_CHAR:
case SQL_CLOB:
case SQL_LONGVARCHAR:
case SQL_VARCHAR:
/* TODO: should handle SQL_DECIMAL and SQL_NUMERIC different ? */
case SQL_DECIMAL:
case SQL_NUMERIC:
ptr = (SQLPOINTER) ALLOC_N(SQLCHAR, bl);
CALL_SQL_GET_DATA(ptr, SQL_C_CHAR, bl);
RETVAL( rb_str_new(ptr, MIN(bl, strlen_or_indptr)) );
free((void*)ptr);
break;
case SQL_BLOB:
case SQL_BINARY:
case SQL_LONGVARBINARY:
case SQL_VARBINARY:
ptr = (SQLPOINTER) ALLOC_N(SQLCHAR, bl);
CALL_SQL_GET_DATA(ptr, SQL_C_BINARY, bl);
RETVAL( rb_str_new(ptr, MIN(bl, strlen_or_indptr)) );
free((void*)ptr);
break;
case SQL_BLOB_LOCATOR:
CALL_SQL_GET_DATA(&ptr_value, SQL_C_BLOB_LOCATOR, sizeof(SQLINTEGER));
RETVAL( TO_RUBY_INT(ptr_value.integer) );
break;
case SQL_CLOB_LOCATOR:
CALL_SQL_GET_DATA(&ptr_value, SQL_C_CLOB_LOCATOR, sizeof(SQLINTEGER));
RETVAL( TO_RUBY_INT(ptr_value.integer) );
break;
case SQL_DBCLOB_LOCATOR:
CALL_SQL_GET_DATA(&ptr_value, SQL_C_DBCLOB_LOCATOR, sizeof(SQLINTEGER));
RETVAL( TO_RUBY_INT(ptr_value.integer) );
break;
case SQL_BIGINT:
/* TODO: How large can a BIGINT be? ==> expect 200 bytes, should be enought? */
ptr = (SQLPOINTER) ALLOC_N(SQLCHAR, MAX(bl,200));
CALL_SQL_GET_DATA(ptr, SQL_C_CHAR, bl);
RETVAL( rb_str_new(ptr, MIN(bl, strlen_or_indptr)) );
rc = rb_funcall(rc, rb_intern("to_i"), 0);
free((void*)ptr);
break;
case SQL_DBCLOB:
case SQL_GRAPHIC:
case SQL_LONGVARGRAPHIC:
case SQL_VARGRAPHIC:
ptr = (SQLPOINTER) ALLOC_N(SQLCHAR, bl); /* NOTE: not SQLDBCHAR */
CALL_SQL_GET_DATA(ptr, SQL_C_DBCHAR, bl);
RETVAL( rb_str_new(ptr, MIN(bl, strlen_or_indptr)) );
free((void*)ptr);
break;
default:
rb_raise(rb_eTypeError, "Wrong parameter for target_type!");
};
#undef RETVAL
#undef CALL_SQL_GET_DATA
return rb_ary_new3(3, TO_RUBY_INT(rc), retval, TO_RUBY_INT(strlen_or_indptr));
}
/*******************************************************
SQLEndTran
=======================================================
PARAMS: handle_type, handle,
completion_type : Integer
RETURNS: rc : Integer
********************************************************/
static VALUE
db2_SQLEndTran(self, handle_type, handle, completion_type)
VALUE self;
VALUE handle_type, handle, completion_type;
{
SQLRETURN rc;
rc = SQLEndTran(
(SQLSMALLINT) TO_C_INT(handle_type),
(SQLHANDLE) TO_C_INT(handle),
(SQLSMALLINT) TO_C_INT(completion_type)
);
return TO_RUBY_INT(rc);
}
/*******************************************************
SQLGetDiagRec
=======================================================
PARAMS: handle_type, handle, rec_number,
buffer_length : Integer
RETURNS: rc : Integer,
sql_state : String,
native_error : Integer,
message_text : String,
text_length : Integer
********************************************************/
static VALUE
db2_SQLGetDiagRec(self, handle_type, handle, rec_number, buffer_length)
VALUE self;
VALUE handle_type, handle, rec_number, buffer_length;
{
SQLRETURN rc;
SQLCHAR sql_state[5];
SQLINTEGER native_error;
SQLCHAR* message_text;
SQLINTEGER bl; /* buffer_length */
SQLSMALLINT text_length;
VALUE retval;
bl = TO_C_INT(buffer_length);
message_text = (SQLCHAR*) ALLOC_N(SQLCHAR, bl);
rc = SQLGetDiagRec(
(SQLSMALLINT) TO_C_INT(handle_type),
(SQLHANDLE) TO_C_INT(handle),
(SQLSMALLINT) TO_C_INT(rec_number),
(SQLCHAR*) sql_state,
(SQLINTEGER*) &native_error,
(SQLCHAR*) message_text,
(SQLINTEGER) bl,
(SQLSMALLINT*) &text_length
);
retval = rb_ary_new3(
5,
TO_RUBY_INT(rc),
rb_str_new(sql_state, 5),
TO_RUBY_INT(native_error),
rb_str_new(message_text, MIN(bl, text_length)),
TO_RUBY_INT(text_length)
);
free(message_text);
return retval;
}
/*******************************************************
SQLTables
=======================================================
PARAMS: statement_handle : Integer,
catalog_name : String, (must be set to "")
schema_name : String,
table_name : String,
table_type : String (e.g. "TABLE, VIEW")
RETURNS: rc : Integer
********************************************************/
static VALUE
db2_SQLTables(self, statement_handle, catalog_name, schema_name,
table_name, table_type)
VALUE self;
VALUE statement_handle, catalog_name, schema_name;
VALUE table_name, table_type;
{
SQLRETURN rc;
MUST_BE_STRING(catalog_name);
MUST_BE_STRING(schema_name);
MUST_BE_STRING(table_name);
MUST_BE_STRING(table_type);
rc = SQLTables(
(SQLHSTMT) TO_C_INT(statement_handle),
(SQLCHAR *FAR) RSTRING(catalog_name)->ptr,
(SQLSMALLINT) RSTRING(catalog_name)->len,
(SQLCHAR *FAR) RSTRING(schema_name)->ptr,
(SQLSMALLINT) RSTRING(schema_name)->len,
(SQLCHAR *FAR) RSTRING(table_name)->ptr,
(SQLSMALLINT) RSTRING(table_name)->len,
(SQLCHAR *FAR) RSTRING(table_type)->ptr,
(SQLSMALLINT) RSTRING(table_type)->len
);
return TO_RUBY_INT(rc);
}
/* Init */
void Init_db2cli() {
mDB2CLI = rb_eval_string("DB2CLI");
#include "constants.h"
rb_define_module_function(mDB2CLI, "SQLAllocHandle", db2_SQLAllocHandle, 2);
rb_define_module_function(mDB2CLI, "SQLFreeHandle", db2_SQLFreeHandle, 2);
rb_define_module_function(mDB2CLI, "SQLFreeStmt", db2_SQLFreeStmt, 2);
rb_define_module_function(mDB2CLI, "SQLDataSources", db2_SQLDataSources, 4);
rb_define_module_function(mDB2CLI, "SQLConnect", db2_SQLConnect, 4);
rb_define_module_function(mDB2CLI, "SQLDisconnect", db2_SQLDisconnect, 1);
rb_define_module_function(mDB2CLI, "SQLPrepare", db2_SQLPrepare, 2);
rb_define_module_function(mDB2CLI, "SQLNumResultCols", db2_SQLNumResultCols, 1);
rb_define_module_function(mDB2CLI, "SQLDescribeCol", db2_SQLDescribeCol, 3);
rb_define_module_function(mDB2CLI, "SQLColAttribute", db2_SQLColAttribute, 4);
rb_define_module_function(mDB2CLI, "SQLExecDirect", db2_SQLExecDirect, 2);
rb_define_module_function(mDB2CLI, "SQLExecute", db2_SQLExecute, 1);
rb_define_module_function(mDB2CLI, "SQLRowCount", db2_SQLRowCount, 1);
rb_define_module_function(mDB2CLI, "SQLFetch", db2_SQLFetch, 1);
rb_define_module_function(mDB2CLI, "SQLFetchScroll", db2_SQLFetchScroll, 3);
rb_define_module_function(mDB2CLI, "SQLGetData", db2_SQLGetData, -1); /* 3-4 */
rb_define_module_function(mDB2CLI, "SQLEndTran", db2_SQLEndTran, 3);
rb_define_module_function(mDB2CLI, "SQLGetDiagRec", db2_SQLGetDiagRec, 4);
rb_define_module_function(mDB2CLI, "SQLTables", db2_SQLTables, 5);
/* Datatype classes or objects */
cDate = rb_eval_string("DB2CLI::Date");
cTime = rb_eval_string("DB2CLI::Time");
cTimestamp = rb_eval_string("DB2CLI::Timestamp");
objNull = rb_eval_string("DB2CLI::Null");
}
--- NEW FILE: extconf.rb ---
require "mkmf"
if RUBY_PLATFORM =~ /(mswin32|cygwin|mingw)/
# version 6.1 Windows 95/98/NT
DB2LIB = "db2cli"
DB2DIR = ENV["DB2DIR"] || "C:/SQLLIB"
else
# version 7.1 Linux
DB2LIB = "db2"
DB2DIR = ENV["DB2DIR"] || "/usr/IBMdb2/V7.1"
end
dir_config( "db2", DB2DIR + "/include", DB2DIR + "/lib" )
if have_library(DB2LIB, "SQLConnect") and
have_header("sqlcli.h")
create_makefile "db2cli"
else
puts "ABORT: Could not locate DB2 libraries or headers!"
puts "Please set DB2DIR to your DB2 directory, e.g. /usr/IBMdb2/V7.1 (UNIX) " +
"or C:/SQLLIB (Windows)"
exit 1
end
|
|
From: Michael N. <mne...@us...> - 2002-09-05 09:57:17
|
Update of /cvsroot/ruby-dbi/subprojects/ruby-db2/utils
In directory usw-pr-cvs1:/tmp/cvs-serv2947/ruby-db2/utils
Added Files:
create_constants.rb
Log Message:
initial import from local CVS repository
--- NEW FILE: create_constants.rb ---
OTHER = %w(
SQL_SUCCESS SQL_SUCCESS_WITH_INFO SQL_INVALID_HANDLE SQL_STILL_EXECUTING
SQL_ERROR SQL_NO_DATA_FOUND SQL_NULL_DATA
SQL_HANDLE_ENV SQL_HANDLE_DBC SQL_HANDLE_STMT SQL_HANDLE_DESC
SQL_NULL_HANDLE SQL_NULL_HENV SQL_NULL_HDBC SQL_NULL_HSTMT SQL_NULL_HDESC
SQL_NO_NULLS SQL_NULLABLE
SQL_COMMIT SQL_ROLLBACK
SQL_TRUE SQL_FALSE
SQL_MAX_DSN_LENGTH
SQL_BIGINT SQL_BLOB SQL_BLOB_LOCATOR SQL_CHAR SQL_BINARY SQL_CLOB
SQL_CLOB_LOCATOR SQL_TYPE_DATE SQL_DBCLOB SQL_DBCLOB_LOCATOR
SQL_DECIMAL SQL_DOUBLE SQL_FLOAT SQL_GRAPHIC SQL_INTEGER
SQL_LONGVARCHAR SQL_LONGVARBINARY SQL_LONGVARGRAPHIC SQL_NUMERIC
SQL_REAL SQL_SMALLINT SQL_TYPE_TIME SQL_TYPE_TIMESTAMP SQL_VARCHAR
SQL_VARBINARY SQL_VARGRAPHIC
SQL_FETCH_NEXT SQL_FETCH_PRIOR SQL_FETCH_RELATIVE SQL_FETCH_ABSOLUTE
SQL_FETCH_FIRST SQL_FETCH_LAST SQL_FETCH_BOOKMARK
SQL_CLOSE SQL_DROP SQL_UNBIND SQL_RESET_PARAMS
)
SQL_DESC = %w(
AUTO_UNIQUE_VALUE CASE_SENSITIVE CATALOG_NAME COUNT DISPLAY_SIZE LABEL
DISTINCT_TYPE OCTET_LENGTH FIXED_PREC_SCALE NAME NULLABLE SCHEMA_NAME
PRECISION SCALE SEARCHABLE TABLE_NAME TYPE TYPE_NAME UNSIGNED UPDATABLE
BASE_COLUMN_NAME BASE_TABLE_NAME CONCISE_TYPE LENGTH LITERAL_PREFIX
LITERAL_SUFFIX LOCAL_TYPE_NAME NUM_PREC_RADIX UNNAMED
).collect {|i| "SQL_DESC_#{i}"}
CONSTANTS = OTHER + SQL_DESC
File.open("constants.h", "w+") {|f|
CONSTANTS.each {|c|
f.puts %{rb_define_const(mDB2CLI, "#{c}", INT2NUM(#{c}));}
}
f.puts
}
|
|
From: Michael N. <mne...@us...> - 2002-09-05 09:57:17
|
Update of /cvsroot/ruby-dbi/subprojects/ruby-db2/samples
In directory usw-pr-cvs1:/tmp/cvs-serv2947/ruby-db2/samples
Added Files:
db2.rb sqlsh.rb test.rb test2.rb
Log Message:
initial import from local CVS repository
--- NEW FILE: db2.rb ---
require "db2/db2cli.rb"
module DB2
FINALIZE_INFO = {}
FINALIZE_PROC = proc do |id|
info = FINALIZE_INFO[id]
if $DEBUG then
$stderr.puts "freeing handle <#{info[1]}> (#{info[0]})"
end
DB2CLI::SQLFreeHandle(info[0], info[1])
end
class CLIError < Exception
attr_reader :sql_state, :native_error, :message_text
def initialize(sql_state, native_error, message_text)
@sql_state = sql_state
@native_error = native_error
@message_text = message_text
end
def message
@message_text
end
end
class Handle
include DB2CLI
def initialize(handle_type, parent_handle)
@handle_type = handle_type
@handle = parent_handle
rc, handle = SQLAllocHandle(@handle_type, @handle)
check_rc(rc)
@handle = handle
add_finalizer
end
def free
rc = SQLFreeHandle(@handle_type, @handle)
check_rc(rc)
end
def handle
@handle
end
private
def add_finalizer
DB2::FINALIZE_INFO[self.id] = [@handle_type.dup, @handle.dup]
ObjectSpace.define_finalizer(self, DB2::FINALIZE_PROC)
end
def check_rc(rc)
if rc != SQL_SUCCESS and rc != SQL_SUCCESS_WITH_INFO then
err = SQLGetDiagRec(@handle_type, @handle, 1, 1024)
raise CLIError.new(err[1], err[2], err[3])
end
end
end # class Handle
class Environment < Handle
def initialize
super(SQL_HANDLE_ENV, SQL_NULL_HANDLE)
end
def dataSources
data_sources_buffer
end
def createConnection(*a)
Connection.new(self, *a)
end
private
def data_sources_buffer(buffer_length = 1024)
retval = []
max_buffer_length = buffer_length
a = SQLDataSources(@handle, SQL_FETCH_FIRST, SQL_MAX_DSN_LENGTH+1, buffer_length)
retval << [a[1], a[3]]
max_buffer_length = [max_buffer_length, a[4]].max
loop do
a = SQLDataSources(@handle, SQL_FETCH_NEXT, SQL_MAX_DSN_LENGTH+1, buffer_length)
break if a[0] == SQL_NO_DATA_FOUND
retval << [a[1], a[3]]
max_buffer_length = [max_buffer_length, a[4]].max
end
if max_buffer_length > buffer_length then
data_sources_buffer(max_buffer_length)
else
retval
end
end
end # class Environment
class Connection < Handle
def initialize(environment, *conn_params)
@env = environment
super(SQL_HANDLE_DBC, @env.handle)
@connected = false
unless conn_params.empty?
connect(*conn_params)
end
end
def connect(server_name, user_name="", auth="")
rc = SQLConnect(@handle, server_name, user_name, auth)
check_rc(rc)
@connected = true
end
def disconnect
rc = SQLDisconnect(@handle)
check_rc(rc)
@connected = false
end
def rollback
rc = SQLEndTran(@handle_type, @handle, SQL_ROLLBACK)
check_rc(rc)
end
def commit
rc = SQLEndTran(@handle_type, @handle, SQL_COMMIT)
check_rc(rc)
end
def createStatement
Statement.new(self)
end
end # class Connection
class Statement < Handle
def initialize(connection)
@conn = connection
super(SQL_HANDLE_STMT, @conn.handle)
end
def prepare(sql)
rc = SQLPrepare(@handle, sql)
check_rc(rc)
self
end
def freeStmt(options)
rc = SQLFreeStmt(@handle, options)
ckeck_rc(rc)
end
def execute
rc = SQLExecute(@handle)
check_rc(rc)
self
end
def execDirect(sql)
rc = SQLExecDirect(@handle, sql)
check_rc(rc)
self
end
def tables(schema_name="%", table_name="%", table_type="TABLE")
rc = SQLTables(@handle, "", schema_name, table_name, table_type)
check_rc(rc)
self
end
def rowCount
rc, rowcount = SQLRowCount(@handle)
check_rc(rc)
rowcount
end
def numResultCols
rc, cols = SQLNumResultCols(@handle)
check_rc(rc)
cols
end
def colNames
rc, nr_cols = SQLNumResultCols(@handle)
(1..nr_cols).collect do |c|
rc, name, bl, type, col_sz = SQLDescribeCol(@handle, c, 1024)
name
end
end
def fetchAll
if block_given?
while (row=fetchRow) do
yield row
end
else
res = []
while (row=fetchRow) do
res << row
end
res
end
end
def fetchRow(orientation=SQL_FETCH_NEXT, offset=0)
rc, nr_cols = SQLNumResultCols(@handle)
cols = (1..nr_cols).collect do |c|
rc, name, bl, type, col_sz = SQLDescribeCol(@handle, c, 1024)
[name, type, col_sz]
end
rc = SQLFetchScroll(@handle, orientation, offset)
return nil if rc == SQL_NO_DATA_FOUND
raise "ERROR" unless rc == SQL_SUCCESS
retval = []
cols.each_with_index do |c, i|
rc, content = SQLGetData(@handle, i+1, c[1], c[2])
retval << content
end
return retval
end
alias :fetch :fetchRow
end # class Statement
end # module DB2
--- NEW FILE: sqlsh.rb ---
require "readline"
require "db2"
class ReadlineControl
def initialize
@keywords = []
set_prompt
Readline.completion_proc = proc {|str| complete(str) }
end
def add_keywords(arr)
@keywords += arr
end
def complete(str)
@keywords.grep(/^#{Regexp.escape(str)}/i)
end
def set_prompt(prompt="> ")
@prompt = prompt
end
def readline
Readline.readline(@prompt, true)
end
end
if ARGV.size < 1 or ARGV.size > 3
puts
puts "USAGE: #{$0} database [, user [, password] ]"
puts
exit 1
else
DB = ARGV.shift
USER = ARGV.shift || ""
PASS = ARGV.shift || ""
end
puts
begin
print " CONNECT TO #{DB}"
print " USER '#{USER}'" unless USER.empty?
print " PASSWORD '#{PASS}'" unless PASS.empty?
puts
Env = DB2::Environment.new
Conn = Env.createConnection("SAMPLE")
rescue DB2::CLIError => err
puts
puts err.message
puts
end
puts
PROMPT = "db2 => "
PROMPT_CONT = "db2 =| "
SQL_KEYWORDS = %w(
INSERT DELETE UPDATE SELECT FROM WHERE IN LIKE SET VALUES INTO
CREATE TABLE DROP
COMMIT ROLLBACK
CHAR VARCHAR INT INTEGER NUMBER FLOAT REAL LONG CLOB BLOB DECIMAL DBCLOB DBBLOB
)
rd = ReadlineControl.new
rd.add_keywords SQL_KEYWORDS
rd.set_prompt(PROMPT)
def output_table(rows)
collength = []
rows.each {|r| r.each_with_index {|c,i|
r[i] = c.to_s.chomp("\000")
c = r[i]
collength[i] = c.size if collength[i].nil? or c.size > collength[i]
} }
split_line = " +"
collength.each {|col|
split_line << "-" * (col+2) + "+"
}
puts
puts split_line
# output table
rows.each_with_index {|r, rn|
print " |"
r.each_with_index {|c,i|
print sprintf(" %*2$s |", c.to_s, -(collength[i]))
}
puts
puts split_line if rn == 0
}
puts split_line
puts
end
loop {
line = rd.readline
line.chomp!
next if line.empty?
begin
if line =~ /^\\/ then
if line =~ /^\\list tables/i then
stmt = Conn.createStatement.tables
elsif line =~ /^\\list views/i then
stmt = Conn.createStatement.tables("%", "%", "VIEW")
elsif line =~ /^\\quit/i then
break
else
puts
puts "Unknown command!"
puts
next
end
else
# multi-line
if line[-1].chr == "\\" then
line.chop!
rd.set_prompt(PROMPT_CONT)
loop {
ln = rd.readline
line.chomp!
next if line.empty?
if ln[-1].chr == "\\" then
line += ln.chop
else
line += ln
break
end
}
end
rd.set_prompt(PROMPT)
stmt = Conn.createStatement.execDirect(line)
end
head = stmt.colNames
next if head.empty?
rows = stmt.fetchAll
rows[0,0] = [head]
output_table(rows)
rescue DB2::CLIError => err
puts
puts err.message
puts
end
}
Conn.disconnect
Conn.free
Env.free
--- NEW FILE: test.rb ---
require "db2/db2cli.rb"
include DB2CLI
rc, env = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE); p rc
puts "Datasources: "
p SQLDataSources(env, SQL_FETCH_FIRST, SQL_MAX_DSN_LENGTH+1, 200)
loop {
a = SQLDataSources(env, SQL_FETCH_NEXT, SQL_MAX_DSN_LENGTH+1, 200)
break if a[0] == SQL_NO_DATA_FOUND
p a
}
puts "--------------------"
readline
rc, dbc = SQLAllocHandle(SQL_HANDLE_DBC, env); p rc
p SQLConnect(dbc, "SAMPLE", "", "")
rc, stmt = SQLAllocHandle(SQL_HANDLE_STMT, dbc); p rc
p SQLPrepare(stmt, "SELECT * FROM EMPLOYEE")
p SQLExecute(stmt)
DELIM = " "
rc, COLS = SQLNumResultCols(stmt)
cols = (1..COLS).collect {|c|
rc, name, bl, type, col_sz = SQLDescribeCol(stmt, c, 100)
[name, type, col_sz]
}
cols.each {|c| print c[0], DELIM }
puts
while SQLFetch(stmt) == SQL_SUCCESS do
cols.each_with_index {|c, i|
rc, content = SQLGetData(stmt, i+1, c[1], 100)
print content, DELIM
}
puts
end
p SQLFreeStmt(stmt, SQL_CLOSE)
################
def get_row_as_hash(stmt)
rc, nr_cols = SQLNumResultCols(stmt)
cols = (1..nr_cols).collect do |c|
rc, name, bl, type, col_sz = SQLDescribeCol(stmt, c, 100)
[name, type, col_sz]
end
rc = SQLFetch(stmt)
return nil if rc == SQL_NO_DATA_FOUND
raise "ERROR" unless rc == SQL_SUCCESS
retval = {}
cols.each_with_index do |c, i|
rc, content = SQLGetData(stmt, i+1, c[1], c[2])
retval[c[0]] = content
end
return retval
end
################
puts "HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH"
p SQLTables(stmt, "", "", "%", "")
while (c=get_row_as_hash(stmt))
p c
end
puts "HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH"
p SQLFreeStmt(stmt, SQL_CLOSE)
p SQLExecDirect(stmt, "SELECT 2, 2.3+3.4, 'Hallo' FROM EMPLOYEE")
#p SQLExecDirect(stmt, "SELECT YEARS FROM STAFF WHERE YEARS IS NULL")
p "*************************************"
p SQLColAttribute(stmt, 2, SQL_DESC_TYPE_NAME, 200)
p SQLColAttribute(stmt, 2, SQL_DESC_TYPE, nil)
p "*************************************"
p SQLFetch(stmt)
puts "=================================="
p SQLGetData(stmt, 1, SQL_INTEGER)
p SQLGetData(stmt, 1, SQL_SMALLINT)
p SQLGetData(stmt, 2, SQL_DOUBLE)
#p SQLGetData(stmt, 2, SQL_FLOAT)
#p SQLGetData(stmt, 2, SQL_REAL)
p SQLGetData(stmt, 3, SQL_INTEGER, 20000)
puts "=================================="
p SQLFreeStmt(stmt, SQL_CLOSE)
puts "-----111111111111111-----------"
p SQLExecDirect(stmt, "INSERT INTO meintable (test,hallo) VALUES (2,3)")
p SQLGetDiagRec(SQL_HANDLE_STMT, stmt, 1, 1000)
p SQLRowCount(stmt)
p SQLEndTran(SQL_HANDLE_DBC, dbc, SQL_ROLLBACK)
p SQLFreeHandle(SQL_HANDLE_STMT, stmt)
p SQLDisconnect(dbc)
p SQLFreeHandle(SQL_HANDLE_DBC, dbc)
p SQLFreeHandle(SQL_HANDLE_ENV, env)
--- NEW FILE: test2.rb ---
require "db2.rb"
include DB2
env = Environment.new
conn = env.createConnection("SAMPLE")
stmt = conn.createStatement
stmt.prepare("SELECT * FROM EMPLOYEE").execute
p stmt.fetchAll
conn.disconnect
|
|
From: Michael N. <mne...@us...> - 2002-09-05 09:57:17
|
Update of /cvsroot/ruby-dbi/subprojects/ruby-db2/lib In directory usw-pr-cvs1:/tmp/cvs-serv2947/ruby-db2/lib Added Files: PATHCONV Log Message: initial import from local CVS repository --- NEW FILE: PATHCONV --- db2 db2 db2 |
|
From: Michael N. <mne...@us...> - 2002-09-05 09:57:16
|
Update of /cvsroot/ruby-dbi/subprojects/ruby-db2/ext In directory usw-pr-cvs1:/tmp/cvs-serv2947/ruby-db2/ext Added Files: PATHCONV Log Message: initial import from local CVS repository --- NEW FILE: PATHCONV --- db2 db2 db2 |
|
From: Michael N. <mne...@us...> - 2002-09-05 09:57:16
|
Update of /cvsroot/ruby-dbi/subprojects/ruby-db2
In directory usw-pr-cvs1:/tmp/cvs-serv2947/ruby-db2
Added Files:
ChangeLog Makefile README setup.rb
Log Message:
initial import from local CVS repository
--- NEW FILE: ChangeLog ---
=begin
= ChangeLog for Ruby/DB2
: 0.3
* sqlsh.rb interactive SQL shell
* Added CLI-functions:
SQLFreeStmt
: 0.2
* DBD driver for DB2 is available (show RAA under DBD/DB2)
* added more examples
* added README
* Load path for require now prefixed by db2/
* Changed directory layout and using setup.rb
* Added following CLI-functions:
SQLDataSources, SQLColAttribute, SQLFetchScroll,
SQLTables
* Now all datatypes in SQLGetData can be handled.
: 0.1
* Only the following CLI-functions are implemented:
SQLAllocHandle, SQLFreeHandle, SQLConnect, SQLDisconnect,
SQLPrepare, SQLNumResultCols, SQLDescribeCol,
SQLExecDirect, SQLExecute, SQLRowCount, SQLFetch,
SQLGetData, SQLEndTran, SQLGetDiagRec.
* No high-level interface!
* Tested with DB2 7.1 on Suse Linux 6.3.
= History
$Id: ChangeLog,v 1.1 2002/09/05 09:57:13 mneumann Exp $
=end
--- NEW FILE: Makefile ---
export: clean
mkdir -p work
(cd work; cvs export -D now ruby/ruby-db2)
(cd work/ruby/ruby-db2; rm -rf utils Makefile)
clean:
rm -rf work
pack:
mkdir -p work/pack
( cd work/pack; cvs export -r Release-$(TAG_MAJOR)_$(TAG_MINOR) ruby/ruby-db2; \
cd ruby/ruby-db2; rm -rf utils Makefile; \
cd ..; tar -cvzf ruby-db2-$(TAG_MAJOR).$(TAG_MINOR).tar.gz ruby-db2 )
--- NEW FILE: README ---
$Id: README,v 1.1 2002/09/05 09:57:13 mneumann Exp $
Ruby/DB2: IBM DB2 Module for Ruby
Copyright (C) 2001 by Michael Neumann (ne...@s-...)
Released under the same terms as Ruby itself.
PREREQUISITES
=============
* IBM DB2 installed (with CLI), tested with DB2 V7.1 on Suse Linxu 6.3 and
DB2 UDB V6.1 for Windows 95/98/NT.
* Ruby, only tested with Ruby 1.6.3, but should work with every version >= 1.6.
* C-Compiler
INSTALL
=======
To compile type the following:
ruby setup.rb config
ruby setup.rb setup
If you get an error message that no libraries and header files were found, then
you have to set DB2DIR to the correct path where DB2 was installed, e.g.:
export DB2DIR=/usr/IBMdb2/V7.1
or under Cygwin and DB2 installed in C:\SQLLIB:
export DB2DIR=C:/SQLLIB
To install, make sure you are the superuser (under UNIX type "su -l root")
and then type:
ruby setup.rb install
For more options on installation, type:
ruby setup.rb --help
The DB2 library files are installed in your site_ruby directory,
of the actual ruby-version (e.g. "site_ruby/1.6") under the
directory "db2" and the .so file under "$arch/db2", where $arch
is your architecure (e.g. i686-linux).
DOCUMENTATION
=============
Not yet written.
You should consult the DB2-CLI manual available from IBM's website and
look at the comments before each function in the file "ext/db2/db2cli.c".
The rule of thumb is that all parameters in the DB2-CLI manual which are
declared as "output" or "input/output" are returned by the function (in an array).
All input values which are of type HANDLE (HENV, HDBC, HSTMT...) are represented by
Integer parameters in the Ruby version.
SAMPLES
=======
See directory "samples".
--- NEW FILE: setup.rb ---
#
# setup.rb
#
# Copyright (c) 2000,2001 Minero Aoki <aa...@dp...>
#
# This program is free software.
# You can distribute/modify this program under the terms of
# the GNU General Public License version 2 or later.
#
require 'tempfile'
if i = ARGV.index(/\A--rbconfig=/) then
file = $'
ARGV.delete_at(i)
require file
else
require 'rbconfig'
end
class InstallError < StandardError; end
class Installer
Version = '2.0.4'
Copyright = 'Copyright (c) 2000,2001 Minero Aoki'
TASKS = {
'config' => 'save your config configurations',
'setup' => 'compiles extention or else',
'install' => 'installs packages',
'clean' => "does `make clean' for each extention",
'dryrun' => 'does test run',
'show' => 'shows current configuration'
}
TASK_ORDER = %w( config setup install clean dryrun show )
FILETYPES = %w( bin lib ext share )
def initialize( argv )
argv = argv.dup
@verbose = true
@no_harm = false
@config = {}
@task = nil
@other_args = []
@task = parsearg( argv )
parsearg_TASK @task, argv
unless @task == 'config' then
load_configs
check_packdesig
end
end
attr :config
attr :task
###
### arg proc.
###
def parsearg( argv )
task_re = /\A(?:#{TASKS.keys.join '|'})\z/
task = nil
arg = argv.shift
case arg
when /\A\w+\z/
unless task_re === arg then
raise InstallError, "wrong task: #{arg}"
end
task = arg
when '-h', '--help'
print_usage $stdout
exit 0
when '-v', '--version'
puts "setup.rb version #{Version}"
exit 0
when '--copyright'
puts Copyright
exit 0
else
raise InstallError, "unknown global option '#{arg}'"
end
task
end
def parsearg_TASK( task, argv )
mid = "parsearg_#{task}"
if respond_to? mid, true then
__send__ mid, argv
else
unless argv.empty? then
raise InstallError, "#{task}: unknown options: #{argv.join ' '}"
end
end
end
def parsearg_config( args )
@config_args = {}
re = /\A--(#{CONFIG_ORDER.join '|'})=/
args.each do |i|
m = re.match(i) or raise InstallError, "config: unknown option #{i}"
@config_args[ m[1] ] = m.post_match.strip
end
end
def parsearg_install( args )
args.each do |i|
if i == '--no-harm' then
@no_harm = true
else
raise InstallError, "#{@task}: wrong option #{i}"
end
end
end
def parsearg_dryrun( args )
@dryrun_args = args
end
def print_usage( out )
out.puts
out.puts 'Usage:'
out.puts ' ruby setup.rb <global option>'
out.puts ' ruby setup.rb <task> [<task options>]'
out.puts
out.puts 'Tasks:'
TASK_ORDER.each do |name|
out.printf " %-10s %s\n", name, TASKS[name]
end
fmt = " %-20s %s\n"
out.puts
out.puts 'Global options:'
out.printf fmt, '-h,--help', 'print this message'
out.printf fmt, '-v,--version', 'print version'
out.printf fmt, '--copyright', 'print copyright'
out.puts
out.puts 'Options for config:'
CONFIG_ORDER.each do |name|
dflt, arg, desc, dflt2 = CONFIG_OPTS[name]
dflt = dflt2 || dflt
out.printf " %-20s %s [%s]\n", "--#{name}=#{arg}", desc, dflt
end
out.printf " %-20s %s [%s]\n",
'--rbconfig=path', 'your rbconfig.rb to load', "running ruby's"
out.puts
out.puts 'Options for install:'
out.printf " %-20s %s [%s]\n",
'--no-harm', 'only display what to do if given', 'off'
out.puts
out.puts 'This archive includes:'
out.print ' ', packages().join(' '), "\n"
out.puts
end
###
### tasks
###
def execute
case @task
when 'config', 'setup', 'install', 'clean'
tryto @task
when 'show'
do_show
when 'dryrun'
do_dryrun
else
raise 'must not happen'
end
end
def tryto( task )
$stderr.printf "entering %s phase...\n", task
begin
__send__ 'do_' + task
rescue
$stderr.printf "%s failed\n", task
raise
end
$stderr.printf "%s done.\n", task
end
ConfigFile = 'config.save'
def do_config
CONFIG_OPTS.each do |k,v|
dflt, vname, desc = v
@config[k] = dflt
end
@config_args.each do |k,v|
setconf k, v
end
save_configs
end
def do_show
CONFIG_ORDER.each do |k|
v = @config[k]
if not v or v.empty? then
v = '(not specified)'
end
printf "%-10s %s\n", k, v
end
end
def do_setup
into_dir( 'bin' ) {
foreach_package do
Dir.foreach( '.' ) do |fname|
next unless File.file? fname
add_rubypath fname
end
end
}
into_dir( 'ext' ) {
foreach_package do
clean
extconf
make
end
}
end
def do_install
into_dir( 'bin' ) {
foreach_package do |targ, *dummy|
install_bin
end
}
into_dir( 'lib' ) {
foreach_package do |targ, topfile|
install_rb targ
if topfile then
create_topfile targ, topfile
end
end
}
into_dir( 'ext' ) {
foreach_package do |targ, *dummy|
install_so targ
end
}
into_dir( 'share' ) {
foreach_package do |targ, *dummy|
install_dat targ
end
}
end
def do_clean
into_dir( 'ext' ) {
foreach_package do
clean
end
}
# rmf ConfigFile
end
def do_dryrun
unless dir? 'tmp' then
$stderr.puts 'setup.rb: setting up temporaly environment...'
@verbose = $DEBUG
begin
@config['bin-dir'] = isdir(File.expand_path('.'), 'tmp', 'bin')
@config['rb-dir'] = isdir(File.expand_path('.'), 'tmp', 'lib')
@config['so-dir'] = isdir(File.expand_path('.'), 'tmp', 'ext')
@config['data-dir'] = isdir(File.expand_path('.'), 'tmp', 'share')
do_install
rescue
rmrf 'tmp'
$stderr.puts '[BUG] setup.rb bug: "dryrun" command failed'
raise
end
end
exec @config['ruby-path'],
'-I' + File.join('.', 'tmp', 'lib'),
'-I' + File.join('.', 'tmp', 'ext'),
*@dryrun_args
end
###
### lib
###
#
# config
#
c = ::Config::CONFIG
rubyname = c['ruby_install_name']
major = c['MAJOR'].to_i
minor = c['MINOR'].to_i
teeny = c['TEENY'].to_i
version = "#{major}.#{minor}"
arch = c['arch']
bindir = File.join( c['bindir'] )
rubylib = File.join( c['libdir'], 'ruby' )
datadir = File.join( c['datadir'] )
rubypath = File.join( bindir, rubyname )
# >=1.4.4 is new path
newpath_p = ((major >= 2) or
((major == 1) and
((minor >= 5) or
((minor == 4) and (teeny >= 4)))))
if newpath_p then
sitelibdir = File.join( rubylib, 'site_ruby', version )
else
sitelibdir = File.join( rubylib, version, 'site_ruby' )
end
stdlibdir = File.join( rubylib, version )
siterb = sitelibdir
siteso = File.join( sitelibdir, arch )
CONFIG_OPTS = {
'bin-dir' => [ bindir,
'path',
'directory to install commands' ],
'rb-dir' => [ siterb,
'path',
'directory to install ruby scripts' ],
'so-dir' => [ siteso,
'path',
'directory to install ruby extentions' ],
'data-dir' => [ datadir,
'path',
'directory to install data' ],
'ruby-path' => [ rubypath,
'path',
'path to ruby for #!' ],
'ruby-prog' => [ rubypath,
'path',
'path to ruby for installation' ],
'make-prog' => [ 'make',
'name',
'make program to compile ruby extentions' ],
'with' => [ '',
'name,name...',
'package name(s) you want to install',
'ALL' ],
'without' => [ '',
'name,name...',
'package name(s) you do not want to install' ]
}
CONFIG_ORDER = %w( bin-dir rb-dir so-dir ruby-path make-prog with without )
def save_configs
File.open( ConfigFile, 'w' ) do |f|
@config.each do |k,v|
f.printf "%s=%s\n", k, v if v
end
end
end
def load_configs
File.file? ConfigFile or raise InstallError, 'setup.rb config first'
File.foreach( ConfigFile ) do |line|
k, v = line.split( '=', 2 )
setconf k.strip, v.strip
end
end
def setconf( k, v )
if CONFIG_OPTS[k][1] == 'path' then
@config[k] = File.expand_path(v)
else
@config[k] = v
end
end
#
# packages
#
def check_packdesig
@with = extract_dirs( @config['with'] )
@without = extract_dirs( @config['without'] )
packs = packages
(@with + @without).each do |i|
if not packs.include? i and not dir? i then
raise InstallError, "no such package or directory '#{i}'"
end
end
end
def extract_dirs( s )
ret = []
s.split(',').each do |i|
if /[\*\?]/ === i then
tmp = Dir.glob(i)
tmp.delete_if {|d| not dir? d }
if tmp.empty? then
tmp.push i # causes error
else
ret.concat tmp
end
else
ret.push i
end
end
ret
end
def packages
ret = []
FILETYPES.each do |type|
next unless File.exist? type
foreach_record( "#{type}/PATHCONV" ) do |dir, pack, *dummy|
ret.push pack
end
end
ret.uniq
end
def foreach_package
path = {}
foreach_record( './PATHCONV' ) do |dir, pack, targ, topfile, *dummy|
path[dir] = [pack, targ, topfile]
end
base = File.basename( Dir.getwd )
Dir.foreach('.') do |dir|
next if dir[0] == ?.
next unless dir? dir
path[dir] or raise "abs path for package '#{dir}' not exist"
pack, targ, topfile = path[dir]
if inclpack pack, "#{base}/#{dir}" then
chdir( dir ) {
yield targ, topfile
}
else
$stderr.puts "setup.rb: skip #{base}/#{dir}(#{pack}) by user option"
end
end
end
def foreach_record( fname )
File.foreach( fname ) do |line|
line.strip!
next if line.empty?
a = line.split(/\s+/)
a[2] ||= '.'
yield a
end
end
def inclpack( pack, dname )
if @with.empty? then
not @without.include? pack and
not @without.include? dname
else
@with.include? pack or
@with.include? dname
end
end
#
# setup
#
def add_rubypath( fn, opt = nil )
line = "\#!#{@config['ruby-path']}#{opt ? ' ' + opt : ''}"
$stderr.puts %Q<setting #! line to "#{line}"> if @verbose
return if @no_harm
tmpf = nil
File.open( fn ) do |f|
first = f.gets
return unless /\A\#!.*ruby/ === first
tmpf = Tempfile.open( 'amsetup' )
tmpf.puts line
tmpf << first
f.each {|i| tmpf << i }
tmpf.close
end
mod = File.stat( fn ).mode
tmpf.open
File.open( fn, 'w' ) do |wf|
tmpf.each {|i| wf << i }
end
File.chmod mod, fn
tmpf.close true
end
#
# install
#
def install_bin
install_all isdir(@config['bin-dir']), 0555
end
def install_rb( dir )
install_all isdir(@config['rb-dir'] + '/' + dir), 0644
end
def install_dat( dir )
install_all isdir(@config['data-dir'] + '/' + dir), 0644
end
def install_all( dir, mode )
Dir.foreach('.') do |fname|
next if /\A\./ === fname
next unless File.file? fname
install fname, dir, mode
end
end
def create_topfile( name, req )
d = isdir(@config['rb-dir'])
File.open( "#{d}/#{name}.rb", 'w' ) do |f|
f.puts "require '#{name}/#{req}'"
end
File.chmod 0644, "#{d}/#{name}.rb"
end
def extconf
command "#{@config['ruby-prog']} extconf.rb"
end
def make
command @config['make-prog']
end
def clean
command @config['make-prog'] + ' clean' if File.file? 'Makefile'
end
def install_so( dir )
to = isdir(File.expand_path @config['so-dir'] + '/' + dir)
find_so('.').each do |fn|
install fn, to, 0555
end
end
DLEXT = ::Config::CONFIG['DLEXT']
def find_so( dir = '.' )
fnames = nil
Dir.open( dir ) {|d| fnames = d.to_a }
exp = /\.#{DLEXT}\z/
arr = fnames.find_all {|fn| exp === fn }
arr or raise InstallError,
'no ruby extention exists: have you done "ruby setup.rb setup" ?'
end
def so_dir?( dn = '.' )
File.file? "#{dn}/MANIFEST"
end
#
# file op.
#
def into_dir( libn )
return unless dir? libn
chdir( libn ) {
yield
}
end
def chdir( dn )
curr = Dir.pwd
begin
Dir.chdir dn
yield
ensure
Dir.chdir curr
end
end
def isdir( dn )
mkpath dn
dn
end
def mkpath( dname )
$stderr.puts "mkdir -p #{dname}" if @verbose
return if @no_harm
# does not check '/'... it's too abnormal case
dirs = dname.split(%r_(?=/)_)
if /\A[a-z]:\z/i === dirs[0] then
disk = dirs.shift
dirs[0] = disk + dirs[0]
end
dirs.each_index do |idx|
path = dirs[0..idx].join('')
Dir.mkdir path unless dir? path
end
end
def rmf( fname )
$stderr.puts "rm -f #{fname}" if @verbose
return if @no_harm
if File.exist? fname or File.symlink? fname then
File.chmod 777, fname
File.unlink fname
end
end
def rmrf( dn )
$stderr.puts "rm -rf #{dn}" if @verbose
return if @no_harm
Dir.chdir dn
Dir.foreach('.') do |fn|
next if fn == '.'
next if fn == '..'
if dir? fn then
verbose_off {
rmrf fn
}
else
verbose_off {
rmf fn
}
end
end
Dir.chdir '..'
Dir.rmdir dn
end
def verbose_off
save, @verbose = @verbose, false
yield
@verbose = save
end
def install( from, to, mode )
$stderr.puts "install #{from} #{to}" if @verbose
return if @no_harm
if dir? to then
to = to + '/' + File.basename(from)
end
str = nil
File.open( from, 'rb' ) {|f| str = f.read }
if diff? str, to then
verbose_off {
rmf to if File.exist? to
}
File.open( to, 'wb' ) {|f| f.write str }
File.chmod mode, to
end
end
def diff?( orig, comp )
return true unless File.exist? comp
s2 = nil
File.open( comp, 'rb' ) {|f| s2 = f.read }
orig != s2
end
def command( str )
$stderr.puts str if @verbose
system str or raise RuntimeError, "'system #{str}' failed"
end
def dir?( dname )
# for CORRUPTED windows stat()
File.directory? (dname[-1,1] == '/' ? dname : dname + '/')
end
end
if $0 == __FILE__ then
begin
MainInstaller = Installer.new( ARGV )
MainInstaller.execute
rescue
raise if $DEBUG
$stderr.puts $!
$stderr.puts 'try "ruby setup.rb --help" for usage'
exit 1
end
end
|
|
From: Michael N. <mne...@us...> - 2002-09-05 09:56:03
|
Update of /cvsroot/ruby-dbi/subprojects/ruby-db2/lib/db2 In directory usw-pr-cvs1:/tmp/cvs-serv2686/db2 Log Message: Directory /cvsroot/ruby-dbi/subprojects/ruby-db2/lib/db2 added to the repository |