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...> - 2003-05-11 15:27:11
|
Update of /cvsroot/ruby-dbi/src/lib/dbi
In directory sc8-pr-cvs1:/tmp/cvs-serv7455
Modified Files:
dbi.rb
Log Message:
class Timestamp:
- fraction nil by default
- fractions may be of type float (as well as integer)
- #to_s do not show fraction if it's nil
Index: dbi.rb
===================================================================
RCS file: /cvsroot/ruby-dbi/src/lib/dbi/dbi.rb,v
retrieving revision 1.38
retrieving revision 1.39
diff -u -r1.38 -r1.39
--- dbi.rb 9 May 2003 19:54:29 -0000 1.38
+++ dbi.rb 11 May 2003 15:27:09 -0000 1.39
@@ -298,15 +298,16 @@
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)
+
+ def initialize(year=0, month=0, day=0, hour=0, minute=0, second=0, fraction=nil)
case year
when ::Time
@year, @month, @day = year.year, year.month, year.day
- @hour, @minute, @second, @fraction = year.hour, year.min, year.sec, 0
+ @hour, @minute, @second, @fraction = year.hour, year.min, year.sec, nil
@original_time = year
when ::Date
@year, @month, @day = year.year, year.month, year.day
- @hour, @minute, @second, @fraction = 0, 0, 0, 0
+ @hour, @minute, @second, @fraction = 0, 0, 0, nil
@original_date = year
else
@year, @month, @day = year, month, day
@@ -314,6 +315,8 @@
end
end
+ def fraction() @fraction || 0 end
+
def mon() @month end
def mon=(val) @month=val end
def mday() @day end
@@ -324,7 +327,12 @@
def sec=(val) @second=val end
def to_s
- sprintf("%04d-%02d-%02d %02d:%02d:%02d.%06d", @year, @month, @day, @hour, @minute, @second, @fraction)
+ s = sprintf("%04d-%02d-%02d %02d:%02d:%02d", @year, @month, @day, @hour, @minute, @second)
+ if @fraction.nil?
+ s
+ else
+ s + '.' + @fraction.to_s.split('.').last
+ end
end
def to_time
|
|
From: Michael N. <mne...@us...> - 2003-05-09 19:54:32
|
Update of /cvsroot/ruby-dbi/src/lib/dbi
In directory sc8-pr-cvs1:/tmp/cvs-serv6282
Modified Files:
dbi.rb
Log Message:
zero-pad date/time/timestamps (classes Date/Time/Timestamp method to_s)
Index: dbi.rb
===================================================================
RCS file: /cvsroot/ruby-dbi/src/lib/dbi/dbi.rb,v
retrieving revision 1.37
retrieving revision 1.38
diff -u -r1.37 -r1.38
--- dbi.rb 27 Apr 2003 17:42:56 -0000 1.37
+++ dbi.rb 9 May 2003 19:54:29 -0000 1.38
@@ -1,7 +1,7 @@
#
# Ruby/DBI
#
-# Copyright (c) 2001, 2002 Michael Neumann <ne...@s-...>
+# Copyright (c) 2001, 2002, 2003 Michael Neumann <mne...@nt...>
#
# All rights reserved.
#
@@ -257,7 +257,7 @@
end
def to_s
- "#{@year}-#{@month}-#{@day}"
+ sprintf("%04d-%02d-%02d", @year, @month, @day)
end
end
@@ -290,7 +290,7 @@
end
def to_s
- "#{@hour}:#{@minute}:#{@second}"
+ sprintf("%02d:%02d:%02d", @hour, @minute, @second)
end
end
@@ -324,7 +324,7 @@
def sec=(val) @second=val end
def to_s
- "#{@year}-#{@month}-#{@day} #{@hour}:#{@minute}:#{@second}.#{@fraction}"
+ sprintf("%04d-%02d-%02d %02d:%02d:%02d.%06d", @year, @month, @day, @hour, @minute, @second, @fraction)
end
def to_time
|
|
From: Michael N. <mne...@us...> - 2003-04-27 19:18:17
|
Update of /cvsroot/ruby-dbi/src/build In directory sc8-pr-cvs1:/tmp/cvs-serv5986 Modified Files: package.sh Log Message: fixed RAA entry update address Index: package.sh =================================================================== RCS file: /cvsroot/ruby-dbi/src/build/package.sh,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- package.sh 28 Oct 2002 11:18:50 -0000 1.5 +++ package.sh 27 Apr 2003 19:18:13 -0000 1.6 @@ -66,7 +66,7 @@ links http://www.sourceforge.net/account/login.php dialog --msgbox "Finally, update the page at the RAA." 8 40 -w3m "http://www.ruby-lang.org/en/raa-update.rhtml?name=Ruby%2FDBI" +w3m "http://raa.ruby-lang.org/update.rhtml?name=ruby-dbi" # remove work cd .. |
|
From: Paul D. <pa...@sn...> - 2003-04-27 19:05:43
|
At 20:49 +0200 4/27/03, Michael Neumann wrote: >Paul DuBois wrote: >> At 10:37 -0700 4/27/03, Michael Neumann wrote: >> >Update of /cvsroot/ruby-dbi/src/lib/dbi >> >In directory sc8-pr-cvs1:/tmp/cvs-serv23497 >> > >> >Modified Files: >> > sql.rb >> >Log Message: >> >Fixed bug in DBI::SQL::BasicQuote::Coerce#as_time >> >Mysql time columns (like "13:32:33") could not be converted into >> >DBI::Time objects >> >(thanks to Tim Bates) >> >> Speaking of coercion... >> >> I've noticed that MySQL DATETIME and TIMESTAMP values get converted >> into formats that don't really reflect how MySQL itself displays >> them. For example, a DATETIME value such as '2001-01-01 00:00:00' >> gets coerced to '2001-1-1 0:0:0.0'. Leading zeros are lost, and >> a fraction-of-seconds part is added at the end. >> >> Should this be considered a bug, or just something that MySQL >> users should be aware of, and wary of? > >The string we get from a Mysql database is parsed and converted into >a DBI::Time object. When calling the to_s method of DBI::Time it >is converted back into a string. > >Does Mysql handle '2001-1-1 0:0:0.0' correctly as a DATETIME value? Yes, though this is because it ignores the fractional part (the .0) at the end, which is not part of DATETIME or TIMESTAMP. >And "0:0:0" for TIME values? Yes. >If not, than it's a bug, otherwise not. On the other hand, your questions relate to putting data *into* MySQL. Applications that expect DATETIME values to come *out* of Ruby DBI programs the way that MySQL itself formats them may break. (That is, if a program assumes a string value in CCYY-MM-DD hh:mm:ss format, it cannot break out parts of the value by looking for fixed-length-and-position substrings.) That's why I asked if this behavior is something MySQL users should be wary of. > >When can of course modify the to_s method to output YYYY-MM-DD HH:MM:SS.F, >that's no problem, except perhaps decreased performance (should be ok). There would be no ".F" part for MySQL. > >Regards, > > Michael |
|
From: Michael N. <mne...@us...> - 2003-04-27 18:57:20
|
Update of /cvsroot/ruby-dbi/src/build In directory sc8-pr-cvs1:/tmp/cvs-serv27901 Modified Files: DBI-VERSIONS USER Log Message: new version Index: DBI-VERSIONS =================================================================== RCS file: /cvsroot/ruby-dbi/src/build/DBI-VERSIONS,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- DBI-VERSIONS 22 Oct 2002 15:28:15 -0000 1.3 +++ DBI-VERSIONS 27 Apr 2003 18:51:55 -0000 1.4 @@ -1,4 +1,5 @@ # All times are in UCT +dbi-0-0-19 2003-04-27 23:00 UTC dbi-0-0-18 2002-10-22 23:00 UTC dbi-0-0-17 2002-10-03 10:00 UTC dbi-0-0-16 2002-07-03 20:10 UTC Index: USER =================================================================== RCS file: /cvsroot/ruby-dbi/src/build/USER,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- USER 2 Oct 2002 18:04:09 -0000 1.1 +++ USER 27 Apr 2003 18:51:55 -0000 1.2 @@ -1,3 +1,4 @@ mneumann:'Michael Neumann <mne...@fa...>' michael:'Michael Neumann <mne...@fa...>' rainer:'Rainer Perl' +pdubois:'Paul Dubois' |
|
From: Michael N. <mne...@us...> - 2003-04-27 18:57:12
|
Update of /cvsroot/ruby-dbi/src/lib/dbi In directory sc8-pr-cvs1:/tmp/cvs-serv28982 Modified Files: version.rb Log Message: new version Index: version.rb =================================================================== RCS file: /cvsroot/ruby-dbi/src/lib/dbi/version.rb,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- version.rb 22 Oct 2002 15:27:01 -0000 1.4 +++ version.rb 27 Apr 2003 18:54:18 -0000 1.5 @@ -4,6 +4,6 @@ module DBI -VERSION = "0.0.18" +VERSION = "0.0.19" end |
|
From: Paul D. <pa...@sn...> - 2003-04-27 18:04:20
|
At 10:37 -0700 4/27/03, Michael Neumann wrote: >Update of /cvsroot/ruby-dbi/src/lib/dbi >In directory sc8-pr-cvs1:/tmp/cvs-serv23497 > >Modified Files: > sql.rb >Log Message: >Fixed bug in DBI::SQL::BasicQuote::Coerce#as_time >Mysql time columns (like "13:32:33") could not be converted into >DBI::Time objects >(thanks to Tim Bates) Speaking of coercion... I've noticed that MySQL DATETIME and TIMESTAMP values get converted into formats that don't really reflect how MySQL itself displays them. For example, a DATETIME value such as '2001-01-01 00:00:00' gets coerced to '2001-1-1 0:0:0.0'. Leading zeros are lost, and a fraction-of-seconds part is added at the end. Should this be considered a bug, or just something that MySQL users should be aware of, and wary of? > > >Index: sql.rb >=================================================================== >RCS file: /cvsroot/ruby-dbi/src/lib/dbi/sql.rb,v >retrieving revision 1.13 >retrieving revision 1.14 >diff -u -r1.13 -r1.14 >--- sql.rb 1 Feb 2003 13:45:23 -0000 1.13 >+++ sql.rb 27 Apr 2003 17:37:02 -0000 1.14 >@@ -47,9 +47,9 @@ > end > > def as_time(str) >- return nil if str.nil? >- t = as_timestamp(str) >- DBI::Time.new(t.hour, t.min, t.sec) >+ return nil if str.nil? or str.empty? >+ t = ParseDate.parsedate(str) >+ DBI::Time.new(*t[3,3]) > end > |
|
From: Michael N. <mne...@us...> - 2003-04-27 17:43:00
|
Update of /cvsroot/ruby-dbi/src/lib/dbi
In directory sc8-pr-cvs1:/tmp/cvs-serv29384
Modified Files:
dbi.rb
Log Message:
bug fix in class DBI::Time (wrong named variable)
Index: dbi.rb
===================================================================
RCS file: /cvsroot/ruby-dbi/src/lib/dbi/dbi.rb,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -r1.36 -r1.37
--- dbi.rb 8 Feb 2003 02:26:15 -0000 1.36
+++ dbi.rb 27 Apr 2003 17:42:56 -0000 1.37
@@ -285,7 +285,7 @@
@original_time
else
t = ::Time.now
- ::Time.local(t.year, t.month, t.day, @hour, @min, @sec)
+ ::Time.local(t.year, t.month, t.day, @hour, @minute, @second)
end
end
|
|
From: Michael N. <mne...@us...> - 2003-04-27 17:40:40
|
Update of /cvsroot/ruby-dbi/src/doc In directory sc8-pr-cvs1:/tmp/cvs-serv27176 Modified Files: index.rd Log Message: new contributor Index: index.rd =================================================================== RCS file: /cvsroot/ruby-dbi/src/doc/index.rd,v retrieving revision 1.28 retrieving revision 1.29 diff -u -r1.28 -r1.29 --- index.rd 26 Apr 2003 14:53:01 -0000 1.28 +++ index.rd 27 Apr 2003 17:40:36 -0000 1.29 @@ -75,6 +75,9 @@ : Paul DuBois Fixed typos and formatting. Maintains DBD Mysql. +: Tim Bates + Bug fixes for Mysql and DBI + == Database Drivers (DBDs) |
|
From: Michael N. <mne...@us...> - 2003-04-27 17:37:07
|
Update of /cvsroot/ruby-dbi/src/lib/dbi
In directory sc8-pr-cvs1:/tmp/cvs-serv23497
Modified Files:
sql.rb
Log Message:
Fixed bug in DBI::SQL::BasicQuote::Coerce#as_time
Mysql time columns (like "13:32:33") could not be converted into DBI::Time objects
(thanks to Tim Bates)
Index: sql.rb
===================================================================
RCS file: /cvsroot/ruby-dbi/src/lib/dbi/sql.rb,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- sql.rb 1 Feb 2003 13:45:23 -0000 1.13
+++ sql.rb 27 Apr 2003 17:37:02 -0000 1.14
@@ -47,9 +47,9 @@
end
def as_time(str)
- return nil if str.nil?
- t = as_timestamp(str)
- DBI::Time.new(t.hour, t.min, t.sec)
+ return nil if str.nil? or str.empty?
+ t = ParseDate.parsedate(str)
+ DBI::Time.new(*t[3,3])
end
|
|
From: Michael N. <mne...@us...> - 2003-04-26 14:53:05
|
Update of /cvsroot/ruby-dbi/src/doc In directory sc8-pr-cvs1:/tmp/cvs-serv960 Modified Files: index.rd Log Message: Index: index.rd =================================================================== RCS file: /cvsroot/ruby-dbi/src/doc/index.rd,v retrieving revision 1.27 retrieving revision 1.28 diff -u -r1.27 -r1.28 --- index.rd 22 Jan 2003 10:55:02 -0000 1.27 +++ index.rd 26 Apr 2003 14:53:01 -0000 1.28 @@ -74,6 +74,7 @@ quote/escape_bytea patch for DBD Pg. : Paul DuBois Fixed typos and formatting. + Maintains DBD Mysql. == Database Drivers (DBDs) |
|
From: Elias K. <el...@us...> - 2003-04-21 18:09:16
|
Update of /cvsroot/ruby-dbi/src/lib/dbd_db2
In directory sc8-pr-cvs1:/tmp/cvs-serv19370
Modified Files:
Tag: DB2BLOBS
DB2.rb
Log Message:
DB2 driver support for columns(table)
Index: DB2.rb
===================================================================
RCS file: /cvsroot/ruby-dbi/src/lib/dbd_db2/DB2.rb,v
retrieving revision 1.6.4.1
retrieving revision 1.6.4.2
diff -u -r1.6.4.1 -r1.6.4.2
--- DB2.rb 28 Dec 2002 14:36:30 -0000 1.6.4.1
+++ DB2.rb 21 Apr 2003 18:09:08 -0000 1.6.4.2
@@ -149,6 +149,39 @@
}
end
+ def columns(table)
+ tabschema, tabname = nil, nil
+ if md = /([^\.]*)\.(.*)/.match(table)
+ tabschema, tabname = md[1], md[2]
+ else
+ raise 'table name should be in SCHEMA.TABLE notation'
+ end
+ query = %{
+ SELECT colname, typename, length, scale, default, nulls
+ FROM syscat.columns
+ WHERE tabschema = '#{tabschema}' AND tabname = '#{tabname}'
+ }
+ if (arr = execute(query).fetch_all)
+ return arr.collect { |row|
+ #sql_type, type_name = DB2_to_DBI_type_mapping[row[1]] # FIXME: map column names to constants
+ ColumnInfo.new({
+ 'name' => row[0],
+ #'type_name' => type_name,
+ #'sql_type' => sql_type,
+ 'type_name' => row[1],
+ 'sql_type' => row[1],
+ 'precision' => row[2],
+ 'scale' => row[3],
+ 'default' => row[4],
+ 'nullable' => (row[5] == 'Y')
+ #'indexed'
+ #'primary'
+ #'unique'
+ })
+ }
+ end
+ end
+
def ping
begin
stmt = execute("SELECT 1 FROM SYSCAT.TABLES")
@@ -179,8 +212,6 @@
def [](attribute)
@attr[attribute]
end
-
- # TODO: method columns(table)
def commit
rc = SQLEndTran(SQL_HANDLE_DBC, @handle, SQL_COMMIT)
|
|
From: Paul D. <pd...@us...> - 2003-04-02 15:42:59
|
Update of /cvsroot/ruby-dbi/src/lib/dbd_mysql
In directory sc8-pr-cvs1:/tmp/cvs-serv13102/lib/dbd_mysql
Modified Files:
Mysql.rb
Log Message:
Modify transaction support to use self.do rather than @handler.query
so that query execution is routed through the mutex.
Index: Mysql.rb
===================================================================
RCS file: /cvsroot/ruby-dbi/src/lib/dbd_mysql/Mysql.rb,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -r1.20 -r1.21
--- Mysql.rb 8 Feb 2003 02:03:16 -0000 1.20
+++ Mysql.rb 2 Apr 2003 15:42:52 -0000 1.21
@@ -272,7 +272,7 @@
def commit
if @have_transactions
- @handle.query("COMMIT")
+ self.do("COMMIT")
else
raise NotSupportedError
end
@@ -282,7 +282,7 @@
def rollback
if @have_transactions
- @handle.query("ROLLBACK")
+ self.do("ROLLBACK")
else
raise NotSupportedError
end
@@ -306,7 +306,7 @@
case attr
when 'AutoCommit'
if @have_transactions
- @handle.query("SET AUTOCOMMIT=" + (value ? "1" : "0"))
+ self.do("SET AUTOCOMMIT=" + (value ? "1" : "0"))
else
raise NotSupportedError
end
|
|
From: Paul D. <pd...@us...> - 2003-02-08 02:26:19
|
Update of /cvsroot/ruby-dbi/src/lib/dbi
In directory sc8-pr-cvs1:/tmp/cvs-serv23097
Modified Files:
dbi.rb
Log Message:
Fix bug in case insensitive driver name lookup on case insensitive filesystems
Index: dbi.rb
===================================================================
RCS file: /cvsroot/ruby-dbi/src/lib/dbi/dbi.rb,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -r1.35 -r1.36
--- dbi.rb 22 Oct 2002 15:06:04 -0000 1.35
+++ dbi.rb 8 Feb 2003 02:26:15 -0000 1.36
@@ -460,8 +460,25 @@
end
found ||= driver_name
+
+ # On a filesystem that is not case-sensitive (e.g., HFS+ on Mac OS X),
+ # the initial require attempt that loads the driver may succeed even
+ # though the lettercase of driver_name doesn't match the actual
+ # filename. If that happens, const_get will fail and it become
+ # necessary to look though the list of constants and look for a
+ # caseless match. The result of this match provides the constant
+ # with the proper lettercase -- which can be used to generate the
+ # driver handle.
- dr = DBI::DBD.const_get(found.intern)
+ dr = nil
+ begin
+ dr = DBI::DBD.const_get(found.intern)
+ rescue NameError
+ # caseless look for constants to find actual constant
+ found = found.downcase
+ found = DBI::DBD.constants.find { |e| e.downcase == found }
+ dr = DBI::DBD.const_get(found.intern) unless found.nil?
+ end
dbd_dr = dr::Driver.new
drh = DBI::DriverHandle.new(dbd_dr)
drh.trace(@@trace_mode, @@trace_output)
|
|
From: Paul D. <pd...@us...> - 2003-02-08 02:03:20
|
Update of /cvsroot/ruby-dbi/src/lib/dbd_mysql
In directory sc8-pr-cvs1:/tmp/cvs-serv15214
Modified Files:
Mysql.rb
Log Message:
Add transaction support: commit and rollback methods, AutoCommit database handle attribute
Index: Mysql.rb
===================================================================
RCS file: /cvsroot/ruby-dbi/src/lib/dbd_mysql/Mysql.rb,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -r1.19 -r1.20
--- Mysql.rb 8 Feb 2003 01:46:02 -0000 1.19
+++ Mysql.rb 8 Feb 2003 02:03:16 -0000 1.20
@@ -181,10 +181,21 @@
def initialize(handle, attr)
super
+ # check server version to determine transaction capability
+ ver_str = @handle.get_server_info
+ major, minor, teeny = ver_str.split(".")
+ teeny.sub!(/\D*$/, "") # strip any non-numeric suffix if present
+ server_version = major.to_i*10000 + minor.to_i*100 + teeny.to_i
+ # It's not until 3.23.17 that SET AUTOCOMMIT,
+ # BEGIN, COMMIT, and ROLLBACK all are available
+ @have_transactions = (server_version >= 32317)
+ # assume the connection begins in AutoCommit mode
+ @attr['AutoCommit'] = true
@mutex = Mutex.new
end
def disconnect
+ self.rollback unless @attr['AutoCommit']
@handle.close
rescue MyError => err
raise DBI::DatabaseError.new(err.message, err.errno)
@@ -259,12 +270,24 @@
Statement.new(self, @handle, statement, @mutex)
end
- # TODO: Raise Error
def commit
+ if @have_transactions
+ @handle.query("COMMIT")
+ else
+ raise NotSupportedError
+ end
+ rescue MyError => err
+ raise DBI::DatabaseError.new(err.message, err.errno)
end
- # TODO: Raise Error
def rollback
+ if @have_transactions
+ @handle.query("ROLLBACK")
+ else
+ raise NotSupportedError
+ end
+ rescue MyError => err
+ raise DBI::DatabaseError.new(err.message, err.errno)
end
@@ -277,6 +300,20 @@
else
super
end
+ end
+
+ def []=(attr, value)
+ case attr
+ when 'AutoCommit'
+ if @have_transactions
+ @handle.query("SET AUTOCOMMIT=" + (value ? "1" : "0"))
+ else
+ raise NotSupportedError
+ end
+ else
+ raise NotSupportedError
+ end
+ @attr[attr] = value
end
private # -------------------------------------------------
|
|
From: Paul D. <pd...@us...> - 2003-02-08 01:46:05
|
Update of /cvsroot/ruby-dbi/src/lib/dbd_mysql
In directory sc8-pr-cvs1:/tmp/cvs-serv10610
Modified Files:
Mysql.rb
Log Message:
return MySQL error number on exceptions, not just error message
Index: Mysql.rb
===================================================================
RCS file: /cvsroot/ruby-dbi/src/lib/dbd_mysql/Mysql.rb,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- Mysql.rb 8 Feb 2003 01:37:51 -0000 1.18
+++ Mysql.rb 8 Feb 2003 01:46:02 -0000 1.19
@@ -67,7 +67,7 @@
return Database.new(handle, attr)
rescue MyError => err
- raise DBI::DatabaseError.new(err.message)
+ raise DBI::DatabaseError.new(err.message, err.errno)
end
def data_sources
@@ -76,7 +76,7 @@
handle.close
return res
rescue MyError => err
- raise DBI::DatabaseError.new(err.message)
+ raise DBI::DatabaseError.new(err.message, err.errno)
end
# Driver-specific functions ------------------------------------------------
@@ -187,7 +187,7 @@
def disconnect
@handle.close
rescue MyError => err
- raise DBI::DatabaseError.new(err.message)
+ raise DBI::DatabaseError.new(err.message, err.errno)
end
def ping
@@ -202,7 +202,7 @@
def tables
@handle.list_tables
rescue MyError => err
- raise DBI::DatabaseError.new(err.message)
+ raise DBI::DatabaseError.new(err.message, err.errno)
end
# Eli Green (fixed up by Michael Neumann)
@@ -251,7 +251,7 @@
@handle.affected_rows # return value
}
rescue MyError => err
- raise DBI::DatabaseError.new(err.message)
+ raise DBI::DatabaseError.new(err.message, err.errno)
end
@@ -363,13 +363,13 @@
@rows = @handle.affected_rows
}
rescue MyError => err
- raise DBI::DatabaseError.new(err.message)
+ raise DBI::DatabaseError.new(err.message, err.errno)
end
def finish
@res_handle.free if @res_handle
rescue MyError => err
- raise DBI::DatabaseError.new(err.message)
+ raise DBI::DatabaseError.new(err.message, err.errno)
end
def fill_array(rowdata)
@@ -387,7 +387,7 @@
@current_row += 1
fill_array(@res_handle.fetch_row)
rescue MyError => err
- raise DBI::DatabaseError.new(err.message)
+ raise DBI::DatabaseError.new(err.message, err.errno)
end
def fetch_scroll(direction, offset)
@@ -431,7 +431,7 @@
}
retval
rescue MyError => err
- raise DBI::DatabaseError.new(err.message)
+ raise DBI::DatabaseError.new(err.message, err.errno)
end
def rows
|
|
From: Paul D. <pd...@us...> - 2003-02-08 01:37:55
|
Update of /cvsroot/ruby-dbi/src/lib/dbd_mysql
In directory sc8-pr-cvs1:/tmp/cvs-serv8541
Modified Files:
Mysql.rb
Log Message:
port and flag connection parameters must be passed as numbers
Index: Mysql.rb
===================================================================
RCS file: /cvsroot/ruby-dbi/src/lib/dbd_mysql/Mysql.rb,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -r1.17 -r1.18
--- Mysql.rb 8 Feb 2003 00:37:20 -0000 1.17
+++ Mysql.rb 8 Feb 2003 01:37:51 -0000 1.18
@@ -58,6 +58,10 @@
hash['host'] ||= 'localhost'
+ # these two connection parameters should be passed as numbers
+ hash['port'] = hash['port'].to_i unless hash['port'].nil?
+ hash['flag'] = hash['flag'].to_i unless hash['flag'].nil?
+
handle = ::Mysql.connect(hash['host'], user, auth, hash['database'], hash['port'], hash['socket'], hash['flag'])
#handle.select_db(hash['database'])
|
|
From: Paul D. <pd...@us...> - 2003-02-08 00:37:24
|
Update of /cvsroot/ruby-dbi/src/lib/dbd_mysql
In directory sc8-pr-cvs1:/tmp/cvs-serv21377
Modified Files:
Mysql.rb
Log Message:
Do not force user to provide database name when connecting
Index: Mysql.rb
===================================================================
RCS file: /cvsroot/ruby-dbi/src/lib/dbd_mysql/Mysql.rb,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- Mysql.rb 26 Sep 2002 18:37:27 -0000 1.16
+++ Mysql.rb 8 Feb 2003 00:37:20 -0000 1.17
@@ -52,9 +52,9 @@
# connect to database
hash = Utils.parse_params(dbname)
- if hash['database'].nil?
- raise DBI::InterfaceError, "must specify database"
- end
+ #if hash['database'].nil?
+ # raise DBI::InterfaceError, "must specify database"
+ #end
hash['host'] ||= 'localhost'
|
|
From: Michael N. <mne...@us...> - 2003-02-01 13:51:27
|
Update of /cvsroot/ruby-dbi/src/lib/dbi/test
In directory sc8-pr-cvs1:/tmp/cvs-serv21141
Modified Files:
testsqlbind.rb
Log Message:
added comment test
Index: testsqlbind.rb
===================================================================
RCS file: /cvsroot/ruby-dbi/src/lib/dbi/test/testsqlbind.rb,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- testsqlbind.rb 22 Nov 2001 14:25:38 -0000 1.5
+++ testsqlbind.rb 1 Feb 2003 13:51:24 -0000 1.6
@@ -56,6 +56,12 @@
bind(self, "WHERE c='connected?' AND d=?", [10])
end
+ def test_comment_dan
+ sql = %{--Dan's query\n--random comment\nselect column1, column2\nfrom table1\nwhere somevalue = ?}
+ res = %{--Dan's query\n--random comment\nselect column1, column2\nfrom table1\nwhere somevalue = 10}
+ assert_equal res, bind(self, sql, [10])
+ end
+
end
$last_suite.add_test (TestSqlBind.suite)
|
|
From: Michael N. <mne...@us...> - 2003-02-01 13:45:27
|
Update of /cvsroot/ruby-dbi/src/lib/dbi
In directory sc8-pr-cvs1:/tmp/cvs-serv16506
Modified Files:
sql.rb
Log Message:
method BasicBind#tokens: added support for C-style (non-nesting) and Ada/SQL92-style comments
Index: sql.rb
===================================================================
RCS file: /cvsroot/ruby-dbi/src/lib/dbi/sql.rb,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- sql.rb 6 Feb 2002 14:24:21 -0000 1.12
+++ sql.rb 1 Feb 2003 13:45:23 -0000 1.13
@@ -140,12 +140,27 @@
# This is NOT a full lexer for SQL. It just breaks up the SQL
# string enough so that question marks, double question marks and
# quoted strings are separated. This is used when binding
- # arguments to "?" in the SQL string. Note: comments are not
- # handled.
+ # arguments to "?" in the SQL string.
+ #
+ # C-style (/* */) and Ada-style (--) comments are handled.
+ # Note: Nested C-style comments are NOT handled!
#
def tokens(sql)
- toks = sql.scan(/('([^'\\]|''|\\.)*'|"([^"\\]|""|\\.)*"|\?\??|[^'"?]+)/)
- toks.collect {|t| t[0]}
+ sql.scan(%r{
+ (
+ -- .* (?# matches "--" style comments to the end of line or string )
+ |
+ /[*] .*? [*]/ (?# matches C-style comments )
+ |
+ ' ( [^'\\] | '' | \\. )* ' (?# match strings surrounded by apostophes )
+ |
+ " ( [^"\\] | "" | \\. )* " (?# match strings surrounded by " )
+ |
+ \?\?? (?# match one or two question marks )
+ |
+ [^-/'"?]+ (?# match all characters except ' " ? - and / )
+
+ )}x).collect {|t| t.first}
end
end # module BasicBind
|
|
From: Michael N. <mne...@us...> - 2003-01-22 10:55:05
|
Update of /cvsroot/ruby-dbi/src/doc In directory sc8-pr-cvs1:/tmp/cvs-serv30558 Modified Files: index.rd Log Message: added contributor, added Articles section Index: index.rd =================================================================== RCS file: /cvsroot/ruby-dbi/src/doc/index.rd,v retrieving revision 1.26 retrieving revision 1.27 diff -u -r1.26 -r1.27 --- index.rd 22 Oct 2002 15:25:38 -0000 1.26 +++ index.rd 22 Jan 2003 10:55:02 -0000 1.27 @@ -72,6 +72,8 @@ Submitted several patches and helped with lots of comments; Co-owner of the project. : MoonWolf quote/escape_bytea patch for DBD Pg. +: Paul DuBois + Fixed typos and formatting. == Database Drivers (DBDs) @@ -182,6 +184,9 @@ The DBD specification (how to write a database driver) is lib/dbi/doc/DBD_SPEC or lib/dbi/doc/html/DBD_SPEC.html or available from WWW at ((<URL:http://ruby-dbi.sourceforge.net/DBD_SPEC.html>)). +== Articles + +* ((<Using the Ruby DBI Module|URL:http://www.kitebird.com/articles/ruby-dbi.html>)) by Paul DuBois. == Applications |
|
From: Michael N. <mne...@us...> - 2003-01-22 10:52:06
|
Update of /cvsroot/ruby-dbi/src/doc In directory sc8-pr-cvs1:/tmp/cvs-serv26656 Modified Files: DBD_SPEC DBI_SPEC Log Message: fixed wrong email address Index: DBD_SPEC =================================================================== RCS file: /cvsroot/ruby-dbi/src/doc/DBD_SPEC,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- DBD_SPEC 22 Jan 2003 10:45:31 -0000 1.2 +++ DBD_SPEC 22 Jan 2003 10:52:03 -0000 1.3 @@ -1,6 +1,6 @@ =begin = DBD Specification Version 0.2.2 (Draft) -by Michael Neumann (ne...@s-...) +by Michael Neumann (mne...@fa...) $Id$ Index: DBI_SPEC =================================================================== RCS file: /cvsroot/ruby-dbi/src/doc/DBI_SPEC,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- DBI_SPEC 22 Jan 2003 10:45:32 -0000 1.2 +++ DBI_SPEC 22 Jan 2003 10:52:03 -0000 1.3 @@ -1,6 +1,6 @@ =begin = DBI Interface Specification Version 0.2.2 (Draft) -by Michael Neumann (ne...@s-...) +by Michael Neumann (mne...@fa...) $Id$ |
|
From: Michael N. <mne...@us...> - 2003-01-22 10:45:35
|
Update of /cvsroot/ruby-dbi/src/doc
In directory sc8-pr-cvs1:/tmp/cvs-serv23382
Modified Files:
DBD_SPEC DBI_SPEC
Log Message:
Fix typos and formatting (by Paul DuBois).
Index: DBD_SPEC
===================================================================
RCS file: /cvsroot/ruby-dbi/src/doc/DBD_SPEC,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- DBD_SPEC 2 Oct 2002 18:10:37 -0000 1.1
+++ DBD_SPEC 22 Jan 2003 10:45:31 -0000 1.2
@@ -19,9 +19,9 @@
.
.
-Where "Driver1" and "Driver2" are the names of DBD driver.
-For example if you have two drivers installed, "Oracle" and
-"Sybase" it would look like:
+Where "Driver1" and "Driver2" are DBD driver names.
+For example, if you have two drivers installed named "Oracle" and
+"Sybase", the layout would look like:
DBD/
DBD/Oracle
@@ -31,209 +31,213 @@
DBD/Sybase/Sybase.so # <== this is the main driver
# has no helper files
-When DBI loads a DBD driver it search all "DBD" directories in Ruby's
+When DBI loads a DBD driver, it searches all "DBD" directories in Ruby's
LOAD_PATH ($:).
-Database dependent functions, that should be callable with DBI::func, must
+Database dependent functions, that should be callable with (({DBI::func})), must
use the prefix "__" before their method names, to prevent nameclashes with
further versions of Ruby/DBI!
== Driver Name
-The DBD driver is simply named after the Database, e.g. Oracle, DB2 etc.
-The suffix will normally be ".rb" but can be any other valid suffix,
-which Ruby is possible to load, e.g. ".so", ".sl" or ".dll", and depends
+The DBD driver is simply named after the Database, e.g., Oracle, DB2, etc.
+The suffix normally will be ".rb" but can be any other valid suffix that is
+possible for Ruby to load, e.g., ".so", ".sl" or ".dll", and depends
for non-Ruby DBD driver on the underlying operating system.
When I refer to the driver name, then I speak of the filename without
-the suffix, e.g. Oracle or DB2.
+the suffix, e.g., Oracle or DB2.
-The name specified in the DSN ((-Data Source Name, e.g. "dbi:Oracle:oracle.neumann"-))
+The name specified in the DSN ((-Data Source Name, e.g., "dbi:Oracle:oracle.neumann"-))
must be the same as the driver name.
== Classes provided by a DBD
A DBD driver has to provide three classes in the namespace
-(({DBI::DBD::}))((*DriverName*)) where ((*DriverName*)) is the name of the
-driver, e.g. Oracle or DB2.
+(({DBI::DBD::}))((*DriverName*)), where ((*DriverName*)) is the name of the
+driver, e.g., Oracle or DB2.
The three classes must be named (({Driver})), (({Database})) and (({Statement})).
== Class Driver
This class must inherit from (({DBI::BaseDriver})).
-=== Methods which must be provided by (({Driver}))
+=== Methods that must be provided by (({Driver}))
--- connect( dbname, user, auth, attr )
- Connect to a database and return a newly created (({Database})) object.
+ Connects to a database and returns a newly created (({Database})) object.
-=== Optional methods which can be specified by (({Driver}))
+=== Optional methods that can be specified by (({Driver}))
--- default_user
- Return an array of the form (({['username', 'password']})) which represent
- the default user when no user and password was specified.
+ Returns an array of the form (({['username', 'password']})) which represents
+ the default user when no username and password were specified.
Defaults to (({['', '']})) if not implemented.
--- default_attributes
- Return a (({Hash})) containing the default attributes which are used
- in (({connect})) additional to the ones the user specify.
+ Returns a (({Hash})) containing the default attributes that are used
+ in ((<connect>)) in addition to the ones the user specifies.
Defaults to (({{}})) (empty hash) if not implemented.
--- data_sources
- Return an array of all valid DSN this driver can access.
+ Returns an array of all valid DSNs this driver can access.
Defaults to (({[]})) (empty array) if not implemented.
--- disconnect_all
- Disconnect all connections made with this driver.
+ Disconnects all connections made with this driver.
- Defaults to raise a NotImplementedError.
+ If this method is not implemented,
+ the default is to raise a NotImplementedError exception.
== Class Database
This class must inherit from (({DBI::BaseDatabase})).
-=== Methods which must be provided by (({Database}))
+=== Methods that must be provided by (({Database}))
--- disconnect
- Disconnect from database.
- But before you have to rollback all outstanding transactions, so
- all changes not yet commited get lost.
+ Disconnects from the database.
+ But you must first roll back all outstanding transactions, so
+ all changes not yet committed get lost (are discarded).
--- prepare( statement )
- Prepare the SQL ((*statement*)) and return an object of class (({Statement})).
+ Prepares the SQL ((|statement|)) and returns an object of class (({Statement})).
--- ping
- Ping the database, and check if the connection is alive.
+ Pings the database to check whether the connection is alive.
This can be implemented by executing a SQL statement like
- "SELECT 1 FROM DUAL" for Oracle database, or for other databases
- this should be query on a table which normally always exists.
+ "SELECT 1 FROM DUAL" for Oracle database.
+ For other databases,
+ this should be a query on a table that normally always exists.
- Return (({true})) if the connection is alive, otherwise (({false})).
+ Returns (({true})) if the connection is alive, otherwise (({false})).
-=== Optional methods which can be specified by (({Database}))
+=== Optional methods that can be specified by (({Database}))
--- commit
--- rollback
- Commit or roll back the current transaction.
+ Commits or rolls back the current transaction.
- Defauls to raise a NotSupportedError, so if the database do not implement
- transactions (mSQL, mySQL, CSV) do not overwrite this method.
+ The default is to raise a NotSupportedError exception, so if the database does not implement
+ transactions (mSQL, MySQL, CSV), do not overwrite this method.
--- tables
- Return an Array of all tables and views.
+ Returns an (({Array})) of all tables and views.
- Defaults to return the empty Array [].
+ The default is to return the empty (({Array})) ((({[]}))).
--- columns( table )
- Return more information about the columns of table ((*table*)).
- Return an Array of Hashes, like Statement#column_info do.
-
- Defaults to return an empty Array [].
+ Returns more information about the columns of the table ((|table|)).
+ Returns an (({Array})) of (({Hash})) objects, like (({Statement#column_info})) does.
+
+ The default is to return an empty (({Array})) ((({[]}))).
--- execute( statement, *bindvars )
- Immediate execution (without preparation) of SQL ((*statement*))
- with binding of placeholders to values given in ((*bindvars*)) before.
+ Immediate execution (without preparation) of SQL ((|statement|))
+ after binding the values in ((|bindvars|)) to the placeholders in the statement.
- Return a (({Statement})) object.
+ Returns a (({Statement})) object.
- Defaults to the call sequence of Database#prepare(), Statement#bind_params() and
- Statement#execute().
+ Defaults to the call sequence of (({Database#prepare()})), (({Statement#bind_params()})) and
+ (({Statement#execute()})).
--- do( statement, *bindvars )
- Execution of SQL ((*statement*)) with binding of placeholders to values given
- in ((*bindvars*)) before, but without returning a (({Statement})) object.
+ Execution of SQL ((|statement|)), after binding the values given
+ in ((|bindvars|)) to the placeholders in the statement, but without returning a (({Statement})) object.
So this is used for 'INSERT', 'UPDATE', 'DELETE' as well as for DCL, which
- do not return a result-set.
+ do not return a result set.
- Return the RPC (Row Processed Count) or (({nil})) if no RPC is available.
+ Returns the RPC (Row Processed Count) or (({nil})) if no RPC is available.
- Defaults to Database#execute() and Statement#rows() followed by Statement#finish().
+ Defaults to (({Database#execute()})) and (({Statement#rows()})) followed by (({Statement#finish()})).
--- quote( value )
- Quote the given value ((*value*)) database specific and return the result.
+ Quotes the given value ((|value|)) in database-specific fashion and returns the result.
- NOTE: This method is not really useful, because of Statement#bind_param.
+ NOTE: This method is not really useful, because of (({Statement#bind_param})).
--- []( attr )
- Return value of attribute ((*attr*)).
+ Returns the value of the attribute ((|attr|)).
- Defauls to return the value of (({@attr[attr]})).
+ The default is to return the value of (({@attr[attr]})).
--- []=( attr, value )
- Set value of attribute ((*attr*)) to ((*value*)).
- An attribute is e.g. "AutoCommit".
- Raise a NotSupportedError, if the database do not support an attribute.
+ Sets the value of the attribute ((|attr|)) to ((|value|)).
+ An attribute is, e.g., "AutoCommit".
+ Raises a NotSupportedError exception if the database does not support an attribute.
- The default implementation is to raise a NotSupportedError.
+ The default implementation is to raise a NotSupportedError exception.
== Class Statement
This class must inherit from (({DBI::BaseStatement})).
-=== Methods which must be provided by (({Statement}))
+=== Methods that must be provided by (({Statement}))
--- bind_param( param, value, attribs )
- Bind ((|param|)) which is either a (({String})) which is then the name of the
- placeholder used in the SQL statement (e.g. Oracle: "SELECT * FROM EMP WHERE ENAME = :ename")
- or it is a (({Fixnum})) which is then the number of the placeholder where counting starts at 1.
+ Binds the value ((|value|)) to a placeholder.
+ The placeholder is represented by ((|param|)), which is either a
+ (({String})) representing the name of the
+ placeholder used in the SQL statement (e.g., Oracle: "SELECT * FROM EMP WHERE ENAME = :ename")
+ or a (({Fixnum})) that indicates the number of the placeholder.
+ Placeholder numbers begin at 1.
- ((|value|)) is the value which is bound to the placeholder.
If ((|value|)) is a (({String})), then the default SQL type is (({VARCHAR})) or (({CHAR})).
If ((|value|)) is a (({Fixnum})) or (({Bignum})), the default SQL type is (({INT})).
If ((|value|)) is a (({Float})), the default SQL type is (({FLOAT})).
- ((*attribs*)) is not yet used in this version but could be a hash containing more information
- like parameter type etc.
+ ((|attribs|)) is not yet used in this version but could be a hash containing more information
+ like parameter type, etc.
--- execute
Execute the statement.
--- finish
Free all the resources for the statement.
- After calling (({finish})) no other operation on this
+ After calling ((<finish>)), no other operation on this
statement is valid.
--- fetch
- Fetch the current row.
- Return a (({Array})) containing all column-data or (({nil})) if
+ Fetches the current row.
+ Returns an (({Array})) containing all column data or (({nil})) if
the last column has been read.
- Note: This method should return not a newly created object on each call,
- instead you should return one and the same Array object but with
+ Note: This method should not return a newly created object on each call;
+ instead, you should return one and the same (({Array})) object but with
changed data.
--- column_info
- Return an (({Array})) of (({Hash}))'s, one for each column.
+ Returns an (({Array})) of (({Hash})) objects, one for each column.
Each (({Hash})) object must have at least one key 'name' which
value is the name of that column.
- Further possible values are 'sql_type' (integer, e.g. DBI::SQL_INT),
+ Further possible values are 'sql_type' (integer, e.g., DBI::SQL_INT),
'type_name' (string), 'precision' (= column size), 'scale' (= decimal digits),
'default', 'nullable', 'indexed', 'primary' and 'unique'.
--- rows
- Return the RPC (Row Processed Count) of the last executed statement, or
- (({nil})) if no such exist.
+ Returns the RPC (Row Processed Count) of the last executed statement, or
+ (({nil})) if no such exists.
-=== Optional methods which can be specified by (({Statement}))
+=== Optional methods that can be specified by (({Statement}))
--- bind_params( *bindvars )
- Binds the placeholders in the statement to the values of ((|bindvars|)).
+ Binds the values in ((|bindvars|)) to the placeholders in the statement.
- Defaults to calling ((<bind_param>)) for each value, with ((*param*)) starting
+ Defaults to calling ((<bind_param>)) for each value, with ((|param|)) starting
from 1 increasingly.
--- cancel
- Free any result set resources which were made after a call to (({execute})).
- After calling this method, a call to one of the ((*fetch*)) methods is no more valid.
+ Free any result set resources which were made after a call to ((<execute>)).
+ After calling this method, calls to any of the ((*fetch*)) methods are no longer valid.
- Defaults to do nothing.
+ The default is to do nothing.
--- fetch_scroll( direction, offset )
- ((*direction*)) is one of the following constants:
+ ((|direction|)) is one of the following constants:
* SQL_FETCH_NEXT
* SQL_FETCH_PRIOR
* SQL_FETCH_FIRST
@@ -241,46 +245,46 @@
* SQL_FETCH_ABSOLUTE
* SQL_FETCH_RELATIVE
- ((*offset*)) is a positive or negativ number (only when SQL_FETCH_RELATIVE is used).
+ ((|offset|)) is a positive or negative number (only when SQL_FETCH_RELATIVE is used).
- By default only SQL_FETCH_NEXT, SQL_FETCH_LAST, SQL_FETCH_RELATIVE (if positive) are
- implemented, otherwise it raises NotSupportedError.
+ By default, only SQL_FETCH_NEXT, SQL_FETCH_LAST, SQL_FETCH_RELATIVE (if positive) are
+ implemented. Otherwise, this method raises a NotSupportedError exception.
- Note: This method should return not a newly created object on each call,
- instead you should return one and the same Array object but with
+ Note: This method should not return a newly created object on each call;
+ instead, you should return one and the same (({Array})) object but with
changed data.
--- fetch_many( cnt )
- Return an (({Array})) of the next ((*cnt*)) rows, where a row is itself an (({Array})).
+ Returns an (({Array})) of the next ((|cnt|)) rows, where a row is itself an (({Array})).
- Note: Unlike (({fetch})), this method should return a new Array object.
+ Note: Unlike ((<fetch>)), this method should return a new (({Array})) object.
- If there are no more ((*cnt*)) rows available return the rest.
- Return (({nil})) if no rows are available.
+ If ((|cnt|)) rows are not available, return the rest (as many as are available).
+ Returns (({nil})) if no rows are available.
- Defaults to multiple calls to (({fetch})).
+ Defaults to multiple calls to ((<fetch>)).
--- fetch_all
- Return an (({Array})) of all rows which have not yet been fetched, where a row is
- itself an (({Array})) (see Statement#fetch_many).
+ Returns an (({Array})) of all rows that have not yet been fetched, where a row is
+ itself an (({Array})) (see (({Statement#fetch_many}))).
- Note: Unlike (({fetch})), this method should return a new Array object.
+ Note: Unlike ((<fetch>)), this method should return a new (({Array})) object.
- Return (({nil})) if no rows are available.
+ Returns (({nil})) if no rows are available.
- Defaults to multiple calls to (({fetch})).
+ Defaults to multiple calls to ((<fetch>)).
--- []( attr )
- Return value of attribute ((*attr*)).
+ Returns the value of the attribute ((|attr|)).
- Defauls to return the value of (({@attr[attr]})).
+ The default is to return the value of (({@attr[attr]})).
--- []=( attr, value )
- Set value of attribute ((*attr*)) to ((*value*)).
- Raise a NotSupportedError, if the database do not support an attribute.
+ Set the value of the attribute ((|attr|)) to ((|value|)).
+ Raise a NotSupportedError exception if the database does not support an attribute.
- The default implementation is to raise a NotSupportedError.
+ The default implementation is to raise a NotSupportedError exception.
=end
Index: DBI_SPEC
===================================================================
RCS file: /cvsroot/ruby-dbi/src/doc/DBI_SPEC,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- DBI_SPEC 2 Oct 2002 18:10:37 -0000 1.1
+++ DBI_SPEC 22 Jan 2003 10:45:32 -0000 1.2
@@ -45,14 +45,14 @@
--- SQL_VARBINARY
--- SQL_LONGVARBINARY
--- SQL_OTHER
- Constant representing SQL types.
+ Constants representing SQL types.
=== Exceptions
Exception classes were "borrowed" from Python API 2.0.
--- Warning < RuntimeError
- For important warnings like data truncation etc.
+ For important warnings such as data truncation, etc.
--- Error < RuntimeError
Base class of all other error exceptions.
@@ -64,75 +64,75 @@
--- NotImplementedError < InterfaceError
Exception raised if the DBD driver has not specified
- a mandantory method (not in Python API 2.0).
+ a mandatory method (not in Python API 2.0).
--- DatabaseError < Error
Exception for errors related to the database.
- Has three attributes ((|err|)), ((|errstr|)) and ((|state|)).
+ Has three attributes: ((|err|)), ((|errstr|)) and ((|state|)).
--- DataError < DatabaseError
Exception for errors due to problems with the processed
- data like division by zero, numeric value out of range etc.
+ data, such ase division by zero, numeric value out of range, etc.
--- OperationalError < DatabaseError
Exception for errors related to the database's operation which
- are not necessarily under the control of the programmer like
+ are not necessarily under the control of the programmer, such as
unexpected disconnect, datasource name not found, transaction
- could not be processed, a memory allocation error occured during
- processing etc.
+ could not be processed, a memory allocation error occurred during
+ processing, etc.
--- IntegrityError < DatabaseError
Exception raised when the relational integrity of the database
- is affected, e.g. a foreign key check fails
+ is affected, e.g., a foreign key check fails.
--- InternalError < DatabaseError
Exception raised when the database encounters an internal error,
- e.g. the cursor is not valid anymore, the transaction is out of sync.
+ e.g., the cursor is not valid anymore, the transaction is out of sync.
--- ProgrammingError < DatabaseError
- Exception raised for programming errors, e.g. table not found
+ Exception raised for programming errors, e.g., table not found
or already exists, syntax error in SQL statement, wrong number
of parameters specified, etc.
--- NotSupportedError < DatabaseError
- Raised if e.g. commit() is called for a database which do not
+ Raised if, e.g., ((<commit>)) is called for a database that does not
support transactions.
=== Module functions
--- DBI.connect( driver_url, user=nil, auth=nil, params=nil )
- Connect to the database specified by ((*driver_url*)), which may
+ Connect to the database specified by ((|driver_url|)), which may
look like "dbi:Oracle:oracle.neumann".
- Returns an (({DBI::DatabaseHandle})) object, or if called with code-block,
+ Returns a (({DBI::DatabaseHandle})) object, or if called with a code-block,
calls this block with the new (({DBI::DatabaseHandle})) as parameter and
- calls (({disconnect})) after calling the block if it was not yet disconnected by
+ calls ((<disconnect>)) after calling the block if it was not yet disconnected by
the user.
--- DBI.available_drivers
- Returns an (({Array})) of all available DBD driver.
- The strings which represent a DBD driver are partial DSN's
- (e.g. "dbi:Oracle:").
+ Returns an (({Array})) of all available DBD drivers.
+ The strings which represent the DBD drivers are partial DSNs
+ (e.g., "dbi:Oracle:").
--- DBI.data_sources( driver )
- Returns all available DSN's for the ((*driver*)), which
- is a partial DSN (e.g. "dbi:Oracle:").
+ Returns all available DSNs for the ((|driver|)), which
+ is a partial DSN (e.g., "dbi:Oracle:").
--- DBI.disconnect_all( driver=nil )
- Disconnects all active connections of ((*driver*)) or
- all drivers if ((*driver*)) is (({nil})).
+ Disconnects all active connections of ((|driver|)) or
+ all drivers if ((|driver|)) is (({nil})).
--- DBI.trace(mode=nil, output=nil)
- Set the trace mode for all following created Handles to these values.
+ Sets the trace mode for all subsequently created Handles to these values.
- If a parameter is (({nil})) the value is not changed.
+ If a parameter is (({nil})), the value is not changed.
((|mode|)) defaults to 2 if it is (({nil})), and ((|output|)) to (({STDERR})) if a value was not
- set before.
- For ((|mode|)) the values 0, 1, 2 or 3 are allowed.
+ previously set.
+ For ((|mode|)), the values 0, 1, 2 or 3 are allowed.
- Note: Tracing is only activated, if you load the module "dbi/trace", because tracing currently
+ Note: Tracing is only activated if you load the module "dbi/trace", because tracing currently
depends on AspectR > 0.3.3.
== Class DBI::Handle
@@ -142,19 +142,19 @@
=== Instance Methods
--- func( function, *values )
- Calls the driver specific extension function named by
+ Calls the driver-specific extension function named by
((|function|)) with ((|values|)) as parameters.
--- trace(mode=nil, output=nil)
- Set the trace mode for this handle as well as for all sub-handles (in the case of DriverHandle and
+ Sets the trace mode for this handle as well as for all sub-handles (in the case of DriverHandle and
DatabaseHandle).
- If a parameter is (({nil})) the value is not changed.
+ If a parameter is (({nil})), the value is not changed.
((|mode|)) defaults to 2 if it is (({nil})), and ((|output|)) to (({STDERR})) if a value was not
- set before.
- For ((|mode|)) the values 0, 1, 2 or 3 are allowed.
+ previously set.
+ For ((|mode|)), the values 0, 1, 2 or 3 are allowed.
- Note: Tracing is only activated, if you load the module "dbi/trace", because tracing currently
+ Note: Tracing is only activated if you load the module "dbi/trace", because tracing currently
depends on AspectR > 0.3.3.
@@ -176,68 +176,69 @@
--- prepare( stmt )
--- prepare( stmt ) {|statement_handle| aBlock}
- Prepare the SQL statement ((|stmt|)) and return a
- (({DBI::StatementHandle})) or if called with a code-block
- calls the block with the handle as parameter and after that
+ Prepares the SQL statement ((|stmt|)) and returns a
+ (({DBI::StatementHandle})), or if called with a code-block,
+ calls the block with the handle as its parameter and after that
calls (({#finish})) onto the handle to free all resources
--- execute( stmt, *bindvars )
--- execute( stmt, *bindvars ) {|statement_handle| aBlock}
- Executes immediately the SQL statement ((*stmt*)) with binding
- the placeholders with values given in ((*bindvars*)) before.
+ Immediately executes the SQL statement ((|stmt|)) after binding
+ the values in ((|bindvars|)) to the placeholders in the statement.
- Returns a (({DBI::StatementHandle})) or if called with code-block
- calls the block with the handle as parameter and after that
+ Returns a (({DBI::StatementHandle})), or if called with a code-block,
+ calls the block with the handle as its parameter and after that
calls (({#finish})) onto the handle to free all resources.
--- do( stmt, *bindvars )
- Same as ((<execute>)) only that no (({DBI::StatementHandle})) is
- returned but the RPC (Row Processed Count).
+ Same as ((<execute>)) except the RPC (Row Processed Count) is returned
+ rather than a (({DBI::StatementHandle})).
--- select_one( stmt, *bindvars)
- Executes the statement with binding the values to the parameters and returns the
- first row as a reference to a Row object.
+ Executes the statement after binding the values to the placeholders in the statement, then returns the
+ first row as a reference to a (({DBI::Row})) object.
--- select_all( stmt, *bindvars)
- Executes the statement with binding the values to the parameters and returns all
- resulting rows.
+ Executes the statement after binding the values to the parameters, then returns all
+ resulting rows as an array of (({DBI::Row})) objects.
- If called as iterator the passed (({DBI::Row})) objects are only references.
+ If called as an iterator, the passed (({DBI::Row})) objects are only references.
--- tables
Returns a list of all tables and views.
--- columns( table )
- Get more information about the columns of table ((|table|)).
- Returns an array containing for each column one (({DBI::ColumnInfo})) object.
+ Gets more information about the columns of the table ((|table|)).
+ Returns an array containing a (({DBI::ColumnInfo})) object for each column
+ in the table.
--- ping
Returns (({true})) if the connection is active, otherwise (({false})).
- In contranst to ((<connected?>)), ((<ping>)) tests if the connection is
+ In contrast to ((<connected?>)), ((<ping>)) tests if the connection is
still active by executing some SQL or doing something else.
--- quote( value )
- Quotes the given value ((*value*)) database specific and returns the result.
+ Quotes the given value ((|value|)) in database-specific fashion and returns the result.
--- commit
- Commits current transaction.
+ Commits the current transaction.
--- rollback
- Rolls the current transaction back.
+ Rolls back the current transaction.
--- transaction {|database_handle| aBlock}
First commits the current transaction, then
executes the given block where the parameter is
the object itself (the database handle). If the
- block raises an exception, then it rolls the transaction
- back otherwise commits it.
+ block raises an exception, then it rolls back the transaction;
+ otherwise, it commits the transaction.
--- [](attr)
--- []=(attr)
- Sets or gets the attribute ((*attr*)).
+ Gets or sets the attribute ((|attr|)).
An attribute can for example be "AutoCommit", which can be set to
- (({true})) or (({false})). Attributes are database dependant.
+ (({true})) or (({false})). Attributes are database dependent.
== Class DBI::StatementHandle
@@ -252,85 +253,87 @@
=== Instance Methods
--- bind_param( param, value, attribs=nil )
- Bind ((*param*)) which is either a (({String})) which is then the name of the
- placeholder used in the SQL statement (e.g. Oracle: "SELECT * FROM EMP WHERE ENAME = :ename")
- or it is an integer which is then the number of the placeholder where counting starts at 1.
+ Binds the value ((|value|)) to a placeholder.
+ The placeholder is represented by ((|param|)), which is either a
+ (({String})) representing the name of the
+ placeholder used in the SQL statement (e.g., Oracle: "SELECT * FROM EMP WHERE ENAME = :ename"),
+ or an integer that indicates the number of the placeholder.
+ Placeholder numbers begin at 1.
- ((*value*)) is the value which is bound to the placeholder.
-
- ((*attribs*)) is not yet used in this version, but could later be a hash containing more information
- like parameter type etc..
+ ((|attribs|)) is not yet used in this version, but could later be a hash containing more information
+ like parameter type, etc.
--- execute( *bindvars )
- Execute the statement but before binds the placeholders with ((*bindvars*)).
+ Executes the statement after binding the values in ((|bindvars|)) to the placeholders in the statement.
--- finish
Frees the resources for the statement.
- After calling ((<finish>)) no other operation on this
+ After calling ((<finish>)), no other operation on this
statement is valid.
--- cancel
Frees any result set resources which were made after a call
- to (({execute})).
- After calling this method, a call to one of the ((*fetch*)) methods
- is no more valid.
+ to ((<execute>)).
+ After calling this method, calls to any of the ((*fetch*)) methods
+ are no longer valid.
--- column_names
Returns an (({Array})) of all column names.
--- column_info
- Returns an (({Array})) containing fore each column one (({DBI::ColumnInfo})) object.
+ Returns an (({Array})) containing a (({DBI::ColumnInfo})) object for each column
+ in the result set.
--- rows
Returns the RPC (Row Processed Count) of the last executed statement, or
- (({nil})) if no such exist.
+ (({nil})) if no such exists.
--- fetchable?
- Returns true if you can fetch rows using fetch etc..
+ Returns (({true})) if you can fetch rows using ((<fetch>)), etc.
--- fetch
Returns a (({DBI::Row})) object, or (({nil})) if there are
no more rows to fetch.
- When called as iterator, the block is called for each row
- until no more row is available. Each row is passed to the
- block as (({DBI::Row})) object.
+ When called as an iterator, the block is called for each row
+ until no more rows are available. Each row is passed to the
+ block as a (({DBI::Row})) object.
Note that the returned or passed (({DBI::Row})) object is only a reference and
- should be copied (dup) if it is store elsewhere.
+ should be copied (dup) if it is stored elsewhere.
--- each {|row| aBlock }
- Same as ((<fetch>)) called as iterator.
+ Same as ((<fetch>)) called as an iterator.
--- fetch_array
- Returns the current row as (({Array})) or nil if no more
- row is available.
+ Returns the current row as an (({Array})) or (({nil})) if no more
+ rows are available.
- Can be also called as iterator.
+ Can also be called as an iterator.
--- fetch_hash
- Returns the current row as (({Hash})) or nil if no more
- row is available.
+ Returns the current row as a (({Hash})) or (({nil})) if no more
+ rows are available.
- Can be also called as iterator.
+ Can also be called as an iterator.
--- fetch_many( cnt )
- Returns an (({Array})) of the next ((*cnt*)) rows, which are
+ Returns an (({Array})) of the next ((|cnt|)) rows, which are
stored as (({DBI::Row})) objects.
Returns the empty array (({[]})) if there are no more rows.
--- fetch_all
- Same as ((<fetch_many>)) only that all rows are returned.
+ Same as ((<fetch_many>)) except that all rows are returned.
--- fetch_scroll( direction, offset=1 )
- ((*direction*)) is one of the following constants:
+ ((|direction|)) is one of the following constants:
* SQL_FETCH_NEXT
* SQL_FETCH_PRIOR
* SQL_FETCH_FIRST
@@ -338,19 +341,19 @@
* SQL_FETCH_ABSOLUTE
* SQL_FETCH_RELATIVE
- ((*offset*)) is a positive or negativ number (only when SQL_FETCH_RELATIVE is used).
+ ((|offset|)) is a positive or negative number (only when SQL_FETCH_RELATIVE is used).
- ((<fetch_scroll>)) do not automatically free the result set if no more rows are available
- if e.g. you get the last row.
+ ((<fetch_scroll>)) does not automatically free the result set if no more rows are available,
+ e.g., if you get the last row.
- Returns a (({DBI::Row})) object, if not possible, returns (({nil})).
+ Returns a (({DBI::Row})) object, or (({nil})) if no row is available.
Note that the returned (({DBI::Row})) object is only a reference and
should be copied (dup) if it is stored elsewhere.
--- [](attr)
--- []=(attr)
- Sets or gets the attribute ((*attr*)).
+ Gets or sets the attribute ((|attr|)).
=end
|
|
From: Elias K. <el...@us...> - 2002-12-28 14:41:30
|
Update of /cvsroot/ruby-dbi/subprojects/ruby-db2/ext/db2
In directory sc8-pr-cvs1:/tmp/cvs-serv29074
Modified Files:
Tag: DB2BLOBS
constants.h db2cli.c
Log Message:
experimental support for BLOBs via SQLBindParameter
Index: constants.h
===================================================================
RCS file: /cvsroot/ruby-dbi/subprojects/ruby-db2/ext/db2/constants.h,v
retrieving revision 1.1
retrieving revision 1.1.2.1
diff -u -r1.1 -r1.1.2.1
--- constants.h 5 Sep 2002 09:57:13 -0000 1.1
+++ constants.h 28 Dec 2002 14:41:26 -0000 1.1.2.1
@@ -5,6 +5,7 @@
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_NEED_DATA", INT2NUM(SQL_NEED_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));
@@ -87,4 +88,7 @@
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));
-
+// parameter direction
+rb_define_const(mDB2CLI, "SQL_PARAM_INPUT", INT2NUM(SQL_PARAM_INPUT));
+rb_define_const(mDB2CLI, "SQL_PARAM_OUTPUT", INT2NUM(SQL_PARAM_OUTPUT));
+rb_define_const(mDB2CLI, "SQL_PARAM_INPUT_OUTPUT", INT2NUM(SQL_PARAM_INPUT_OUTPUT));
Index: db2cli.c
===================================================================
RCS file: /cvsroot/ruby-dbi/subprojects/ruby-db2/ext/db2/db2cli.c,v
retrieving revision 1.2
retrieving revision 1.2.2.1
diff -u -r1.2 -r1.2.2.1
--- db2cli.c 20 Dec 2002 10:04:58 -0000 1.2
+++ db2cli.c 28 Dec 2002 14:41:27 -0000 1.2.2.1
@@ -8,7 +8,7 @@
* Contributors:
*
* Songsu Yun (yu...@us...)
- *
+ * Elias Karakoulakis (ek...@na...)
*
* Copyright (c) 2001, 2002 by Michael Neumann.
*
@@ -36,7 +36,25 @@
system (in Germany correct would be "5,7"). Fault of Linux ????
**********************************************************************/
-
+/**********************************************************************
+ A little note about memory management:
+ ======================================================================
+ When the old and the new programming paradigms (C & Ruby) are forced
+ to cooperate (as in our case), strange things can happen in the memory
+ management arena.
+ In detail: we need to be able to allocate memory from C routines AND
+ free them from the CLI AND Ruby's Garbage cleaner. Otherwise, memory
+ leaks will cause your available memory to drain.
+ We can't just use Ruby variables to store our intermediate buffers,
+ since the CLI will fiddle with them, regardless of any GC in place.
+ So we use a hash class variable, 'param_buffers' that contains all
+ memory buffer pointers allocated for CLI's use. Its form is:
+ key: Object.id of object holding buffers e.g. a Statement
+ value: array of pointer pairs (buffer, buffer size), one for each
+ parameter bound to this statement.
+ all buffers for a statement are freed whenever a new statement is
+ initialized, OR whenever a Statement object gets finalized from GC.
+**********************************************************************/
/* Includes */
#include <stdio.h>
@@ -44,8 +62,6 @@
#include "sqlcli1.h"
#include "ruby.h"
-
-
/* Macros */
#define TO_C_INT(val) NUM2INT(val)
#define TO_RUBY_INT(val) INT2NUM(val)
@@ -55,11 +71,11 @@
#define MIN(a,b) ((a) < (b) ? (a) : (b))
/* Global Variables */
-static VALUE mDB2CLI;
+static VALUE mDB2CLI, cDBI_Binary;
static VALUE cDate, cTime, cTimestamp;
static VALUE objNull; /* object for a SQL NULL value */
-
-
+static VALUE param_buffers;
+static VALUE paranoid_debug;
/* Functions */
@@ -445,7 +461,6 @@
(SQLSMALLINT*) &nullable
);
-
retval = rb_ary_new3(
5,
TO_RUBY_INT(rc),
@@ -1039,51 +1054,177 @@
}
-/*******************************************************
- SQLBindParameter added by yun
- =======================================================
- PARAMS: statement_handle : Integer,
- parameter_number : Integer,
- parameter_type : Integer,
- parameter_size : Integer,
- decimal_digits : Integer
- parameter_value : String,
-
- RETURNS: rc : Integer
-
- Note
- ValueType parameter to SQLBindParameter call is set to
- SQL_C_CHAR. DB2 will convert it to proper type
- based on ParameterType parameter(parameter_type)
-********************************************************/
-
-static VALUE
-db2_SQLBindParameter(self, statement_handle, parameter_number, parameter_type,
- parameter_size, decimal_digits, parameter_value)
- VALUE self;
- VALUE statement_handle, parameter_number, parameter_type, parameter_value;
- VALUE parameter_size, decimal_digits;
-{
- SQLRETURN rc;
-
- MUST_BE_STRING(parameter_value);
- rc = SQLBindParameter(
- (SQLHSTMT) TO_C_INT(statement_handle),
- (SQLUSMALLINT) TO_C_INT(parameter_number),
- (SQLSMALLINT) SQL_PARAM_INPUT, /* support input parameter only */
- (SQLSMALLINT) SQL_C_CHAR, /* ValueType. Always string */
- (SQLSMALLINT) TO_C_INT(parameter_type), /* SQL data type of the parameter */
- (SQLUINTEGER) TO_C_INT(parameter_size), /* column size */
- (SQLSMALLINT) TO_C_INT(decimal_digits), /* decimal digits */
- (SQLCHAR *FAR) RSTRING(parameter_value)->ptr, /* parameter value pointer */
- (SQLINTEGER) RSTRING(parameter_value)->len, /* buffer length */
- (SQLINTEGER *FAR) &(RSTRING(parameter_value)->len) /*StrLen */
- );
-
- return TO_RUBY_INT(rc);
+//~ /*******************************************************
+ //~ SQLBindParameter added by yun
+ //~ =======================================================
+ //~ PARAMS: statement_handle : Integer,
+ //~ parameter_number : Integer,
+ //~ parameter_type : Integer,
+ //~ parameter_size : Integer,
+ //~ decimal_digits : Integer
+ //~ parameter_value : String,
+
+ //~ RETURNS: rc : Integer
+
+ //~ Note
+ //~ ValueType parameter to SQLBindParameter call is set to
+ //~ SQL_C_CHAR. DB2 will convert it to proper type
+ //~ based on ParameterType parameter(parameter_type)
+//~ ********************************************************/
+
+//~ static VALUE
+//~ db2_SQLBindParameter(self, statement_handle, parameter_number, parameter_type,
+ //~ parameter_size, decimal_digits, parameter_value)
+ //~ VALUE self;
+ //~ VALUE statement_handle, parameter_number, parameter_type, parameter_value;
+ //~ VALUE parameter_size, decimal_digits;
+//~ {
+ //~ SQLRETURN rc;
+
+ //~ MUST_BE_STRING(parameter_value);
+ //~ rc = SQLBindParameter(
+ //~ (SQLHSTMT) TO_C_INT(statement_handle),
+ //~ (SQLUSMALLINT) TO_C_INT(parameter_number),
+ //~ (SQLSMALLINT) SQL_PARAM_INPUT, /* support input parameter only */
+ //~ (SQLSMALLINT) SQL_C_CHAR, /* ValueType. Always string */
+ //~ (SQLSMALLINT) TO_C_INT(parameter_type), /* SQL data type of the parameter */
+ //~ (SQLUINTEGER) TO_C_INT(parameter_size), /* column size */
+ //~ (SQLSMALLINT) TO_C_INT(decimal_digits), /* decimal digits */
+ //~ (SQLCHAR *FAR) RSTRING(parameter_value)->ptr, /* parameter value pointer */
+ //~ (SQLINTEGER) RSTRING(parameter_value)->len, /* buffer length */
+ //~ (SQLINTEGER *FAR) &(RSTRING(parameter_value)->len) /*StrLen */
+ //~ );
+
+ //~ return TO_RUBY_INT(rc);
+//~ }
+
+/*******************************************************
+ SQLBindParameter: bind a buffer to a parameter marker
+ =======================================================
+ PARAMS: SQLHSTMT StatementHandle (in)
+ SQLUSMALLINT ParameterNumber (in)
+ SQLSMALLINT InputOutputType (in)
+ SQLSMALLINT ValueType (in)
+ SQLSMALLINT ParameterType (in)
+ SQLUINTEGER ColumnSize (in)
+ SQLSMALLINT DecimalDigits (in)
+ SQLPOINTER ParameterValuePtr (in DEFERRED/out DEFERRED)
+ SQLINTEGER BufferLength, (in)
+ SQLINTEGER *FAR StrLen_or_IndPtr (in DEFERRED/out DEFERRED)
+ RETURNS: rc : Integer
+ ParameterValuePtr: Integer
+ StrLen_or_IndPtr: Integer
+********************************************************/
+static VALUE
+db2_SQLBindParameter(self, hstmt, param_id, param_direction, db2_sql_type, ruby_value)
+ VALUE self, hstmt, param_id, param_direction, db2_sql_type, ruby_value;
+{
+ SQLSMALLINT fCType, ibScale=0;
+ SQLUINTEGER cbColDef = 0;
+ SQLPOINTER rgbValue;
+ SQLINTEGER* pcbValue = ALLOC_N(SQLINTEGER, 1);
+ SQLRETURN rc;
+ VALUE tmp, id, hash, buffers;
+ int paramType;
+
+ if ((SQL_PARAM_OUTPUT == TO_C_INT(param_direction)) ||
+ (SQL_PARAM_INPUT_OUTPUT == TO_C_INT(param_direction))) {
+ // TODO: alloc buffer for returned value
+ }
+
+ if (NIL_P(ruby_value)) { // parameter is null
+ *pcbValue = SQL_NULL_DATA;
+ rgbValue = NULL;
+ fCType = SQL_C_DEFAULT;
+ paramType = SQL_NULL_DATA;
+ } else {
+ if (NIL_P(db2_sql_type)) {
+ rb_raise(rb_eTypeError, "DB2 CLI: db2_sql_type must be set to a valid type when a not-nil value is bound");
+ }
+ paramType = TO_C_INT(db2_sql_type);
+ switch (TYPE(ruby_value)) {
+ case T_OBJECT:
+ if (rb_obj_is_instance_of(ruby_value, cDBI_Binary)) {
+ ruby_value = rb_funcall(ruby_value, rb_intern("to_s"), 0);
+ } else {
+ rb_raise(rb_eTypeError, "DB2 CLI: large objects must be wrapped inside a DBI::Binary instance");
+ }
+ fCType = SQL_C_BINARY;
+ *pcbValue = RSTRING(ruby_value)->len;
+ rgbValue = ALLOC_N(char, (*pcbValue));
+ memcpy(rgbValue, RSTRING(ruby_value)->ptr, *pcbValue);
+ break;
+ case T_FIXNUM:
+ fCType = SQL_C_LONG;
+ *pcbValue = sizeof(long);
+ rgbValue = ALLOC(long);
+ *((long *)rgbValue) = (long) FIX2INT(ruby_value);
+ break;
+ case T_BIGNUM: case T_FLOAT: // dirty hack
+ ruby_value = rb_funcall(ruby_value, rb_intern("to_s"), 0);
+ case T_STRING:
+ fCType = SQL_C_CHAR;
+ *pcbValue = RSTRING(ruby_value)->len + 1; // to accomodate the terminating nil
+ rgbValue = ALLOC_N(char, (*pcbValue));
+ memcpy(rgbValue, RSTRING(ruby_value)->ptr, *pcbValue);
+ break;
+ default:
+ rb_raise(rb_eTypeError, "Cannot bind parameter to this kind of value!");
+ }
+ }
+
+ if (paranoid_debug) {
+ printf("SQLBindParameter: self=%x, hstmt=%x, param_id=%d, rgbValue=0x%08x, pcbValue=0x%08x, indPtr=%d\n", self, TO_C_INT(hstmt), TO_C_INT(param_id), rgbValue, pcbValue, ((SQLINTEGER) *pcbValue));
+ }
+
+ rc = SQLBindParameter(
+ (SQLHSTMT) TO_C_INT(hstmt), // StatementHandle
+ (SQLUSMALLINT) TO_C_INT(param_id), // ParameterNumber
+ (SQLSMALLINT) TO_C_INT(param_direction), // InputOutputType
+ (SQLSMALLINT) fCType, // ValueType
+ (SQLSMALLINT) paramType, // ParameterType
+ (SQLUINTEGER) cbColDef, // ColumnSize
+ (SQLSMALLINT) ibScale, // DecimalDigits
+ (SQLPOINTER) rgbValue, // ParameterValuePtr
+ (SQLINTEGER) sizeof(rgbValue), /* cbValueMax */ // BufferLength
+ (SQLINTEGER *FAR) pcbValue
+ );
+
+ // store buffer addresses for later disposal
+ //if (paranoid_debug) printf("param_buffers: %s\n", RSTRING(rb_funcall(param_buffers, rb_intern("inspect"), 0))->ptr);
+ id = rb_funcall(self, rb_intern("__id__"), 0);
+ if (NIL_P(buffers = rb_hash_aref(param_buffers, id))) {
+ buffers = rb_ary_new(); // create array of parameter buffer pointers
+ rb_hash_aset(param_buffers, id, buffers);
+ }
+ rb_ary_store(buffers, TO_C_INT(param_id)-1, rb_ary_new3(
+ 2, TO_RUBY_INT((int) rgbValue), TO_RUBY_INT((int) pcbValue)
+ ));
+ if (paranoid_debug) printf("param_buffers: %s\n", RSTRING(rb_funcall(param_buffers, rb_intern("inspect"), 0))->ptr);
+ return TO_RUBY_INT(rc);
+}
+
+// free parameter buffers
+static VALUE
+db2_free_bound_params(VALUE self, VALUE id) {
+ VALUE arr, pointer_pair, p1, p2;
+ if (paranoid_debug) printf("DB2CLI: cleaning up id %d, buffers: %s\n", TO_C_INT(id), RSTRING(rb_funcall(param_buffers, rb_intern("inspect"), 0))->ptr);
+ if (!NIL_P(arr = rb_hash_aref(param_buffers, id))) {
+ if (paranoid_debug) printf("DB2CLI: found hash key\n");
+ while (!NIL_P(pointer_pair = rb_ary_pop(arr))) {
+ p1 = rb_ary_pop(pointer_pair);
+ p2 = rb_ary_pop(pointer_pair);
+ free((void*) TO_C_INT(p1));
+ free((void*) TO_C_INT(p2));
+ if (paranoid_debug) printf("DB2CLI: freed buffers 0x%08x, 0x%08x\n", TO_C_INT(p1), TO_C_INT(p2));
+ }
+ if (paranoid_debug) printf("DB2CLI: deleting key %d from hash\n", TO_C_INT(id));
+ rb_funcall(param_buffers, rb_intern("delete"), 1, id);
+ }
+ if (paranoid_debug) printf("DB2CLI: buffers AFTER cleanup: %s\n", RSTRING(rb_funcall(param_buffers, rb_intern("inspect"), 0))->ptr);
+ return TO_RUBY_INT(0);
}
-
/*******************************************************
SQLGetCursorName added by yun
=======================================================
@@ -1144,11 +1285,65 @@
return TO_RUBY_INT(rc);
}
+
+
+/*******************************************************
+ SQLParamData added by ekarak
+ =======================================================
+ PARAMS: SQLHSTMT StatementHandle,
+ SQLPOINTER FAR *ValuePtrPtr
+ RETURNS: rc : Integer
+********************************************************/
+static VALUE
+db2_SQLParamData(self, hstmt, valueptrptr)
+VALUE self, hstmt, valueptrptr;
+{
+ SQLRETURN rc;
+
+ rc = SQLParamData(
+ (SQLHSTMT) TO_C_INT(hstmt),
+ (SQLPOINTER FAR*) TO_C_INT(valueptrptr)
+ );
+
+ return TO_RUBY_INT(rc);
+}
+
+/*******************************************************
+ SQLPutData added by ekarak
+ =======================================================
+ PARAMS: SQLHSTMT StatementHandle
+ SQLPOINTER DataPtr
+ SQLINTEGER StrLen_or_Ind
+ RETURNS: rc : Integer
+********************************************************/
+static VALUE
+db2_SQLPutData(self, hstmt, dataptr, strlen_or_ind)
+VALUE self, hstmt, dataptr, strlen_or_ind;
+{
+ SQLRETURN rc;
+
+ rc = SQLPutData(
+ (SQLHSTMT) TO_C_INT(hstmt),
+ (SQLPOINTER) TO_C_INT(dataptr),
+ (SQLINTEGER) TO_C_INT(strlen_or_ind)
+ );
+
+ return TO_RUBY_INT(rc);
+}
+
/* Init */
void Init_db2cli() {
+ rb_require("dbi");
+ // FIXME: is eval_string the most efficient way?
mDB2CLI = rb_eval_string("DB2CLI");
-
+ cDBI_Binary = rb_eval_string("DBI::Binary");
+
+ param_buffers = rb_hash_new();
+ rb_cv_set(mDB2CLI, "@@param_buffers", param_buffers); // store it as a class variable so that GC never frees it
+ printf("INIT: param_buffers: 0x%08x\n", param_buffers);
+ paranoid_debug = RTEST(rb_gv_get("$PARANOID_DEBUG"));
+
#include "constants.h"
rb_define_module_function(mDB2CLI, "SQLAllocHandle", db2_SQLAllocHandle, 2);
@@ -1178,15 +1373,17 @@
rb_define_module_function(mDB2CLI, "SQLGetDiagRec", db2_SQLGetDiagRec, 4);
rb_define_module_function(mDB2CLI, "SQLTables", db2_SQLTables, 5);
- rb_define_module_function(mDB2CLI, "SQLBindParameter", db2_SQLBindParameter, 6);
+ rb_define_module_function(mDB2CLI, "SQLBindParameter", db2_SQLBindParameter, 5);
rb_define_module_function(mDB2CLI, "SQLSetCursorName", db2_SQLSetCursorName, 2);
rb_define_module_function(mDB2CLI, "SQLGetCursorName", db2_SQLGetCursorName, 1);
+ rb_define_module_function(mDB2CLI, "SQLParamData", db2_SQLParamData, 2);
+ rb_define_module_function(mDB2CLI, "SQLPutData", db2_SQLPutData, 3);
+ //
+ rb_define_singleton_method(mDB2CLI, "free_bound_params",db2_free_bound_params,1);
+
/* 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");
}
-
-
|
|
From: Elias K. <el...@us...> - 2002-12-28 14:36:36
|
Update of /cvsroot/ruby-dbi/src/lib/dbd_db2
In directory sc8-pr-cvs1:/tmp/cvs-serv27888/lib/dbd_db2
Modified Files:
Tag: DB2BLOBS
DB2.rb
Log Message:
experimental support for BLOBs via SQLBindParameter
Index: DB2.rb
===================================================================
RCS file: /cvsroot/ruby-dbi/src/lib/dbd_db2/DB2.rb,v
retrieving revision 1.6
retrieving revision 1.6.4.1
diff -u -r1.6 -r1.6.4.1
--- DB2.rb 3 Jul 2002 16:48:35 -0000 1.6
+++ DB2.rb 28 Dec 2002 14:36:30 -0000 1.6.4.1
@@ -29,6 +29,8 @@
#
# $Id$
#
+# Severly hacked by Elias Karakoulakis <ek...@na...>
+# to support large object functionality
require 'db2/db2cli.rb'
@@ -36,7 +38,7 @@
module DBD
module DB2
-USED_DBD_VERSION = "0.1"
+USED_DBD_VERSION = "0.2.2"
module Util
include DB2CLI
@@ -44,11 +46,16 @@
private
def rc_ok(rc)
- rc == SQL_SUCCESS or rc == SQL_SUCCESS_WITH_INFO
+ rc == SQL_SUCCESS or rc == SQL_SUCCESS_WITH_INFO or rc == SQL_NEED_DATA
end
- def error(rc, msg)
- raise DBI::DatabaseError.new(msg) unless rc_ok(rc)
+ def error(rc, msg, handleType=nil, handle=nil)
+ begin
+ unless handle.nil? or handleType.nil?
+ SQLGetDiagRec(handleType, handle, 1, 512).each { |a| msg << "\n\t#{a}" }
+ end
+ raise DBI::DatabaseError.new(msg, rc)
+ end unless rc_ok(rc)
end
end # module DB2Util
@@ -65,10 +72,10 @@
def connect(dbname, user, auth, attr)
rc, dbc = SQLAllocHandle(SQL_HANDLE_DBC, @env)
- error(rc, "Could not allocate Database Connection")
+ error(rc, "Could not allocate Database Connection", SQL_HANDLE_ENV, @env)
rc = SQLConnect(dbc, dbname, user, auth)
- error(rc, "Could not connect to Database")
+ error(rc, "Could not connect to Database", SQL_HANDLE_DBC, dbc)
return Database.new(dbc, attr)
end
@@ -107,25 +114,26 @@
class Database < DBI::BaseDatabase
include Util
- include SQL::BasicBind
- include SQL::BasicQuote
+ #include SQL::BasicBind
+ #include SQL::BasicQuote
def disconnect
rollback
rc = SQLDisconnect(@handle)
- error(rc, "Could not disconnect from Database")
+ error(rc, "Could not disconnect from Database", SQL_HANDLE_DBC, @handle)
rc = SQLFreeHandle(SQL_HANDLE_DBC, @handle)
- error(rc, "Could not free Database handle")
- end
+ error(rc, "Could not free Database handle", SQL_HANDLE_DBC, @handle)
+ end
+=begin
def tables
rc, stmt = SQLAllocHandle(SQL_HANDLE_STMT, @handle)
- error(rc, "Could not allocate Statement")
+ error(rc, "Could not allocate Statement", SQL_HANDLE_DBC, @handle)
rc = SQLTables(stmt, "", "%", "%", "TABLE, VIEW")
- error(rc, "Could not execute SQLTables")
+ error(rc, "Could not execute SQLTables", SQL_HANDLE_STMT, stmt)
st = Statement.new(stmt, nil)
res = st.fetch_all
@@ -133,7 +141,13 @@
res.collect {|row| row[1].to_s + "." + row[2].to_s}
end
+=end
+ def tables
+ execute("SELECT TABSCHEMA,TABNAME FROM SYSCAT.TABLES").fetch_all.collect { |row|
+ "#{row[0].strip}.#{row[1].strip}"
+ }
+ end
def ping
begin
@@ -145,45 +159,37 @@
return false
end
end
-
- def do(stmt, *bindvars)
- rc, sth = SQLAllocHandle(SQL_HANDLE_STMT, @handle)
- error(rc, "Could not allocate Statement")
-
- sql = bind(self, stmt, bindvars)
- rc = SQLExecDirect(sth, sql)
- error(rc, "Could not execute statement")
-
- rc, rpc = SQLRowCount(sth)
- error(rc, "Could not get RPC")
-
- rc = SQLFreeHandle(SQL_HANDLE_STMT, sth)
- error(rc, "Could not free Statement")
-
- return rpc
+
+ def prepare(sql)
+ new_statement = Statement.new(@handle, sql)
+ new_statement.prepare
+ return new_statement
end
- def prepare(statement)
- rc, stmt = SQLAllocHandle(SQL_HANDLE_STMT, @handle)
- error(rc, "Could not allocate Statement")
-
- Statement.new(stmt, statement)
+ def []=(attribute, value)
+ rc = case attribute.downcase
+ when 'autocommit'
+ SQLSetConnectAttr(@handle, SQL_ATTR_AUTOCOMMIT, (value ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF), SQL_IS_INTEGER)
+ else -1
+ end
+ error(rc, "Could not set DB2 connection attribute (#{attribute.inspect}=#{value.inspect})", SQL_HANDLE_DBC, @handle)
+ @attr[attribute] = value
+ end
+
+ def [](attribute)
+ @attr[attribute]
end
-
- # TODO
- #def []=(attr, value)
- #end
# TODO: method columns(table)
def commit
rc = SQLEndTran(SQL_HANDLE_DBC, @handle, SQL_COMMIT)
- error(rc, "Could not commit transaction")
+ error(rc, "Could not commit transaction", SQL_HANDLE_DBC, @handle)
end
def rollback
rc = SQLEndTran(SQL_HANDLE_DBC, @handle, SQL_ROLLBACK)
- error(rc, "Could not rollback transaction")
+ error(rc, "Could not rollback transaction", SQL_HANDLE_DBC, @handle)
end
end # class Database
@@ -193,22 +199,102 @@
include Util
include SQL::BasicBind
include SQL::BasicQuote
-
- def initialize(handle, statement)
+
+ attr_reader :handle
+
+ # WARNING: Statement.new first argument is its parent database handle
+ # and NOT a statement handle (to converge with other DBD drivers API)
+ def initialize(dbhandle, statement)
super(nil)
- @handle = handle
+ @dbhandle = dbhandle
@statement = statement
+ rc, @handle = SQLAllocHandle(SQL_HANDLE_STMT, dbhandle)
+ error(rc, "Could not allocate Statement", SQL_HANDLE_DBC, dbhandle)
@arr = []
- @params = []
@cols = nil
- @cols = get_col_info if @statement.nil?
+ #@cols = get_col_info if @statement.nil?
+ #
+ @prepared = false
+ @params = Hash.new
+ @boundvars = 0
+ puts "#{self}.initialize handle=#{@handle}, dbhandle=#{dbhandle}, statement=#{statement}" if $DEBUG
end
-
+
+ #Ruby's finalizers are strange: finalizer closure must be defined OUTSIDE self.new()
+ # so that no reference to object is visible to the finalizer...!
+ @@__statement_new__ = Statement.method('new')
+ def self.new(*args)
+ obj = @@__statement_new__[args[0], args[1]]
+ puts "new Statement, id=#{obj.id}" if $DEBUG
+ ObjectSpace.define_finalizer(obj, Statement.finalizer)
+ return obj
+ end
+ def self.finalizer
+ return proc {|id|
+ puts "Statement id=#{id} is FINALIZED" if $DEBUG
+ DB2CLI.free_bound_params(id)
+ }
+ end
+ def prepare
+ puts "#{self}.prepare hnd=#{@handle} stmt=#{@statement}" if $DEBUG
+ raise DBI::DatabaseError.new('statement already prepared') if @prepared
+ rc = SQLPrepare(@handle, @statement)
+ error(rc, "Could not prepare statement", SQL_HANDLE_STMT, @handle)
+ if $DEBUG
+ rc, count = SQLNumParams(@handle)
+ puts "#{self}.prepare: DB2CLI counted #{count} parameters in statement"
+ end
+ parse_params
+ @prepared = true
+ end
+
+ def bind_param(param_id, param_value, attribs=nil)
+ puts "#{self}.bind_param: idx=#{param_id}, param_value.size=#{param_value.to_s.length}, attribs=#{attribs.inspect}" if $DEBUG
+ raise InterfaceError, "only '?' parameters supported" unless param_id.is_a? Fixnum
+ direction = SQL_PARAM_INPUT
+ # TODO: ruby-to-CLI mapping should be done by the DBI layer, not the driver
+ rc, db2_sql_type, size, decimalDigits = SQLDescribeParam(@handle, param_id)
+ error(rc, 'SQLDescribeParam failed', SQL_HANDLE_STMT, @handle)
+ if attribs
+ case attribs['direction']
+ when 'in' then direction = SQL_PARAM_INPUT
+ when 'out' then direction = SQL_PARAM_OUTPUT
+ when 'inout' then direction = SQL_PARAM_INPUT_OUTPUT
+ end
+ if attribs['sql_type']
+ db2_sql_type = DBI_to_DB2_type_mapping[attribs['sql_type']][0]
+ puts 'db2_sql_type overriden: ' + DBI::Utils::ConstResolver.to_name(DBI::DB2CLI, db2_sql_type).join(',') if $DEBUG
+ end
+ end
+ # do the doo
+ rc = SQLBindParameter(@handle, param_id, direction, db2_sql_type, param_value)
+ error(rc, "Could not bind parameter #{param_id.inspect}", SQL_HANDLE_STMT, @handle)
+ @boundvars += 1
+ end
+
+=begin
def bind_param(param, value, attribs)
raise InterfaceError, "only ? parameters supported" unless param.is_a? Fixnum
@params[param-1] = value
end
+=end
+
+ def execute
+ puts "#{self}.execute" if $DEBUG
+ if @prepared and (@params.size != @boundvars)
+ errstr = (@params.size < @boundvars)? 'Too many' : 'Not enough'
+ errstr << " SQL parameters (expected #{@params.size}, got #{@boundvars})"
+ raise DBI::DatabaseError.new(errstr)
+ end
+
+ rc = SQLExecute(@handle)
+ error(rc, "Could not execute statement:\n#{@statement}", SQL_HANDLE_STMT, @handle)
+
+ @cols = get_col_info
+ backbind_params
+ end
+=begin
def execute
sql = bind(self, @statement, @params)
@@ -220,10 +306,12 @@
#rc = SQLExecute(@handle)
#error(rc, "Could not execute statement")
end
+=end
def finish
+ flush_params
rc = SQLFreeHandle(SQL_HANDLE_STMT, @handle)
- error(rc, "Could not free Statement")
+ error(rc, "Could not free Statement", SQL_HANDLE_STMT, @handle)
end
def fetch
@@ -250,18 +338,55 @@
def cancel
rc = SQLFreeStmt(@handle, SQL_CLOSE)
- error(rc, "Could not close/cancel statment")
+ error(rc, "Could not close/cancel statement", SQL_HANDLE_STMT, @handle)
@cols = nil
end
def rows
rc, rpc = SQLRowCount(@handle)
- error(rc, "Could not get RPC")
+ error(rc, "Could not get RPC", SQL_HANDLE_STMT, @handle)
return rpc
end
-
+ #------
private
+ #------
+
+ # parses statements for parameters
+ def parse_params
+ puts "#{self}.parse_params" if $DEBUG
+ result = ""
+ @params = []
+ #flush_params
+ #puts "statement tokens: #{tokens(@statement).join(', ')}" if $DEBUG
+ tokens(@statement).each { |part|
+ case part
+ when '?'
+ @params << part
+ result << '?'
+ when '??'
+ result << '?'
+ else
+ result << part
+ end
+ }
+ puts "#{self}.parse_params: params size=#{@params.size}" if $DEBUG
+ end
+
+ # binds inout/out (result) parameter buffers after query execution into ruby values
+ def backbind_params
+ puts "#{self}.backbind_params" if $DEBUG
+ flush_params
+ # TODO: some beautiful code that uses @boundvars to return new Ruby values
+ # from stored procedure execution
+ end
+
+ # frees buffers allocated for inout/out parameters
+ def flush_params
+ puts "#{self}.flush_params" if $DEBUG
+ DB2CLI.free_bound_params(self.id) # let CLI free up its internal param buffers
+ @boundvars = 0
+ end
# TODO: check typenames
DB2_to_DBI_type_mapping = {
@@ -300,6 +425,42 @@
DB2CLI::SQL_LONGVARGRAPHIC => [DBI::SQL_OTHER, 'LONG VARGRAPHIC']
}
+ DBI_to_DB2_type_mapping = {
+ DBI::SQL_DOUBLE => [DB2CLI::SQL_DOUBLE, 'DOUBLE'],
+ DBI::SQL_FLOAT => [DB2CLI::SQL_FLOAT, 'FLOAT'],
+ DBI::SQL_REAL => [DB2CLI::SQL_REAL, 'REAL'],
+
+ DBI::SQL_INTEGER => [DB2CLI::SQL_INTEGER, 'INTEGER'],
+ DBI::SQL_BIGINT => [DB2CLI::SQL_BIGINT, 'BIGINT'],
+ DBI::SQL_SMALLINT => [DB2CLI::SQL_SMALLINT, 'SMALLINT'],
+
+ DBI::SQL_DECIMAL => [DB2CLI::SQL_DECIMAL, 'DECIMAL'],
+ DBI::SQL_NUMERIC => [DB2CLI::SQL_NUMERIC, 'NUMERIC'],
+
+ DBI::SQL_DATE => [DB2CLI::SQL_TYPE_DATE, 'DATE'],
+ DBI::SQL_TIME => [DB2CLI::SQL_TYPE_TIME, 'TIME'],
+ DBI::SQL_TIMESTAMP => [DB2CLI::SQL_TYPE_TIMESTAMP,'TIMESTAMP'],
+
+ DBI::SQL_CHAR => [DB2CLI::SQL_CHAR, 'CHAR'],
+ DBI::SQL_VARCHAR => [DB2CLI::SQL_VARCHAR, 'VARCHAR'],
+ DBI::SQL_LONGVARCHAR => [DB2CLI::SQL_LONGVARCHAR, 'LONG VARCHAR'],
+ DBI::SQL_CLOB => [DB2CLI::SQL_CLOB, 'CLOB'],
+
+ DBI::SQL_BINARY => [DB2CLI::SQL_BINARY, 'BINARY'],
+ DBI::SQL_VARBINARY => [DB2CLI::SQL_VARBINARY, 'VARBINARY'],
+ DBI::SQL_LONGVARBINARY => [DB2CLI::SQL_LONGVARBINARY, 'LONG VARBINARY'],
+ DBI::SQL_BLOB => [DB2CLI::SQL_BLOB, 'BLOB'],
+
+ # DB2 specific types
+ 'SQL_BLOB_LOCATOR' => [DB2CLI::SQL_BLOB_LOCATOR, 'BLOB LOCATOR'],
+ 'SQL_CLOB_LOCATOR' => [DB2CLI::SQL_CLOB_LOCATOR, 'CLOB LOCATOR'],
+ 'SQL_DBCLOB' => [DB2CLI::SQL_DBCLOB, 'DBCLOB'],
+ 'SQL_DBCLOB_LOCATOR' => [DB2CLI::SQL_DBCLOB_LOCATOR, 'DBCLOB LOCATOR'],
+ 'SQL_GRAPHIC' => [DB2CLI::SQL_GRAPHIC, 'GRAPHIC'],
+ 'SQL_VARGRAPHIC' => [DB2CLI::SQL_VARGRAPHIC, 'VARGRAPHIC'],
+ 'SQL_LONGVARGRAPHIC' => [DB2CLI::SQL_LONGVARGRAPHIC, 'LONG VARGRAPHIC']
+ }
+
MAX_COL_SIZE = 256
#
@@ -307,11 +468,11 @@
#
def get_col_info
rc, nr_cols = SQLNumResultCols(@handle)
- error(rc, "Could not get number of result columns")
+ error(rc, "Could not get number of result columns", SQL_HANDLE_STMT, @handle)
(1..nr_cols).collect do |c|
rc, column_name, buflen, data_type, column_size, decimal_digits, nullable = SQLDescribeCol(@handle, c, MAX_COL_SIZE)
- error(rc, "Could not describe column")
+ error(rc, "Could not describe column", @handle, SQL_HANDLE_STMT)
sql_type, type_name = DB2_to_DBI_type_mapping[data_type]
@@ -329,11 +490,11 @@
def do_fetch(rc)
return nil if rc == SQL_NO_DATA_FOUND
- error(rc, "Could not fetch row")
+ error(rc, "Could not fetch row", @handle, SQL_HANDLE_STMT)
@cols.each_with_index do |c, i|
rc, content = SQLGetData(@handle, i+1, c['db2_type'], c['precision'])
- error(rc, "Could not get data")
+ error(rc, "Could not get data", @handle, SQL_HANDLE_STMT)
@arr[i] =
case content
|