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 |