[svn-commits] r131 - in drivers/ruby/tags: . ingres-ruby-1.3.0

grant at ingres.com grant at ingres.com
Tue Jul 1 11:00:02 PDT 2008


Author: grant
Date: 2008-07-01 11:00:01 -0700 (Tue, 01 Jul 2008)
New Revision: 131

Added:
   drivers/ruby/tags/ingres-ruby-1.3.0/
   drivers/ruby/tags/ingres-ruby-1.3.0/CHANGELOG
   drivers/ruby/tags/ingres-ruby-1.3.0/README
   drivers/ruby/tags/ingres-ruby-1.3.0/extconf.rb
   drivers/ruby/tags/ingres-ruby-1.3.0/ingres_adapter.rb
   drivers/ruby/tags/ingres-ruby-1.3.0/readme.html
Removed:
   drivers/ruby/tags/ingres-ruby-1.3.0/CHANGELOG
   drivers/ruby/tags/ingres-ruby-1.3.0/README
   drivers/ruby/tags/ingres-ruby-1.3.0/extconf.rb
   drivers/ruby/tags/ingres-ruby-1.3.0/ingres_adapter.rb
   drivers/ruby/tags/ingres-ruby-1.3.0/readme.html
Log:
#199 - Create tag for Ruby 1.3.0

Copied: drivers/ruby/tags/ingres-ruby-1.3.0 (from rev 127, drivers/ruby/main)

Deleted: drivers/ruby/tags/ingres-ruby-1.3.0/CHANGELOG
===================================================================
--- drivers/ruby/main/CHANGELOG	2008-06-30 16:18:19 UTC (rev 127)
+++ drivers/ruby/tags/ingres-ruby-1.3.0/CHANGELOG	2008-07-01 18:00:01 UTC (rev 131)
@@ -1,22 +0,0 @@
-SVN
-- Add support for Ingres datatypes float4, float8, money, decimal, bigint,
-  and ANSI date/time/timestamp.
-- Add support in ingres_adapter.rb for Rails migrations
-- Restrict tables() to non-system tables
-
-version 1.2.2
-- Add an ascii README file for systems without access to a browser
-- Add TODO.txt show show areas that require attention
-- Add missing GPL header text to ingres_adapter.rb
-- Fix quote() in ingres_adapater.rb to use the class of variable rather than
-  the equivalent Ingres column type.
-- Fix segvio in Ingres Ruby driver when fetching char/varchar with data
-  longer than 4074 bytes.
-
-version 1.2.1
-- Initial release
-
-/*
-vim: ts=4 sw=4 expandtab
-$Id$
-*/

Copied: drivers/ruby/tags/ingres-ruby-1.3.0/CHANGELOG (from rev 128, drivers/ruby/main/CHANGELOG)
===================================================================
--- drivers/ruby/tags/ingres-ruby-1.3.0/CHANGELOG	                        (rev 0)
+++ drivers/ruby/tags/ingres-ruby-1.3.0/CHANGELOG	2008-07-01 18:00:01 UTC (rev 131)
@@ -0,0 +1,25 @@
+ersion 1.3.0
+- Add quote_column_names() for quoting of table and column names. Required
+  for the ActiveRecord base unit tests
+- Fix data truncation for the ActiveRecord :text type
+- Add support for Ingres datatypes float4, float8, money, decimal, bigint,
+  and ANSI date/time/timestamp.
+- Add support in ingres_adapter.rb for Rails migrations
+- Restrict tables() to non-system tables
+
+version 1.2.2
+- Add an ascii README file for systems without access to a browser
+- Add TODO.txt show show areas that require attention
+- Add missing GPL header text to ingres_adapter.rb
+- Fix quote() in ingres_adapater.rb to use the class of variable rather than
+  the equivalent Ingres column type.
+- Fix segvio in Ingres Ruby driver when fetching char/varchar with data
+  longer than 4074 bytes.
+
+version 1.2.1
+- Initial release
+
+/*
+vim: ts=4 sw=4 expandtab
+$Id$
+*/

Deleted: drivers/ruby/tags/ingres-ruby-1.3.0/README
===================================================================
--- drivers/ruby/main/README	2008-06-30 16:18:19 UTC (rev 127)
+++ drivers/ruby/tags/ingres-ruby-1.3.0/README	2008-07-01 18:00:01 UTC (rev 131)
@@ -1,513 +0,0 @@
-
-Ingres Corporation
-
-
-
-IInnggrreess RRuubbyy AAccttiivvee RReeccoorrdd AAddaapptteerr//DDrriivveerr VVeerrssiioonn 11..22..22
-
--------------------------------------------------------------------------------
-_11_.._00_ _WW_ee_ll_cc_oo_mm_ee
-_22_.._00_ _OO_vv_ee_rr_vv_ii_ee_ww
-_2_._1_ _N_e_w_ _i_n_ _T_h_i_s_ _R_e_l_e_a_s_e
-_33_.._00_ _OO_pp_ee_rr_aa_tt_ii_nn_gg_ _SS_yy_ss_tt_ee_mm_ _SS_uu_pp_pp_oo_rr_tt
-_44_.._00_ _II_nn_ss_tt_aa_ll_ll_aa_tt_ii_oo_nn_ _CC_oo_nn_ss_ii_dd_ee_rr_aa_tt_ii_oo_nn_ss
-_55_.._00_ _GG_ee_nn_ee_rr_aa_ll_ _CC_oo_nn_ss_ii_dd_ee_rr_aa_tt_ii_oo_nn_ss
-_5_._1_ _F_e_a_t_u_r_e_s_ _N_o_t_ _I_n_c_l_u_d_e_d
-_5_._2_ _S_y_n_t_a_x_ _f_o_r_ _t_h_e_ _I_n_g_r_e_s_ _A_R_ _A_d_a_p_t_e_r
-_5_._3_ _S_y_n_t_a_x_ _f_o_r_ _t_h_e_ _I_n_g_r_e_s_ _R_u_b_y_ _D_r_i_v_e_r
-_66_.._00_ _BB_uu_ii_ll_dd_ii_nn_gg_ _aa_nn_dd_ _II_nn_ss_tt_aa_ll_ll_ii_nn_gg_ _tt_hh_ee_ _II_nn_gg_rr_ee_ss_ _RR_uu_bb_yy_ _AA_RR_ _AA_dd_aa_pp_tt_ee_rr_//_DD_rr_ii_vv_ee_rr
-_6_._1_ _I_n_g_r_e_s_ _A_R_ _A_d_a_p_t_e_r
-_6_._2_ _I_n_g_r_e_s_ _R_u_b_y_ _D_r_i_v_e_r
-_77_.._00_ _EE_xx_aa_mm_pp_ll_ee_ _CC_oo_dd_ee
-_7_._1_ _E_x_a_m_p_l_e_ _1_:_ _R_a_i_l_s_ _C_o_o_k_b_o_o_k_ _T_u_t_o_r_i_a_l_ _(_W_e_b_ _A_p_p_l_i_c_a_t_i_o_n_)_ _U_s_i_n_g_ _I_n_g_r_e_s_ _A_R
-_A_d_a_p_t_e_r
-_7_._2_ _E_x_a_m_p_l_e_ _2_:_ _I_R_B_ _(_I_n_t_e_r_a_c_t_i_v_e_ _R_u_b_y_)_ _U_s_i_n_g_ _I_n_g_r_e_s_ _R_u_b_y_ _D_r_i_v_e_r_ _O_n_l_y_ _(_W_i_t_h_o_u_t_ _A_R
-_A_d_a_p_t_e_r_)
-_7_._3_ _E_x_a_m_p_l_e_ _3_:_ _R_u_b_y_ _P_r_o_g_r_a_m_ _U_s_i_n_g_ _I_n_g_r_e_s_ _R_u_b_y_ _D_r_i_v_e_r_ _O_n_l_y_ _(_W_i_t_h_o_u_t_ _A_R_ _A_d_a_p_t_e_r_)
-_7_._4_ _E_x_a_m_p_l_e_ _4_:_ _I_n_g_r_e_s_ _F_l_i_g_h_t_ _P_l_a_n_n_e_r_ _D_e_m_o_ _U_s_i_n_g_ _I_n_g_r_e_s_ _R_u_b_y_ _D_r_i_v_e_r_ _O_n_l_y_ 
-_(_W_i_t_h_o_u_t_ _A_R_ _A_d_a_p_t_e_r_)
-_88_.._00_ _KK_nn_oo_ww_nn_ _II_ss_ss_uu_ee_ss
-_99_.._00_ _CC_oo_nn_tt_aa_cc_tt_ _TT_ee_cc_hh_nn_ii_cc_aa_ll_ _SS_uu_pp_pp_oo_rr_tt
--------------------------------------------------------------------------------
-
-11..00 WWeellccoommee
-
-This readme contains all of the documentation on the Ingres Ruby Active Record
-(AR) adapter and driver. AR is the standard database access interface used by
-Ruby on Rails (ROR or Rails) applications.
-Please review this readme before building or installing this software. We
-encourage users to test the software and provide feedback.
--------------------------------------------------------------------------------
-
-22..00 OOvveerrvviieeww
-
-There are two components to the Ingres support for Ruby:
-
-* Ingres Active Record adapter
-* Ingres Ruby driver
-
-Both components are required for Rails applications using Active Record (AR),
-which is the standard Rails Object-to-Relations Mapping (ORM) interface. The
-adapter implements the AR classes for Ingres; internally, it invokes the
-classes and methods in the driver to actually communicate with Ingres.
-The driver, while primarily intended to service the adapter, can also be
-invoked directly from any Ruby program to communicate with Ingres. The driver
-interface does not follow any industry standard and may change in the future,
-if required.
-To summarize, the AR interface provides an object interface while the driver
-interface is a more direct SQL-level interface.
--------------------------------------------------------------------------------
-
-22..11 NNeeww iinn TThhiiss RReelleeaassee
-
-This is a minor release that addresses the following issues:
-
-* Fix quote() in ingres_adapater.rb to use the class of variable rather than
-  the equivalent Ingres column type.
-* Fix segvio in Ingres Ruby driver when fetching char/varchar with data longer
-  than 4074 bytes.
-
-The following files have been added to keep a track of the changes made and the
-work still to be done:
-
-* CHANGELOG
-* TODO
-
--------------------------------------------------------------------------------
-
-33..00 OOppeerraattiinngg SSyysstteemm SSuuppppoorrtt
-
-This Ingres Ruby Active Record adapter/driver supports all of the platforms
-supported by Ingres, including:
-
-* Solaris
-* HP-UX
-* AIX
-* Linux
-* Windows
-
--------------------------------------------------------------------------------
-
-44..00 IInnssttaallllaattiioonn CCoonnssiiddeerraattiioonnss
-
-To build and install the Ingres Ruby interface, the following components are
-required:
-
-* Ingres 2.6 or above. At a minimum, an Ingres client installation is required
-  on the same machine as the Ruby installation. For a list of Ingres binary and
-  source downloads, see _h_t_t_p_:_/_/_w_w_w_._i_n_g_r_e_s_._c_o_m.
-* Ruby, preferably at version 1.8.5 or later. Additional Ruby components or
-  related products (such as Active Record or Rails) may also be required
-  depending on how Ruby will be used with Ingres. See below for details.
-* C compiler (for example, GNU/C on Linux and UNIX, or Microsoft Visual Studio
-  6 on Windows). The C compiler is not needed if using a pre-built version of
-  the Ingres Ruby driver.
-  NNoottee:: Ruby does not yet support building on later versions of Microsoft
-  Visual Studio.
-* The Ingres Ruby AR adapter source code and driver binary. The source code for
-  the driver is also needed if not using the pre-built binary.
-
--------------------------------------------------------------------------------
-
-55..00 GGeenneerraall CCoonnssiiddeerraattiioonnss
-
--------------------------------------------------------------------------------
-
-55..11 FFeeaattuurreess NNoott IInncclluuddeedd
-
-The following features are currently not included in the Ingres Open Source
-Ruby interface (also see the Known Issues section):
-
-* Only one Ingres connection at a time is supported from an application.
-* Data types not supported are: float4, float8, money, bigint, decimal, and
-  ANSI date/time/timestamp.
-
--------------------------------------------------------------------------------
-
-55..22 SSyynnttaaxx ffoorr tthhee IInnggrreess AARR AAddaapptteerr
-
-See Ruby Active Record documentation: _h_t_t_p_:_/_/_a_r_._r_u_b_y_o_n_r_a_i_l_s_._c_o_m_/.
--------------------------------------------------------------------------------
-
-55..33 SSyynnttaaxx ffoorr tthhee IInnggrreess RRuubbyy DDrriivveerr
-
-NNoottee:: We do not recommend that production applications use this API since it is
-intended for the Ingres AR adapter. The API may change in the future. It is,
-however, useful for testing Ingres connectivity and functionality.
-Ruby program must have a “require 'Ingres'” statement to load in driver
-file.
-CCrreeaattee IInnggrreess ccllaassss oobbjjeecctt::
-
-  object_instance_name=Ingres.new
-
-MMeetthhooddss ((bbyy ccaatteeggoorryy))::
-CCoonnnneecctt ttoo ddaattaabbaassee::
-
-  connect(database_name)
-
-  connect_with_credentials(database_name, user, password)
-
-DDiissccoonnnneecctt ffrroomm ddaattaabbaassee::
-
-  disconnect()
-
-EExxeeccuuttee SSQQLL qquueerriieess aanndd ttrraannssaaccttiioonnaall ssttaatteemmeennttss::
-
-  execute(sql)
-
-(Alias for “execute” is “exec”.)
-For SQL queries or database procedure calls that contain parameters, use the
-pexecute() method in one of the following formats.
-For selects, inserts, deletes, and updates:
-
-  pexecute(sql [ [, param_type, param_value ] … ] )
-
-For database procedure calls:
-
-  pexecute(“{ <call> | <execute procedure> procedure_name [
-  (column_name = ? [ [ , column_name = ? ] … ] ) ] }” [ [ , column_name,
-  param_type, param_value ] … ] )
-
-where parameters in the sql text are represented by question marks (?) and
-there is one set of param_type/param_value entries for each one.
-param_type must be one of the following single characters:
- _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
-|_'_b_'_|_b_y_t_e_ _ _ _ _ _ _ _ |
-|_'_B_'_|_l_o_n_g_ _b_y_t_e_ _ _ |
-|_'_c_'_|_c_h_a_r_ _ _ _ _ _ _ _ |
-|_'_d_'_|_d_a_t_e_,_ _ _ _ _ _ _ |
-|_'_D_'_|_d_e_c_i_m_a_l_ _ _ _ _ |
-|_'_f_'_|_f_l_o_a_t_ _ _ _ _ _ _ |
-|_'_i_'_|_i_n_t_e_g_e_r_ _ _ _ _ |
-|_'_n_'_|_n_c_h_a_r_ _ _ _ _ _ _ |
-|_'_N_'_|_n_v_a_r_c_h_a_r_ _ _ _ |
-|_'_t_'_|_t_e_x_t_ _ _ _ _ _ _ _ |
-|_'_T_'_|_l_o_n_g_ _t_e_x_t_ _ _ |
-|_'_v_'_|_v_a_r_c_h_a_r_ _ _ _ _ |
-|_'_V_'_|_l_o_n_g_ _v_a_r_c_h_a_r|
-
-param_value should correspond to the type.
-Both methods return a result set consisting of an array of rows, each of which
-is in turn an array of the columns within the row. For example:
-
-  ing.pexecute("select * from t1 where f1 = ?", 'i', 2)
-
-RReessuulltt SSeett MMeettaaddaattaa::
- _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
-|_r_o_w_s___a_f_f_e_c_t_e_d_(_)_ _ _ _ _ _ _ _|_R_e_t_u_r_n_s_ _t_h_e_ _n_u_m_b_e_r_ _o_f_ _r_o_w_s_ _a_f_f_e_c_t_e_d_ _b_y_ _l_a_s_t_ _e_x_e_c_u_t_e_(_)|
-|_c_o_l_u_m_n___l_i_s_t___o_f___n_a_m_e_s_(_)_|_R_e_t_u_r_n_s_ _t_h_e_ _n_a_m_e_s_ _o_f_ _t_h_e_ _c_o_l_u_m_n_s_ _i_n_ _t_h_e_ _r_e_s_u_l_t_ _s_e_t_ _ _ |
-|data_types()          |Returns the data types of the columns in the result  |
-|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_s_e_t_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
-|data_sizes()          |Returns the data lengths of the columns in the result|
-|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_s_e_t_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
-
-DDaattaabbaassee MMeettaaddaattaa::
- _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
-|_c_u_r_r_e_n_t___d_a_t_a_b_a_s_e_(_)_|_R_e_t_u_r_n_s_ _n_a_m_e_ _o_f_ _t_h_e_ _c_u_r_r_e_n_t_ _d_a_t_a_b_a_s_e_ _c_o_n_n_e_c_t_e_d_ _t_o_ |
-|_t_a_b_l_e_s_(_)_ _ _ _ _ _ _ _ _ _ _|_R_e_t_u_r_n_s_ _l_i_s_t_ _o_f_ _a_l_l_ _t_a_b_l_e_s_ _i_n_ _t_h_e_ _c_u_r_r_e_n_t_ _d_a_t_a_b_a_s_e|
-
-MMiisscceellllaanneeoouuss::
-To turn trace debugging on or off:
-
-  set_debug_flag(flag, flag_value)
-
-where
-flag is one of following: GLOBAL_DEBUG, DEBUG_TRANSACTIONS, DEBUG_SQL,
-DEBUG_TERMINATION.
-flag_value is TRUE or FALSE.
--------------------------------------------------------------------------------
-
-66..00 BBuuiillddiinngg aanndd IInnssttaalllliinngg tthhee IInnggrreess RRuubbyy AARR AAddaapptteerr//DDrriivveerr
-
--------------------------------------------------------------------------------
-
-66..11 IInnggrreess AARR AAddaapptteerr
-
-At a minimum, Ruby's Active Record must be installed. If running Rails, this
-will already exist as part of the Rails installation. For non-Rails users, AR
-may come with Ruby or may be installed separately as a Ruby “gem” into the
-Ruby installation.
-There are several steps required to install the Ingres AR adapter into the Ruby
-AR installation.
-NNoottee:: If only using the Ingres Ruby driver interface (not AR), installation of
-the adapter can be skipped and you can go directly to installation of the
-driver below.
-Typically, the base path of the AR installation will be similar to the
-following and will be referred to hereafter in this documentation as AR_BASE
-(where the last digits in the path refer to the AR version):
-UUNNIIXX//LLiinnuuxx:: /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.14.2
-WWiinnddoowwss:: C:\ruby\lib\ruby\gems\1.8\gems\activerecord-1.15.3
-TToo iinnssttaallll tthhee IInnggrreess AARR aaddaapptteerr iinnttoo tthhee RRuubbyy AARR iinnssttaallllaattiioonn
-
-  1. Copy the adapter file, iinnggrreess__aaddaapptteerr..rrbb, to the AR_BASE/lib/active-
-     record/connection_adapters directory.
-  2. Add Ingres as a valid database to AR. Edit active_record.rb file in
-     AR_BASE/lib by adding “ingres” to the end of a line that looks like:
-
-       RAILS_CONNECTION_ADAPTERS = %w( mysql postgresql sqlite firebird
-       sqlserver db2 oracle sybase openbase iinnggrreess )
-
-  3. Set up database connection information. Create a new directory called
-     nnaattiivvee__iinnggrreess under the AR_BASE/test/connections directory. Copy and edit
-     the sample ccoonnnneeccttiioonn..rrbb file to define database name, user ID, password
-     information.
-  4. Set II_DATE_FORMAT to SWEDEN. Either set this as an OS environment
-     variable in your RAILS application environment or as an Ingres variable
-     (with the ingsetenv command). This restriction will be removed in the
-     future. Also, code in the adapter file, if uncommented (scan for SWEDEN),
-     may allow successful processing without setting II_DATE_FORMAT.
-  5. For each Rails application accessing Ingres, edit the ddaattaabbaassee..yymmll file in
-     the application's config folder to specify the Ingres adapter plus
-     database and user information. The following is a sample entry for a local
-     Ingres database connection named my_rails_app_development:
-
-       development:
-           adapter: ingres
-           database: my_rails_app_development
-           username: ingres
-           password: ingres
-           host: localhost
-
-     For remote connections, change database and host to Ingres remote
-     connection format in either “vnode::databasename” where vnode is a
-     name configured in the Ingres Network Utility or a dynamic vnode in
-     @host,protocol,port[user,pwd]” format. For details, see the Ingres
-     Connectivity Guide.
-
--------------------------------------------------------------------------------
-
-66..22 IInnggrreess RRuubbyy DDrriivveerr
-
-A binary version of the driver is provided for Windows (Ingres.so). If using
-the provided binary, skip to the iinnssttaallll step below.
-The driver can also be built from the source provided (Ingres.c). To build and
-install the Ingres Ruby driver, the following components are needed AND MUST BE
-IN YOUR PATH:
-
-* Ingres installation
-* C compiler (for example, GNU/C on Linux and UNIX, or Microsoft Visual Studio
-  6 on Windows).
-
-TToo bbuuiilldd tthhee ddrriivveerr
-
-  1. Copy source Ingres.c and extconf.rb to your build directory (anywhere).
-  2. Create the makefile using the Ruby mkmf utility. Run the following command
-     after customizing it to your installation of Ingres:
-
-       ruby -r mkmf extconf.rb
-           --with-ingres-include='/opt/Ingres/IngresII/ingres/files/'
-           --with-ingres-lib='/opt/Ingres/IngresII/ingres/lib/'
-
-     A sample createMake.bat has been included for Windows. The utility mkmf
-     pulls configuration information from the extconf.rb file, which may need
-     slight library name changes for different versions of Ingres or operating
-     systems; see comments in extconf.rb file.
-     The output should look similar to the following:
-
-       bash-2.05$ ruby -r mkmf extconf.rb --with-ingres-include='/usr/ingres/
-       files/' --with-ingres-lib='/usr/ingres/lib'
-       checking for iiapi.h... yes
-       checking for main() in -lingres... yes
-       checking for main() in -lingres... yes
-       creating Makefile
-
-  3. Compile and link the driver. Type mmaakkee on Linux and UNIX or nnmmaakkee on
-     Windows. This should compile and link cleanly, creating output shared
-     library Ingres.so.
-
-     o On Windows, this is a DLL, but is nevertheless suffixed with “.so”
-       rather than “.dll”.
-     o On Windows, you can ignore warnings about the compiler and linker flags
-       being unknown options.
-     o On Windows with Ruby versions later than 1.8.5, the following error may
-       be seen on the link:
-
-         cannot open input file "msvcrt-ruby18.lib"
-
-       This can be resolved by removing the (lower case) “libpath =” line
-       in the makefile.
-
-
-TToo iinnssttaallll tthhee ddrriivveerr
-Type mmaakkee iinnssttaallll. (On Windows, type nnmmaakkee).
-Or, with the pre-built Windows binary, copy Ingres.so to Ruby i386-msvcrt
-directory, such as: c:\ruby\lib\ruby\site_ruby\1.8\i386-msvcrt.
--------------------------------------------------------------------------------
-
-77..00 EExxaammppllee CCooddee
-
--------------------------------------------------------------------------------
-
-77..11 EExxaammppllee 11:: RRaaiillss CCooookkbbooookk TTuuttoorriiaall ((WWeebb AApppplliiccaattiioonn)) UUssiinngg IInnggrreess AARR
-AAddaapptteerr
-
-A Cookbook Tutorial can be accessed from the Rails website (_h_t_t_p_:_/_/
-_r_u_b_y_o_n_r_a_i_l_s_._o_r_g_/ docs) under the Tutorials section. Selection Rolling with Ruby
-on Rails: Part I takes you to _h_t_t_p_:_/_/_w_w_w_._o_n_l_a_m_p_._c_o_m_/_p_u_b_/_a_/_o_n_l_a_m_p_/_2_0_0_6_/_1_2_/_1_4_/
-_r_e_v_i_s_i_t_i_n_g_-_r_u_b_y_-_o_n_-_r_a_i_l_s_-_r_e_v_i_s_i_t_e_d_._h_t_m_l. The demo referred to in the tutorial
-is installed as part of some of the prepackaged Ruby on Rails versions, such as
-InstantRails on Windows or Rails LiveCD on Linux.
-To run this demo in InstantRails, which is preconfigured to run against another
-database, do the following:
-
-  1. Install the Ingres Ruby AR adapter and driver into InstantRails per the
-     instructions above (InstantRails comes with its own version of Ruby and
-     Active Record).
-  2. Create the database in Ingres with schemas.
-
-       1. Create the database:
-
-            createdb cookbook_development
-
-       2. Create and populate the tables:
-
-            sql cookbook_development < cookbook_ingres.sql
-
-
-  3. Configure the application to use the Ingres ActiveRecord adapter.
-     Edit database.yml in ...\rails_apps\cookbook:
-
-       1. Change adapter from "mysql" to "ingres" in all (three) occurrences.
-       2. Update username and password as needed; for example, username:
-          ingres.
-       3. Edit database to be the full name of the database. Unlike MySql, the
-          _development, _test, _production suffixes are not automatically
-          added.
-
-  4. Start up systems (if not already started):
-
-       1. Start up Ingres (ingstart)
-       2. Start up Rails. For Instant Rails:
-
-            cd d:\InstantRails
-            use_ruby
-            cd ..
-            InstantRails
-
-       3. Start up Mongrel (web server)
-          If Mongrel is already up and app or even database.yml was changed,
-          you must restart Mongrel:
-          Shutdown with Control-C in Mongrel startup command window.
-
-            cd d:\InstantRails\rails_apps\cookbook
-            mongrel_rails start
-
-
-  5. Run application:
-     From web browser, set url=http://localhost:3000/category. You should get a
-     screen showing "Online Cookbook" at the top.
-
--------------------------------------------------------------------------------
-
-77..22 EExxaammppllee 22:: IIRRBB ((IInntteerraaccttiivvee RRuubbyy)) UUssiinngg IInnggrreess RRuubbyy DDrriivveerr OOnnllyy ((WWiitthhoouutt AARR
-AAddaapptteerr))
-
-
-  >>>$ irb
-
-  irb(main):001:0> require 'Ingres'
-
-  => true
-
-  irb(main):002:0> i = Ingres.new
-
-  => #<Ingres:0xb7fba520>
-
-  irb(main):003:0> i.connect("activerecord_unittest")
-
-  => #<Ingres:0xb7fba520>
-
-  irb(main):006:0> sql="select * from developers"
-
-  => "select * from developers"
-
-  irb(main):007:0> result_set = i.execute(sql)
-
-  => [[5, "fixture_5", 100000, "NULL", "NULL"], [6, "fixture_6", 100000,
-  "NULL", "NULL"], [7,"fixture_7", 100000, "NULL", "NULL"], [11, "Jamis", 9000,
-  "NULL", "NULL"], [8, "fixture_8", 100000, "NULL", "NULL"], [9, "fixture_9",
-  100000, "NULL", "NULL"], [2, "Jamis", 150000, "NULL", "NULL"], [10,
-  "fixture_10", 100000, "NULL", "NULL"], [3, "fixture_3", 100000, "NULL",
-  "NULL"], [1, "David", 80000, "NULL", "NULL"], [4, "fixture_4", 100000,
-  "NULL", "NULL"]]
-
--------------------------------------------------------------------------------
-
-77..33 EExxaammppllee 33:: RRuubbyy PPrrooggrraamm UUssiinngg IInnggrreess RRuubbyy DDrriivveerr OOnnllyy ((WWiitthhoouutt AARR AAddaapptteerr))
-
-
-  require "Ingres"
-  ing = Ingres.new
-  # You must connect to a database.
-  # Be sure you've created the database using "createdb".
-  ing.connect(some_database)
-  # you can also use:
-  # ing.connect_with_credentials( some_database, user_name, password)
-  sql = "select * from some_table"
-  result_set = ing.execute(sql)
-  # or
-  # result_set = ing.exec(sql)
-  # the result set is an array of arrays.
-  # you get one array for each row
-  # {{a,b,c}, {d,e,f}, etc}
-  # metadata is stored in these routines
-  # how many rows were touched by the last query
-  # usually an update
-  puts ing.rows_affected
-  # what's the current database (from the connect call)
-  puts ing.current_database
-  # the names of each column in the result set
-  puts ing.column_list_of_names
-  # the size of the data in each column
-  # this could be the length of a varchar or an int
-  puts ing.data_sizes
-  # what type is in each column
-  puts ing.data_types
-  # all the tables in the current database
-  puts ing.tables
-  # properly terminate your database connection
-  ing.disconnect
-
--------------------------------------------------------------------------------
-
-77..44 EExxaammppllee 44:: IInnggrreess FFlliigghhtt PPllaannnneerr DDeemmoo UUssiinngg IInnggrreess RRuubbyy DDrriivveerr OOnnllyy
-((WWiitthhoouutt AARR AAddaapptteerr))
-
-If you would like to get a copy of this, please post a request on the Ingres
-Community Forum in the Database Drivers and APIs area.
--------------------------------------------------------------------------------
-
-88..00 KKnnoowwnn IIssssuueess
-
-Known issues are as follows:
-
-* Errors (such as trying to read an unsupported data type) may leave connection
-  state in an unusable state, causing errors such as “The requested operaton
-  cannot be performed with active transactions.”
-* Driver will not build on later versions of Microsoft Visual Studio (2003 and
-  later). While this was a Ruby limitation and not a driver problem, it needs
-  to be resolved before MS VS 6 becomes obsolete.
-* The tables() method in the Ingres driver should only return user tables, but
-  also returns internal Ingres (catalog) tables (those beginning with
-  “ii”).
-* Driver compilation and linking issues a number of warnings.
-* Some Active Record Unit (regression) tests fail.
-* RDoc does not generate accurate or helpful documentation of the adapter and
-  driver.
-* Ingres II_DATE_FORMATs other than SWEDEN not supported.
-* Ingres driver current_database() returns the entire connection string for the
-  database, including “vnode::” and server type, if present.
-
--------------------------------------------------------------------------------
-
-99..00 CCoonnttaacctt TTeecchhnniiccaall SSuuppppoorrtt
-
-As this product is still in alpha status, issues specific to the Ingres Ruby AR
-adapter and driver should be posted on the Ingres forum _h_t_t_p_:_/_/
-_c_o_m_m_u_n_i_t_y_._i_n_g_r_e_s_._c_o_m_/_f_o_r_u_m_s_/_i_n_d_e_x_._p_h_p_?_c_=_3 in the Database Driver and APIs forum
-rather than contacting Ingres Technical Support.
-For online technical assistance for other Ingres products or components, and a
-complete list of locations, primary service hours, and telephone numbers,
-contact technical support at _h_t_t_p_:_/_/_i_n_g_r_e_s_._c_o_m_/_s_u_p_p_o_r_t.
--------------------------------------------------------------------------------
-Copyright © 2007 Ingres Corporation. All rights reserved.

Copied: drivers/ruby/tags/ingres-ruby-1.3.0/README (from rev 129, drivers/ruby/main/README)
===================================================================
--- drivers/ruby/tags/ingres-ruby-1.3.0/README	                        (rev 0)
+++ drivers/ruby/tags/ingres-ruby-1.3.0/README	2008-07-01 18:00:01 UTC (rev 131)
@@ -0,0 +1,598 @@
+
+
+Ingres Corporation
+
+
+
+Ingres Ruby Active Record Adapter/Driver Version 1.3.0
+
+-------------------------------------------------------------------------------
+
+  1. Welcome
+  2. Overview
+
+       1. New_in_This_Release
+
+  3. Operating_System_Support
+  4. Installation_Considerations
+  5. General_Considerations
+
+       1. Features_Not_Included
+       2. Syntax_for_the_Ingres_Ruby_Driver
+       3. Syntax_for_the_Ingres_AR_Adapter
+
+  6. Building_and_Installing_the_Ingres_Ruby_AR_Adapter/Driver
+
+       1. Ingres_Ruby_Source_Code
+       2. Ingres_Ruby_Driver
+       3. Ingres_AR_Adapter
+
+  7. Example_Code
+
+       1. IRB_(Interactive_Ruby)_Using_Ingres_Ruby_Driver_Only_
+          (Without_AR_Adapter)
+       2. Ruby_Program_Using_Ingres_Ruby_Driver_Only_(Without_AR_Adapter)
+       3. Rails_Cookbook_Tutorial_(Web_Application)_Using_Ingres_AR_Adapter
+       4. Ingres_Flight_Planner_Demo_Using_Ingres_Ruby_Driver_Only_
+          (Without_AR_Adapter)
+
+  8. Known_Issues
+  9. More_Information
+
+-------------------------------------------------------------------------------
+
+Welcome
+
+This readme contains all of the documentation on the Ingres Ruby Active Record
+(AR) adapter and driver. AR is the standard database access interface used by
+Ruby on Rails (ROR or Rails) applications.
+Please review this readme before building or installing this software. We
+encourage users to test the software and provide feedback.
+-------------------------------------------------------------------------------
+
+Overview
+
+There are two components to the Ingres support for Ruby:
+
+* Ingres Active Record adapter
+* Ingres Ruby driver
+
+Both components are required for Rails applications using Active Record (AR),
+which is the standard Rails Object-to-Relations Mapping (ORM) interface. The
+adapter implements the AR classes for Ingres; internally, it invokes the
+classes and methods in the driver to actually communicate with Ingres.
+The driver, while primarily intended to service the adapter, can also be
+invoked directly from any Ruby program to communicate with Ingres. The driver
+interface does not follow any industry standard and may change in the future,
+if required.
+To summarize, the AR interface provides an object interface while the driver
+interface is a more direct SQL-level interface.
+-------------------------------------------------------------------------------
+
+New in This Release
+
+This is a major release that addresses the following:
+
+* Ingres Ruby Driver
+
+  o Restrict tables() to only return non-system tables
+  o Add support for Ingres datatypes float4, float8, money, decimal, bigint,
+    and ANSI SQL date/time/timestamp
+
+* Ruby on Rails adapter
+
+  o Add support for Ruby on Rails 2.1 Migrations - for more information about
+    ActiveRecord Migrations see - http://wiki.rubyonrails.org/rails/pages/
+    UnderstandingMigrations
+  o Extend driver support for new data types to Rails
+  o Improved test results for ActiveRecord unit tests - see http://
+    community.ingres.com/wiki/How_to_test_Ruby_on_Rails_with_Ingres
+
+
+-------------------------------------------------------------------------------
+
+Operating System Support
+
+This Ingres Ruby Active Record adapter/driver supports all of the platforms
+supported by Ingres, including:
+
+* Solaris
+* HP-UX
+* AIX
+* Linux
+* Windows
+
+-------------------------------------------------------------------------------
+
+Installation Considerations
+
+To build and install the Ingres Ruby interface, the following components are
+required:
+
+* Ingres 2.6 or above. At a minimum, an Ingres client installation is required
+  on the same machine as the Ruby installation. For a list of Ingres binary and
+  source downloads, see http://www.ingres.com.
+* Ruby, preferably at version 1.8.5 or later. Additional Ruby components or
+  related products (such as Active Record or Rails) may also be required
+  depending on how Ruby will be used with Ingres. See below for details.
+* C compiler (for example, GNU/C on Linux and UNIX, or Microsoft Visual Studio
+  6 on Windows). The C compiler is not needed if using a pre-built version of
+  the Ingres Ruby driver.
+  Note: Ruby does not yet support building on later versions of Microsoft
+  Visual Studio.
+* The Ingres Ruby AR adapter source code and driver binary. The source code for
+  the driver is also needed if not using the pre-built binary.
+
+-------------------------------------------------------------------------------
+
+General Considerations
+
+-------------------------------------------------------------------------------
+
+Features Not Included
+
+The following features are currently not included in the Ingres Open Source
+Ruby interface (also see the Known Issues section):
+
+* Only one Ingres connection at a time is supported from an application.
+
+-------------------------------------------------------------------------------
+
+Syntax for the Ingres Ruby Driver
+
+Note: We do not recommend that production applications use this API since it is
+intended for the Ingres AR adapter. The API may change in the future. It is,
+however, useful for testing Ingres connectivity and functionality.
+Ruby program must have a "require 'Ingres'" statement to load in driver file.
+Create Ingres class object:
+
+  object_instance_name=Ingres.new
+
+Methods (by category):
+Connect to database:
+
+  connect(database_name)
+
+  connect_with_credentials(database_name, user, password)
+
+Disconnect from database:
+
+  disconnect()
+
+Execute SQL queries and transactional statements:
+
+  execute(sql)
+
+(Alias for "execute" is "exec".)
+For SQL queries or database procedure calls that contain parameters, use the
+pexecute() method in one of the following formats.
+For selects, inserts, deletes, and updates:
+
+  pexecute(sql [ [, param_type, param_value ] … ] )
+
+For database procedure calls:
+
+  pexecute("{ <call> | <execute procedure> procedure_name [ (column_name = ? [
+  [ , column_name = ? ] … ] ) ] }" [ [ , column_name, param_type, param_value
+  ] … ] )
+
+where parameters in the sql text are represented by question marks (?) and
+there is one set of param_type/param_value entries for each one.
+param_type must be one of the following single characters:
+ _______________________
+|param_type|Description_|
+|b_________|byte________|
+|B_________|long_byte___|
+|c_________|char________|
+|d_________|date,_______|
+|D_________|decimal_____|
+|f_________|float_______|
+|i_________|integer_____|
+|n_________|nchar_______|
+|N_________|nvarchar____|
+|t_________|text________|
+|T_________|long_text___|
+|v_________|varchar_____|
+|V_________|long_varchar|
+
+param_value should correspond to the type.
+Both methods return a result set consisting of an array of rows, each of which
+is in turn an array of the columns within the row. For example:
+
+  ing.pexecute("select * from t1 where f1 = ?", 'i', 2)
+
+Result Set Metadata:
+ ____________________________________________________________________________
+|Method________________|Description__________________________________________|
+|rows_affected()_______|Returns_the_number_of_rows_affected_by_last_execute()|
+|column_list_of_names()|Returns_the_names_of_the_columns_in_the_result_set___|
+|data_types()          |Returns the data types of the columns in the result  |
+|______________________|set__________________________________________________|
+|data_sizes()          |Returns the data lengths of the columns in the result|
+|______________________|set__________________________________________________|
+
+Database Metadata:
+ _____________________________________________________________________
+|Method____________|Description_______________________________________|
+|current_database()|Returns_name_of_the_current_database_connected_to_|
+|tables()__________|Returns_list_of_all_tables_in_the_current_database|
+
+Miscellaneous:
+To turn trace debugging on or off:
+
+  set_debug_flag(flag, flag_value)
+
+where
+flag is one of following:
+
+* GLOBAL_DEBUG
+* DEBUG_TRANSACTIONS
+* DEBUG_SQL
+* DEBUG_TERMINATION
+
+flag_value is TRUE or FALSE.
+-------------------------------------------------------------------------------
+
+Syntax for the Ingres AR Adapter
+
+See Ruby Active Record documentation: http://ar.rubyonrails.com/.
+
+ActiveRecord Type Mappings
+
+The following table shows the type mappings between Ingres, Ruby and
+ActiveRecord.
+ _____________________________________________________________________________
+|ActiveRecord_Type|Ruby_Class|Ingres_Type_______________|Notes________________|
+|:primary_key     |          |INTEGER NOT NULL PRIMARY  |                     |
+|_________________|__________|KEY_______________________|_____________________|
+|:string          |String    |CHAR, NCHAR, VARCHAR,     |                     |
+|_________________|__________|NVARCHAR,INTERVAL_________|_____________________|
+|:text____________|String____|VARCHAR(32000)____________|_____________________|
+|:boolean_________|Boolean___|INTEGER1__________________|_____________________|
+|:integer_________|Fixnum____|INTEGER2|4|8______________|_____________________|
+|                 |Bignum    |if INTEGER4|8 won't fit in|                     |
+|_________________|__________|Fixnum____________________|_____________________|
+|:float___________|Float_____|FLOAT4,_FLOAT8,_MONEY_____|_____________________|
+|:decimal_________|String____|DECIMAL___________________|_____________________|
+|:date____________|Date______|ANSIDATE__________________|Ingres_9.1.0_or_later|
+|:datetime________|Time______|DATE,_INGRESDATE__________|_____________________|
+|:time____________|Time______|TIME______________________|Ingres_9.1.0_or_later|
+|:timestamp_______|Time______|TIMESTAMP_________________|Ingres_9.1.0_or_later|
+
+Note that the :binary ActiveRecord type is missing due to the lack of support
+for Ingres LONG BYTE, LONG VARCHAR support.
+-------------------------------------------------------------------------------
+
+Building and Installing the Ingres Ruby AR Adapter/Driver
+
+-------------------------------------------------------------------------------
+
+Ingres Ruby Source Code
+
+The source code for the Ingres Ruby driver is kept in a Subversion repository
+at http://code.ingres.com. In order to download the source you will need an SVN
+client. Below is a list of some of the clients available for working with
+Subversion
+
+* Windows - TortoiseSVN - http://tortoisesvn.tigris.org/
+* Linux - "subversion" package for your distribution
+* Unix - Build from sources http://subversion.tigris.org/
+* OS X
+
+  o Subversion from http://www.macports.org/
+  o Versions from http://www.versionsapp.com/
+
+
+To download the source you need to specify the following URL when performing a
+checkout:
+
+* Ruby - http://code.ingres.com/ingres/drivers/ruby/
+
+For example if using the command line Subversion client 'svn' the following
+will check out all the code for the Ingres Ruby driver:
+
+  svn co http://code.ingres.com/ingres/drivers/ruby/
+
+This will download the complete tree for the Ruby driver into the directory
+'ruby'. If you are only interested in the 'main' code line use the following
+command:
+
+  svn co http://code.ingres.com/ingres/drivers/ruby/main/ ruby-main
+
+Note that an additional parameter of 'ruby-main' has been specified. The code
+for http://code.ingres.com/ingres/drivers/ruby/main/ will be extracted in to
+this directory. Otherwise the checkout will download the code into a directory
+named 'main'. For more information on working with Ingres source code control
+system see - http://community.ingres.com/wiki/Connectivity_Drivers_Source_Code
+-------------------------------------------------------------------------------
+
+Ingres Ruby Driver
+
+A binary version of the driver is provided for Windows (Ingres.so). If using
+the provided binary, skip to the install step below.
+The driver can also be built from the source provided (Ingres.c). To build and
+install the Ingres Ruby driver, the following components are needed AND MUST BE
+IN YOUR PATH:
+
+* Ingres installation
+* C compiler (for example, GNU/C on Linux and UNIX, or Microsoft Visual Studio
+  6 on Windows).
+
+To build the driver
+
+  1. Copy source Ingres.c and extconf.rb to your build directory (anywhere).
+  2. Create the makefile using the Ruby mkmf utility. Run the following command
+     after customizing it to your installation of Ingres:
+
+       ruby -r mkmf extconf.rb
+           --with-ingres-include='/opt/Ingres/IngresII/ingres/files/'
+           --with-ingres-lib='/opt/Ingres/IngresII/ingres/lib/'
+
+     A sample createMake.bat has been included for Windows. The utility mkmf
+     pulls configuration information from the extconf.rb file, which may need
+     slight library name changes for different versions of Ingres or operating
+     systems; see comments in extconf.rb file.
+     The output should look similar to the following:
+
+       bash-2.05$ ruby -r mkmf extconf.rb --with-ingres-include='/usr/ingres/
+       files/' --with-ingres-lib='/usr/ingres/lib'
+       checking for iiapi.h... yes
+       checking for main() in -lingres... yes
+       checking for main() in -lingres... yes
+       creating Makefile
+
+  3. Compile and link the driver. Type make on Linux and UNIX or nmake on
+     Windows. This should compile and link cleanly, creating output shared
+     library Ingres.so.
+
+     o On Windows, this is a DLL, but is nevertheless suffixed with ".so"
+       rather than ".dll".
+     o On Windows, you can ignore warnings about the compiler and linker flags
+       being unknown options.
+     o On Windows with Ruby versions later than 1.8.5, the following error may
+       be seen on the link:
+
+         cannot open input file "msvcrt-ruby18.lib"
+
+       This can be resolved by removing the (lower case) "libpath =" line in
+       the makefile.
+
+
+To install the driver
+Type make install. (On Windows, type nmake).
+Or, with the pre-built Windows binary, copy Ingres.so to Ruby i386-msvcrt
+directory, such as: c:\ruby\lib\ruby\site_ruby\1.8\i386-msvcrt.
+-------------------------------------------------------------------------------
+
+Ingres AR Adapter
+
+At a minimum, Ruby's Active Record must be installed. If running Rails, this
+will already exist as part of the Rails installation. For non-Rails users, AR
+may come with Ruby or may be installed separately as a Ruby "gem" into the Ruby
+installation.
+There are several steps required to install the Ingres AR adapter into the Ruby
+AR installation.
+Note: If only using the Ingres Ruby driver interface (not AR), installation of
+the adapter can be skipped and you can go directly to installation of the
+driver below.
+Typically, the base path of the AR installation will be similar to the
+following and will be referred to hereafter in this documentation as AR_BASE
+(where the last digits in the path refer to the AR version):
+UNIX/Linux: /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.14.2
+Windows: C:\ruby\lib\ruby\gems\1.8\gems\activerecord-1.15.3
+To install the Ingres AR adapter into the Ruby AR installation
+
+  1. Copy the adapter file, ingres_adapter.rb, to the AR_BASE/lib/active-
+     record/connection_adapters directory.
+  2. NOTE: Not required for Rails 2.1 or later Add Ingres as a valid database
+     to AR. Edit active_record.rb file in AR_BASE/lib by adding "ingres" to the
+     end of a line that looks like:
+
+       RAILS_CONNECTION_ADAPTERS = %w( mysql postgresql sqlite firebird
+       sqlserver db2 oracle sybase openbase ingres )
+
+  3. Set up database connection information. Create a new directory called
+     native_ingres under the AR_BASE/test/connections directory. Copy and edit
+     the sample connection.rb file to define database name, user ID, password
+     information.
+  4. Set II_DATE_FORMAT to SWEDEN. Either set this as an OS environment
+     variable in your RAILS application environment or as an Ingres variable
+     (with the ingsetenv command). This restriction will be removed in the
+     future. Also, code in the adapter file, if uncommented (scan for SWEDEN),
+     may allow successful processing without setting II_DATE_FORMAT.
+  5. For each Rails application accessing Ingres, edit the database.yml file in
+     the application's config folder to specify the Ingres adapter plus
+     database and user information. The following is a sample entry for a local
+     Ingres database connection named my_rails_app_development:
+
+       development:
+           adapter: ingres
+           database: my_rails_app_development
+           username: ingres
+           password: ingres
+           host: localhost
+
+     For remote connections, change database and host to Ingres remote
+     connection format in either "vnode::databasename" where vnode is a name
+     configured in the Ingres Network Utility or a dynamic vnode in
+     @host,protocol,port[user,pwd]" format. For details, see the Ingres
+     Connectivity Guide.
+
+-------------------------------------------------------------------------------
+
+Example Code
+
+-------------------------------------------------------------------------------
+
+IRB (Interactive Ruby) Using Ingres Ruby Driver Only (Without AR Adapter)
+
+
+  >>>$ irb
+
+  irb(main):001:0> require 'Ingres'
+
+  => true
+
+  irb(main):002:0> i = Ingres.new
+
+  => #<Ingres:0xb7fba520>
+
+  irb(main):003:0> i.connect("activerecord_unittest")
+
+  => #<Ingres:0xb7fba520>
+
+  irb(main):006:0> sql="select * from developers"
+
+  => "select * from developers"
+
+  irb(main):007:0> result_set = i.execute(sql)
+
+  => [[5, "fixture_5", 100000, "NULL", "NULL"], [6, "fixture_6", 100000,
+  "NULL", "NULL"], [7,"fixture_7", 100000, "NULL", "NULL"], [11, "Jamis", 9000,
+  "NULL", "NULL"], [8, "fixture_8", 100000, "NULL", "NULL"], [9, "fixture_9",
+  100000, "NULL", "NULL"], [2, "Jamis", 150000, "NULL", "NULL"], [10,
+  "fixture_10", 100000, "NULL", "NULL"], [3, "fixture_3", 100000, "NULL",
+  "NULL"], [1, "David", 80000, "NULL", "NULL"], [4, "fixture_4", 100000,
+  "NULL", "NULL"]]
+
+-------------------------------------------------------------------------------
+
+Ruby Program Using Ingres Ruby Driver Only (Without AR Adapter)
+
+
+  require "Ingres"
+  ing = Ingres.new
+  # You must connect to a database.
+  # Be sure you've created the database using "createdb".
+  ing.connect(some_database)
+  # you can also use:
+  # ing.connect_with_credentials( some_database, user_name, password)
+  sql = "select * from some_table"
+  result_set = ing.execute(sql)
+  # or
+  # result_set = ing.exec(sql)
+  # the result set is an array of arrays.
+  # you get one array for each row
+  # {{a,b,c}, {d,e,f}, etc}
+  # metadata is stored in these routines
+  # how many rows were touched by the last query
+  # usually an update
+  puts ing.rows_affected
+  # what's the current database (from the connect call)
+  puts ing.current_database
+  # the names of each column in the result set
+  puts ing.column_list_of_names
+  # the size of the data in each column
+  # this could be the length of a varchar or an int
+  puts ing.data_sizes
+  # what type is in each column
+  puts ing.data_types
+  # all the tables in the current database
+  puts ing.tables
+  # properly terminate your database connection
+  ing.disconnect
+
+-------------------------------------------------------------------------------
+
+Rails Cookbook Tutorial (Web Application) Using Ingres AR Adapter
+
+A Cookbook Tutorial can be accessed from the Rails website (http://
+rubyonrails.org/ docs) under the Tutorials section. Selection Rolling with Ruby
+on Rails: Part I takes you to http://www.onlamp.com/pub/a/onlamp/2006/12/14/
+revisiting-ruby-on-rails-revisited.html. The demo referred to in the tutorial
+is installed as part of some of the prepackaged Ruby on Rails versions, such as
+InstantRails on Windows or Rails LiveCD on Linux.
+To run this demo in InstantRails, which is preconfigured to run against another
+database, do the following:
+
+  1. Install the Ingres Ruby AR adapter and driver into InstantRails per the
+     instructions above (InstantRails comes with its own version of Ruby and
+     Active Record).
+  2. Create the database in Ingres with schemas.
+
+       1. Create the database:
+
+            createdb cookbook_development
+
+       2. Create and populate the tables:
+
+            sql cookbook_development < cookbook_ingres.sql
+
+
+  3. Configure the application to use the Ingres ActiveRecord adapter.
+     Edit database.yml in ...\rails_apps\cookbook:
+
+       1. Change adapter from "mysql" to "ingres" in all (three) occurrences.
+       2. Update username and password as needed; for example, username:
+          ingres.
+       3. Edit database to be the full name of the database. Unlike MySql, the
+          _development, _test, _production suffixes are not automatically
+          added.
+
+  4. Start up systems (if not already started):
+
+       1. Start up Ingres (ingstart)
+       2. Start up Rails. For Instant Rails:
+
+            cd d:\InstantRails
+            use_ruby
+            cd ..
+            InstantRails
+
+       3. Start up Mongrel (web server)
+          If Mongrel is already up and app or even database.yml was changed,
+          you must restart Mongrel:
+          Shutdown with Control-C in Mongrel startup command window.
+
+            cd d:\InstantRails\rails_apps\cookbook
+            mongrel_rails start
+
+
+  5. Run application:
+     From web browser, set url=http://localhost:3000/category. You should get a
+     screen showing "Online Cookbook" at the top.
+
+-------------------------------------------------------------------------------
+
+Ingres Flight Planner Demo Using Ingres Ruby Driver Only (Without AR Adapter)
+
+If you would like to get a copy of this, please post a request on the Ingres
+Community Forum in the Database Drivers and APIs area.
+-------------------------------------------------------------------------------
+
+Known Issues
+
+Known issues are as follows:
+
+* Errors (such as trying to read an unsupported data type) may leave connection
+  state in an unusable state, causing errors such as "The requested operaton
+  cannot be performed with active transactions."
+* Driver will not build on later versions of Microsoft Visual Studio (2003 and
+  later). While this was a Ruby limitation and not a driver problem, it needs
+  to be resolved before MS VS 6 becomes obsolete.
+* Driver compilation and linking issues a number of warnings.
+* Some Active Record Unit (regression) tests fail.
+* RDoc does not generate accurate or helpful documentation of the adapter and
+  driver.
+* Ingres II_DATE_FORMATs other than SWEDEN not supported.
+* Ingres driver current_database() returns the entire connection string for the
+  database, including "vnode::" and server type, if present.
+* Ingres decimals are handled as string values
+
+-------------------------------------------------------------------------------
+
+More Information
+
+As this product is still in alpha status, issues specific to the Ingres Ruby AR
+adapter and driver should be posted on the Ingres forum http://
+community.ingres.com/forums/index.php?c=3 in the Database Driver and APIs forum
+rather than contacting Ingres Technical Support.
+You can find more information on using the Ingres Ruby driver and ActiveRecord
+bindings at http://community.ingres.com/wiki/Ingres_Ruby_Development_Center.
+For online technical assistance for other Ingres products or components, and a
+complete list of locations, primary service hours, and telephone numbers,
+contact technical support at http://ingres.com/support.
+-------------------------------------------------------------------------------
+Revision $Id: README.html 48 2008-05-02 15:45:23Z crogr01 $
+Available from: $Url$
+(c) 2008 Ingres Corporation. All rights reserved.

Deleted: drivers/ruby/tags/ingres-ruby-1.3.0/extconf.rb
===================================================================
--- drivers/ruby/main/extconf.rb	2008-06-30 16:18:19 UTC (rev 127)
+++ drivers/ruby/tags/ingres-ruby-1.3.0/extconf.rb	2008-07-01 18:00:01 UTC (rev 131)
@@ -1,65 +0,0 @@
-# ruby -r mkmf extconf.rb  --with-ingres-include="${II_SYSTEM}/ingres/files/" --with-ingres-lib="${II_SYSTEM}/ingres/lib/"
-
-#
-# if mkmf is not found on your system, install something like ruby1.8-dev
-#
-# May need to modify parameter to both "have_library" statements below
-# depending on operating system and/or version of Ingres.  See NOTEs
-# adjacent to each below.
-#
-require 'mkmf'
-puts "Start extconf.rb"
-dir_config('ingres')
-
-if RUBY_PLATFORM !~ /mswin32/
-    if ENV["II_SYSTEM"]
-        puts "Using II_SYSTEM=#{ENV['II_SYSTEM']}"
-        $CFLAGS += " -I#{ENV["II_SYSTEM"]}/ingres/files"
-    end
-end
-
-if have_header('iiapi.h')
-    if RUBY_PLATFORM =~ /mswin32/
-        if have_library('oiapi','IIapi_initialize') # Check for Ingres 2.6
-            puts "Found Ingres 2.6 or earlier.\n"
-        elsif have_library('iilibapi','IIapi_initialize')
-            puts "Found Ingres 2006 or later.\n"
-        else
-            puts "\n\nI couldn't find the Ingres libraries so I didn't create your Makefile.\n"
-            puts "Do you have Ingres installed?\n"
-            puts "Be sure to use the '--with-ingres-include' and '--with-ingres-lib' options.\n"
-            puts "See the first line of extconf.rb for an example.\n\n"
-            puts "BUILD FAILED\n\n"
-            exit
-        end
-    else
-        if ENV["II_SYSTEM"]
-            libdir = ENV["II_SYSTEM"] + "/ingres/lib"
-            $LDFLAGS += " -L#{libdir}"
-            $LDFLAGS += " -lq.1 -lcompat.1 -lframe.1 -lrt -liiapi.1"
-        end
-       
-        if RUBY_PLATFORM =~ /solaris/
-            $LDFLAGS += " -lsocket"
-        end
-
-        if have_library('iiapi')
-        else
-            puts "\n\nI couldn't find the Ingres libraries so I didn't create your Makefile.\n"
-            puts "Do you have Ingres installed?\n"
-            puts "Be sure to use the '--with-ingres-include' and '--with-ingres-lib' options.\n"
-            puts "See the first line of extconf.rb for an example.\n\n"
-            puts "BUILD FAILED\n\n"
-            exit
-        end
-
-        if ENV["INGRES_RUBY_DEBUG"] == "Y"
-            $CFLAGS += " -g "
-        end
-    end 
-    create_makefile('Ingres')
-else
-    puts "Unable to find iiapi.h, please verify your setup"
-end
-#do not remove the following line
-#vim: ts=4 sw=4 expandtabs

Copied: drivers/ruby/tags/ingres-ruby-1.3.0/extconf.rb (from rev 130, drivers/ruby/main/extconf.rb)
===================================================================
--- drivers/ruby/tags/ingres-ruby-1.3.0/extconf.rb	                        (rev 0)
+++ drivers/ruby/tags/ingres-ruby-1.3.0/extconf.rb	2008-07-01 18:00:01 UTC (rev 131)
@@ -0,0 +1,67 @@
+# ruby -r mkmf extconf.rb  --with-ingres-include="${II_SYSTEM}/ingres/files/" --with-ingres-lib="${II_SYSTEM}/ingres/lib/"
+
+#
+# if mkmf is not found on your system, install something like ruby1.8-dev
+#
+# May need to modify parameter to both "have_library" statements below
+# depending on operating system and/or version of Ingres.  See NOTEs
+# adjacent to each below.
+#
+require 'mkmf'
+puts "Start extconf.rb"
+dir_config('ingres')
+
+if RUBY_PLATFORM !~ /mswin32/
+    if ENV["II_SYSTEM"]
+        puts "Using II_SYSTEM=#{ENV['II_SYSTEM']}"
+        $CFLAGS += " -I#{ENV["II_SYSTEM"]}/ingres/files"
+    end
+end
+
+if have_header('iiapi.h')
+    if RUBY_PLATFORM =~ /mswin32/
+        if have_library('oiapi','IIapi_initialize') # Check for Ingres 2.6
+            have_library('ingres')
+            puts "Found Ingres 2.6 or earlier.\n"
+        elsif have_library('iilibapi','IIapi_initialize')
+            have_library('libingres')
+            puts "Found Ingres 2006 or later.\n"
+        else
+            puts "\n\nI couldn't find the Ingres libraries so I didn't create your Makefile.\n"
+            puts "Do you have Ingres installed?\n"
+            puts "Be sure to use the '--with-ingres-include' and '--with-ingres-lib' options.\n"
+            puts "See the first line of extconf.rb for an example.\n\n"
+            puts "BUILD FAILED\n\n"
+            exit
+        end
+    else
+        if ENV["II_SYSTEM"]
+            libdir = ENV["II_SYSTEM"] + "/ingres/lib"
+            $LDFLAGS += " -L#{libdir}"
+            $LDFLAGS += " -lq.1 -lcompat.1 -lframe.1 -lrt -liiapi.1"
+        end
+       
+        if RUBY_PLATFORM =~ /solaris/
+            $LDFLAGS += " -lsocket"
+        end
+
+        if have_library('iiapi')
+        else
+            puts "\n\nI couldn't find the Ingres libraries so I didn't create your Makefile.\n"
+            puts "Do you have Ingres installed?\n"
+            puts "Be sure to use the '--with-ingres-include' and '--with-ingres-lib' options.\n"
+            puts "See the first line of extconf.rb for an example.\n\n"
+            puts "BUILD FAILED\n\n"
+            exit
+        end
+
+        if ENV["INGRES_RUBY_DEBUG"] == "Y"
+            $CFLAGS += " -g "
+        end
+    end 
+    create_makefile('Ingres')
+else
+    puts "Unable to find iiapi.h, please verify your setup"
+end
+#do not remove the following line
+#vim: ts=4 sw=4 expandtabs

Deleted: drivers/ruby/tags/ingres-ruby-1.3.0/ingres_adapter.rb
===================================================================
--- drivers/ruby/main/ingres_adapter.rb	2008-06-30 16:18:19 UTC (rev 127)
+++ drivers/ruby/tags/ingres-ruby-1.3.0/ingres_adapter.rb	2008-07-01 18:00:01 UTC (rev 131)
@@ -1,1087 +0,0 @@
-#--
-# Copyright (c) 2007 Ingres Corporation
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 2 as 
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-# ingres_adapter.rb
-#
-# History
-#       12/18/06 (Jared Richardson)
-#           Community developer provided original source 
-#           for Ingres Corp to use as basis for Ruby driver
-#       12/19/07 (grant.croker at ingres.com)
-#           Fix quote() to use the class variable rather than 
-#           the equivalent Ingres column type.   
-#       01/17/08 (grant.croker at ingres.com)
-#           Add GPL License header
-#       06/27/08 (grant.croker at ingres.com)
-#           Add support for Rails Migrations.
-#       06/27/08 (bruce.lunsford at ingres.com)
-#           Add support for Ingres datatypes float4, float8, and money
-#           as AR :float and Ruby Float; previously, Ingres floats
-#           were mapped to AR nil and Ruby String. Remove unneeded/unused
-#           code such as SMALLINT and xxx_simplified_type() methods.
-#           Add mapping for Ingres ANSI date/time formats and change
-#           INGRESDATE (=DATE in pre-ANSI Ingres) mapping from :date to
-#           :datetime.
-#++
-
-
-
-require 'active_record/connection_adapters/abstract_adapter'
-require 'pp'
-
-#debug print routines
-
-PRINT_TRACES = false
-
-def debug_level
-   return 0
-end
-
-def debug_print (msg, context=nil)
-   puts "\nDebug Print::\n"
-   puts msg
-   if context then
-      puts context
-   end
-end
-
-def complete_trace (msg)
-   if(PRINT_TRACES) then
-      puts "\n#{msg}\n"
-   end
-end
-
-
-
-module ActiveRecord
-   class Base
-      # Establishes a connection to the database that's used by all Active Record objects
-      def self.ingres_connection(config) # :nodoc:
-         require_library_or_gem 'Ingres' unless self.class.const_defined?(:Ingres)
-
-         complete_trace("in ingres_connection(config) ")
-
-         ing = Ingres.new
-
-         config = config.symbolize_keys
-
-         if config.has_key?(:database)
-            database = config[:database]
-         else
-            raise ArgumentError, "No database specified. Missing argument: database."
-         end
-
-         if config.has_key?(:username)
-            username = config[:username].to_s
-            password = config[:password].to_s
-            conn = ing.connect_with_credentials(database, username, password)
-         else
-            # ingres allows a local connection w/o username and password
-            conn = ing.connect(database)
-         end
-
-         #return the connection adapter
-         ConnectionAdapters::IngresAdapter.new(conn, logger)
-      end
-   end
-
-   module ConnectionAdapters
-
-      class IngresColumn < Column #:nodoc:
-
-         def value_to_boolean (str)
-
-            if(str.to_i==0)
-               return 0
-            else
-               return 1
-            end
-         end
-
-         def initialize(name, default, sql_type_hash = nil, null = true)
-
-            complete_trace(" in initialize (#{name}, #{default}, #{sql_type_hash.inspect}, #{null})")
-
-            super(name, default, sql_type_hash["column_type"], null)
-
-         end
-
-         def type_cast(value)
-            complete_trace(" in type_cast(#{value}) w/@type=#{@type}")
-
-            return nil if value.nil?
-            case @type
-            when :string    then value
-            when :text      then value
-            when :float     then value.to_f
-            when :binary    then self.class.binary_to_string(value)
-            when :boolean   then self.class.value_to_boolean(value)
-            when :integer   then value.to_i rescue value ? 1 : 0
-            when :datetime  then self.class.string_to_time(value)
-            when :timestamp then self.class.string_to_time(value)
-            when :time      then self.class.string_to_dummy_time(value)
-            when :date
-               res = self.class.string_to_date(value)
-               if(@name =~ /_time$/ ) then
-                  value=value[11,19]
-                  value = "2000-01-01 " << value
-                  #res = self.class.string_to_dummy_time(value)
-                  res = Time.parse(value)
-               else
-                  res = self.class.string_to_date(value)
-               end
-               res
-            else
-               value
-            end
-         end
-
-         def type_cast_code(var_name)
-            complete_trace(" in type_cast_code(#{var_name}) ")
-            case type
-            when :string    then nil
-            when :text      then nil
-            when :integer   then "(#{var_name}.to_i rescue #{var_name} ? 1 : 0)"
-            when :float     then "#{var_name}.to_f"
-            when :datetime  then "#{self.class.name}.string_to_time(#{var_name})"
-            when :timestamp then "#{self.class.name}.string_to_time(#{var_name})"
-            when :time      then "#{self.class.name}.string_to_dummy_time(#{var_name})"
-            when :binary    then "#{self.class.name}.binary_to_string(#{var_name})"
-            when :boolean   then "#{self.class.name}.value_to_boolean(#{var_name})"
-
-            when :date
-               #str = "#{self.class.name}.string_to_date(#{var_name})"
-               str = "if(@name =~ /_time$/ ) then \n"
-               str << " #{var_name}=#{var_name}[11,19] \n"
-               str << " value = '2000-01-01' << #{var_name} \n"
-               str << " res = #{self.class.name}.string_to_time(#{var_name}) \n"
-               str << " else \n"
-               str << " res = #{self.class.name}.string_to_date(#{var_name}) \n"
-               str << " end\n"
-               # puts "\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"
-               # puts ">>#{str}<<"
-
-               str
-            else nil
-            end
-         end
-
-
-         private
-         def simplified_type(field_type)
-            complete_trace(" in simplified_type(#{field_type}) ")
-            case field_type
-            when /INTEGER/
-               :integer
-            when /FLOAT|MONEY/
-               :float
-            when /BOOLEAN/
-               :boolean
-            when /VARCHAR/
-               :string
-            when /CHAR/
-               :string
-            when /ANSIDATE/
-               :date
-            when /DATE|INGRESDATE/
-               :datetime
-            when /TIMESTAMP/
-               :timestamp
-            when /TIME/
-               :time
-            when /INTERVAL/    # No equivalent in Rails
-               :string
-            end
-         end
-      end
-
-
-      # This Ingres adapter works with the Ruby/Ingres driver written
-      # by Jared Richardson
-      #
-      # Options:
-      #
-      # * <tt>:username</tt> - Optional-Defaults to nothing
-      # * <tt>:password</tt> - Optional-Defaults to nothing
-      # * <tt>:database</tt> - The name of the database. No default, must be provided.
-      #
-      # Maintainer: jared at jaredrichardson.net
-      #
-      class IngresAdapter < AbstractAdapter
-         def adapter_name
-            'Ingres'
-         end
-
-         def native_database_types
-            complete_trace(" in native_database_type ")
-            {
-               #:primary_key => "TABLE_KEY NOT NULL with system_maintained",
-               :primary_key => "integer NOT NULL PRIMARY KEY",
-               :string      => { :name => "varchar(255)"},
-               :text        => { :name => "text" },
-               :integer     => { :name => "integer" },
-               :float       => { :name => "float" },
-               :datetime    => { :name => "ingresdate" },
-               :timestamp   => { :name => "timestamp" },
-               :time        => { :name => "time" },
-               :date        => { :name => "ansidate" }, #"date" pre-ansidate
-               :binary      => { :name => "blob" },
-               :boolean     => { :name => "tinyint" }
-            }
-         end
-
-         def get_data_size(id)
-            complete_trace(" in get_data_size(#{id}) ")
-            column_names = @connection.column_list_of_names
-            index = column_names.index(id)
-
-            if(index) then
-               data_sizes = @connection.data_sizes
-               res = data_sizes.at(index)
-            else
-               res = 0
-            end
-            res
-         end
-
-         def supports_migrations?
-            true
-         end
-
-         def prefetch_primary_key?(table_name = nil)
-            true
-         end
-
-         def default_sequence_name(table_name, primary_key) # :nodoc:
-            complete_trace(" in default_sequence_name(#{table_name}, #{primary_key}) ")
-            "#{table_name} #{primary_key}"
-         end
-
-         def next_sequence_value(sequence_name)
-            complete_trace(" in next_sequence_value ")
-
-            ary = sequence_name.split(' ')
-            if (!ary[1]) then
-               ary[0] =~ /(\w+)_nonstd_seq/
-               ary[0] = $1
-               if( ary[1]== nil) then
-                  ary[1]=get_primary_key
-               end
-            end
-
-            # ary[0] is the table name (e.g. ary[0]=topics)
-            # ary[1] is the index column (e.g. ary[1]=id)
-
-            # @connection.unique_row_id(ary[0], ary[1])
-
-            result_set = @connection.execute("select MAX ( #{ary[1]} ) FROM #{ary[0]} ")
-            inner_result_set = result_set[0]
-            max_id = inner_result_set[0]
-            if (max_id==1) then
-               # be sure this isn't an empty table
-               # the code that returns ints can return a 1 if the number is
-               # invalid or undefined. We want to be sure a 1 is really a 1
-               table_count = @connection.execute("select COUNT (*) FROM #{ary[0]} ")
-               table_count_inner_result_set = table_count[0]
-               actual_table_count = table_count_inner_result_set[0]
-               if(actual_table_count == 0) then
-                  # the table is empty. Set the id field to be one
-                  next_value = 1
-               else
-                  # the table isn't empty, which means the MAX id is really 1.
-                  # that means the table has a single entry. We should set the next
-                  # entry to be 2
-                  next_value = 2
-               end
-            else
-               max_id = 0 if max_id == "NULL"
-               next_value = max_id + 1
-            end
-            if (next_value == nil) then
-               puts "\n\n((((((((((((((( next_sequence_value returning nil \n\n"
-            end
-            if (next_value == 0) then
-               puts "\n\n((((((((((((((( next_sequence_value returning 0 \n\n"
-            end
-            return next_value
-         end
-
-
-         # QUOTING ==================================================
-
-         # COMMENT OUT following method for II_DATE_FORMAT=SWEDEN.
-         #def quoted_date(value)
-         # The following line is the original. It's from quoting.rb:
-         #    value.strftime("%Y-%m-%d %H:%M:%S")
-         # This fixed the date/time (US vs SWEDEN in II_DATE_FORMAT) issues -jrr
-         #  value.strftime("%m-%d-%Y %H:%M:%S")
-         #end
-
-         def quote(value, column = nil)
-            complete_trace(" in quote() ")
-            if column
-               complete_trace(" column= name::#{column.name}, @sql_type::#{column.sql_type}, @type=>#{value.class} ")
-            end
-
-            case value
-              when String
-                if column && column.type == :binary && column.class.respond_to?(:string_to_binary)
-                  "'#{@connection.insert_binary(value)}'"
-                else
-                  "'#{quote_string(value)}'"
-                end
-              when TrueClass then '1'
-              when FalseClass then '0'
-              when Fixnum, Bignum then force_numeric?(column) ? value.to_s : "'#{value.to_s}'"
-              when NilClass then "NULL"
-              when Time, DateTime        then "'#{value.strftime("%Y-%m-%d %H:%M:%S")}'"
-              else                       super
-            end
-
-         end
-
-         def force_numeric?(column)
-          (column.nil? || [:integer, :float, :decimal].include?(column.type))
-         end
-
-         # Quotes a string, escaping any ' (single quote) and \ (backslash)
-         # characters.
-         def quote_string(s)
-            complete_trace(" in quote_string(#{s}) ")
-            s.gsub(/'/, "''") # ' (for ruby-mode)
-         end
-
-         def quoted_true
-            "1"
-         end
-
-         def quoted_false
-            "0"
-         end
-
-         def quote_columns(column_name)
-            complete_trace(" in quote_columns(#{column_name})")
-            return column_name
-         end
-
-
-         # DATABASE STATEMENTS ======================================
-
-         # Ingres does not support ALTER TABLE RENAME COL so we have to do it another way
-         #
-         # !!!!Note!!!!
-         # This method only handles tables and primary keys as generated by ActiveRecord
-         # If someone has modified the table structure or added additional indexes these 
-         # will be lost.
-         # TODO - handle secondary indexes and alternate base table structures
-         def rename_column(table_name, column_name, new_column_name) #:nodoc:
-           table_columns = columns(table_name)
-           #Strip the leading :
-           old_column_name = "#{column_name}"
-           no_table_columns = table_columns.size
-           count = 0
-           column_sql = ""
-           table_columns.each do |col|
-             count = count + 1 
-             if col.name == old_column_name then
-               column_sql << " #{col.name} as #{new_column_name}"
-             else
-               column_sql << " #{col.name}"
-             end
-             if (count < no_table_columns) then
-               column_sql << ", " 
-             end
-           end
-           pk_col = get_primary_key(table_name)
-           # Backup the current table renaming the chosen column
-           execute( <<-SQL_COPY, nil)
-             DECLARE GLOBAL TEMPORARY TABLE session.table_copy AS
-               SELECT #{column_sql}
-               FROM #{table_name}
-             ON COMMIT PRESERVE ROWS
-             WITH NORECOVERY
-           SQL_COPY
-
-           #Drop table_name
-           execute( <<-SQL_COPY, nil)
-             DROP TABLE #{table_name}
-           SQL_COPY
-
-           #Re-create table_name based on session.table_copy
-           execute( <<-SQL_COPY, nil)
-             CREATE TABLE #{table_name} AS
-               SELECT * FROM session.table_copy
-           SQL_COPY
-
-           #Add the Primary key back
-           execute( <<-SQL_COPY, nil)
-             ALTER TABLE #{table_name} ADD CONSTRAINT #{table_name[0..4]}_#{pk_col}_pk PRIMARY KEY (#{pk_col})
-           SQL_COPY
-
-           #Drop the GTT session.table_copy
-           execute( <<-SQL_COPY, nil)
-             DROP TABLE session.table_copy
-           SQL_COPY
-         end
-
-         def add_column(table_name, column_name, type, options = {})
-            complete_trace(" in add_column(#{table_name}, #{column_name}, #{type}, #{options}) ")
-
-            add_column_sql = "ALTER TABLE #{table_name} ADD #{column_name} #{type_to_sql(type)}"
-            if( (type.to_s=="string") && (options[:limit]!=nil) ) then
-               add_column_sql.gsub!("varchar(255)", "varchar(#{options[:limit]})")
-               # puts ("\ntype.to_s.class is #{type.to_s.class}")
-            end
-            execute(add_column_sql)
-         end
-
-         # Ingres can limit your number of replies using FIRST N
-         # but it doesn't understand offset.
-         # So I'm storing the values in @limit and ds_dataType at offset and
-         # I'll apply the variables later in apply_limit_and_offset!
-
-         def add_limit_offset!(sql, options) #:nodoc
-            complete_trace(" in add_limit_offset!(#{sql}, #{options}) ")
-            # reset the variables
-            @limit=nil
-            @offset=nil
-            if @limit = options[:limit]
-               unless @offset = options[:offset]
-                  sql.gsub!("SELECT ", "SELECT FIRST #{@limit} ")
-               end
-            end
-         end
-
-         def apply_limit_and_offset!(result_set)
-            complete_trace(" in apply_limit_and_offset!#{result_set}) ")
-            # ingres doesn't have the concept of offset, so I've got to
-            # apply the limit and offset here.
-            # This is a horribly inefficient thing to do.
-            # I'm not tracking the result set and returning a different bit
-            # each time. I'm re-running the entire query.
-            #
-            # Note that just a limit can be applied using the FIRST
-            # and it is in add_limit_offset!
-            #
-            if(1==2) then
-               puts "\n=====----------==========--------=======----\n"
-               puts "\n in apply_limit_and_offset!(result_set) "
-               puts "\n limit=#{@limit} offset=#{@offset}\n"
-               require 'pp'
-               puts "result_set=#{pp result_set}\n"
-               puts "\n=====----------==========--------=======----\n"
-               puts result_set[0]
-               puts result_set[1]
-
-               puts "\n=====----------==========--------=======----\n"
-            end
-            if @offset then
-               if @limit then
-                  # if there's a limit requested, respect it
-                  result_set = result_set[@offset , @limit]
-               else
-                  # otherwise, start at the offset and return the
-                  # rest of the resultset
-                  result_set = result_set[@offset, result_set.size]
-               end
-            end
-            result_set
-         end
-
-
-         def select_all(sql, name = nil) #:nodoc:
-            complete_trace(" in select_all(#{sql}, #{name}) ")
-            execute_with_result_set(sql, name)
-         end
-
-         def select_one(sql, name = nil) #:nodoc:
-            complete_trace(" in select_one(#{sql}, #{name}) ")
-            add_limit_offset!(sql,{:limit => 1})
-            results = select(sql, name)
-            results.first if results
-         end
-
-         def select_rows(sql, name = nil)
-            complete_trace(" in select_rows(#{sql}, #{name}) ")
-            result = select_all(sql, name)
-            rows = []
-            result.each do |row| 
-               rows << row.values_at("version")
-            end
-            rows
-         end
-
-         def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) #:nodoc:
-            complete_trace(" in insert(#{sql}, #{name}, #{pk}, #{id_value}, #{sequence_name}) ")
-            execute(sql, name)
-            update_nulls_after_insert(sql, name, pk, id_value, sequence_name)
-            id_value
-         end
-
-         def exception_str(exc=$!)
-            complete_trace(" in execption_str(#{exc}) ")
-
-            str = ''
-            first = true
-            exc.backtrace.each do |bt|
-               str << (first \
-               ? "#{bt}: #{exc.message} (#{exc.class})\n" \
-               : "\tfrom #{bt}\n")
-               first = false
-            end
-            str
-         end
-
-         def print_exception(exc=$!, out=$stdout)
-            out.puts exception_str(exc)
-         end
-
-
-         def my_print_exception(msg)
-            begin
-               raise msg
-            rescue
-               print_exception()
-            end
-         end
-
-
-         def update(sql, name = nil) #:nodoc:
-            complete_trace(" in update(#{sql}, #{name}) ")
-            execute(sql, name)
-            return @connection.rows_affected
-         end
-
-         def delete(sql, name = nil) #:nodoc:
-            complete_trace(" in delete(#{sql}, #{name} ")
-            execute(sql, name)
-            return @connection.rows_affected
-         end
-
-
-         def execute(sql, name = nil) #:nodoc:
-            complete_trace(" in execute(#{sql}, #{name}) ")
-
-            # debug print
-            if(1==2) then
-               bad_sql = "auto_id_tests"
-               if(sql.include?bad_sql) then
-                  my_print_exception(bad_sql)
-               end
-            end
-
-            sql = add_ordering(sql)
-            #sql = sql.gsub("\n", "\\n")
-
-            begin
-               result = log(sql, name) { @connection.execute(sql) }
-            rescue
-               puts "\nAn error occurred!\n"
-               print_exception()
-            end
-            return result
-         end
-
-         def execute_with_result_set(sql, name = nil) #:nodoc:
-            complete_trace(" in execute_with_result_set(#{sql}, #{name}) ")
-
-            sql = add_ordering(sql)
-            rows = execute_without_adding_ordering(sql)
-            return rows
-         end
-
-         def execute_without_adding_ordering(sql, name=nil)
-            complete_trace(" in execute_without_adding_ordering(#{sql}, #{name}) ")
-
-            # TODO: clean up this hack
-            sql.gsub!(" = NULL", " is NULL")
-
-            # debug print
-            if(1==2) then
-               bad_sql = "auto_id_tests"
-               if(sql.include?bad_sql) then
-                  my_print_exception(bad_sql)
-               end
-            end
-
-            begin
-               rs = log(sql, name) { @connection.execute(sql) }
-            rescue
-               puts "\nAn error occurred!\n"
-               print_exception()
-            end
-            col_names = @connection.column_list_of_names
-            data_type = @connection.data_types
-
-            rows=[]
-            rs.each do |row|
-               index = 0
-               this_column = Hash.new
-               row.each do |item |
-
-                  col_name = col_names[index].rstrip
-                  col_val = item.to_s.rstrip
-
-                  if (col_val=="NULL") then
-                     col_val = nil
-                  end
-                  this_column[ col_name] = col_val
-                  index += 1
-               end
-               rows << this_column
-               index = 0
-            end
-            if(@offset) then
-               rows = apply_limit_and_offset!(rows)
-            end
-
-            # debug print block
-            if(1==2) then
-               puts "\n=============\n"
-               puts "the result set is:\n"
-               pp rows
-               puts "\n=============\n"
-            end
-
-            if(1==2 && rows[0] && rows[0].values_at("content")==["--- \n- one\n- two\n- three"]) then
-               # h = rows[0]
-               # h.delete("content")
-               # h.store("content", "--- \n- one\n- two\n- three\n")
-               # rows[0] = h
-            end
-
-            return rows
-         end
-
-
-         # I'm redefining the remove_index routine here.
-         # The original is in schema_statements.rb
-
-         def remove_index(table_name, options = {})
-            complete_trace(" in remove_index(#{table_name}, #{options}) ")
-            execute "DROP INDEX #{index_name(table_name, options)}"
-         end
-
-         alias_method :delete, :update #:nodoc:
-         #=begin
-         def begin_db_transaction #:nodoc:
-            execute "START TRANSACTION"
-         rescue Exception
-            # Transactions aren't supported
-         end
-
-         def commit_db_transaction #:nodoc:
-            execute("COMMIT")
-         rescue Exception
-            # Transactions aren't supported
-         end
-
-         def rollback_db_transaction #:nodoc:
-            execute "ROLLBACK"
-         rescue Exception
-            # Transactions aren't supported
-         end
-         #=end
-
-         # SCHEMA STATEMENTS ========================================
-
-         # Create an Ingres database
-         def create_database(name, options = {})
-           #`createdb #{name} -i -fnofeclients`
-         end
-
-         # Drops an Ingres database
-         def drop_database(name) #:nodoc:
-           #`destroydb #{name}`
-         end
-
-         # Return the list of all tables in the schema search path.
-         def tables(name = nil) #:nodoc:
-            complete_trace(" in tables(#{name}) ")
-            tables = @connection.tables
-            #tables.reject! { |t| /\A_SYS_/ === t }
-            tables
-         end
-
-         def columns(table_name, name = nil) #:nodoc:
-            complete_trace(" in columns(#{table_name}, #{name}) ")
-
-            sql = "SELECT column_name, column_default_val, column_datatype, column_length FROM iicolumns  "
-            sql << "WHERE table_name='#{table_name}' "
-            sql << "ORDER BY column_sequence "
-            columns = []
-            select_all(sql, name).each do |row|
-               default_value = default_value( row["column_default_val"])
-               column_type = sql_type_name( row["column_datatype"], row["column_length"])
-
-               if (1==2) then
-                  puts "\n---\n"
-                  puts row["column_name"]
-                  puts default_value
-                  puts column_type
-               end
-               data_size = get_data_size(row["column_name"])
-
-               complete_trace ("-----------------------")
-               complete_trace ("row['column_name']=#{row["column_name"]}")
-               complete_trace ("default_value=#{default_value}")
-               complete_trace ("column_type=#{column_type}"      )
-               complete_trace ("data_size=#{data_size}"  )
-               complete_trace ("-----------------------")
-
-               column_type_hash = { "data_size" => data_size, "column_type" => column_type}
-
-               columns << IngresColumn.new(row["column_name"],
-               default_value,
-               column_type_hash,
-               row["notnull"]
-               )
-            end
-            columns
-         end
-
-         def get_ordering_field(table_name)
-            field = get_primary_key(table_name)
-            if(!field) then
-               # fetch some field from the table (or sql) to order
-               # if need be, fetch another field here to order by...
-               # get a list of all fields that are indexed (key_sequence !=0)
-               sql = "SELECT column_name, column_length FROM iicolumns WHERE table_name = '#{table_name}' AND key_sequence != 0 ORDER BY column_name"
-               result_set = execute_without_adding_ordering(sql)
-
-               if(result_set==nil || result_set==[]) then
-
-                  field = nil
-                  # didn't get a hit... cast a broader net and just pick a table
-                  sql = "SELECT column_name, column_length FROM iicolumns WHERE table_name = '#{table_name}' ORDER BY column_name"
-                  result_set = execute_without_adding_ordering(sql)
-
-               else
-                  # now verify that our field is in the result set
-
-                  # breakpoint =-==
-                  # TODO: finish this!
-                  # result_set.flatten.include?(
-
-
-               end
-               if(!field) then
-                  # just take the first field name we see.
-                  # this table has no primary key and no indexes
-                  # we need some sort of ordering to be consistent, so we're using the
-                  # first table we see, alphabetically
-                  begin
-                     if(result_set == [] || result_set ==nil) then
-                        field = nil
-                     else
-                        field  = result_set[0][0]
-                     end
-                  rescue
-                     breakpoint
-                     field = nil
-                  end
-               end
-            else
-               # should we validate that this field exists in the table we are executing against
-               # if it doesn't, pick a replacement
-            end
-
-            return field
-         end
-
-         def get_primary_key(table_name)
-            complete_trace(" in get_primary_key(#{table_name} ")
-            indexes(table_name)
-            return @primary_key
-         end
-
-         def indexes(table_name, name = nil)#:nodoc:
-            complete_trace(" in indexes(#{table_name}, #{name}) ")
-            @primary_key = nil
-            sql =  "SELECT base_name, index_name, unique_rule "
-            sql <<    "FROM "
-            sql <<    "iiindexes "
-            sql <<    "WHERE  "
-            sql <<    "base_name = '#{table_name}' "
-
-            indexes = []
-            result_set = execute_without_adding_ordering(sql, name)
-
-            if(result_set) then
-               result_set.each do | column |
-                  base_name  = column.values_at("base_name")[0]
-                  index_name = column.values_at("index_name")[0]
-                  unique_rule =column.values_at("unique_rule")[0]=='U'
-                  column_name = column.values_at("column_name")[0]
-
-                  # get a copy of the  primary index
-                  # Ingres uses the first 5 characters of a table name for the primary key index
-                  if table_name.length < 5 then
-                    short_name = table_name
-                  else
-                    short_name = table_name[0..4]
-                  end
-                  if (index_name.starts_with?("$#{short_name}")) then
-                    # we have the name of the pointer to the index
-                    # now let's fetch the actual name of the primary key
-                    sql2="select column_name from iiindex_columns where index_name='#{index_name}'"
-                    result_set_2 = execute_without_adding_ordering(sql2)
-                    @primary_key = result_set_2[0].fetch('column_name')
-                  end
-
-                  # ignore any index with a $pk or ii prefix. It's a system index
-                  prefix1 = "$#{short_name}"
-                  prefix2 = "ii"
-                  if ( (index_name.starts_with?(prefix1)) || (index_name.starts_with?(prefix2)) ) then
-                     #puts "\nSkipping #{index_name}\n"
-                  else
-                     #puts "\nAdding >>#{index_name}<<\n"
-
-                     # now fetch the column names and store them in an Array
-                     column_names = []
-                     sql = "SELECT column_name from iiindex_columns "
-                     sql << " WHERE index_name = '#{index_name}' "
-                     rs2 = execute_without_adding_ordering(sql, name)
-                     rs2.each do | col2 |
-                        this_col_name = col2.values_at("column_name").first
-                        column_names << this_col_name
-                     end
-                     # class IndexDefinition < Struct.new(:table, :name, :unique, :columns) #:nodoc:
-                     indexes << IndexDefinition.new( table_name, index_name, unique_rule, column_names)
-                     complete_trace( "Just created an index with (#{table_name}, #{index_name}, #{unique_rule}, #{column_names})\n")
-                  end
-               end
-            end
-            indexes
-         end
-
-
-         private
-         def select(sql, name = nil)
-            complete_trace(" in select(#{sql}, #{name}) ")
-
-            sql = translate_sql(sql)
-            results = execute_with_result_set(sql, name)
-
-            rows = []
-            counter = 0
-            if ( @connection.rows_affected )
-               results.each do |row|  # loop through result rows
-                  hashed_row = {}
-
-                  row.each_pair do |key, value|
-                     hashed_row[key] = value unless key == "id"
-                  end
-                  rows << hashed_row
-               end
-            end
-            if(1==2) then
-               puts "rows.class=#{rows.class}\n"
-               puts "\n\n rows is: \n"
-               rows.each { |x| x.each {|y| puts y } }
-            end
-
-            rows
-         end
-
-         def default_value(value)
-            complete_trace(" in default_value#{value}) ")
-            # Empty strings should be set to null
-            return nil if value == nil
-            return nil if value.empty?
-
-            # Boolean type values
-            return true if value =~ /true/
-            return false if value =~ /false/
-
-            # Date / Time magic values
-            # return Time.now.to_s if value =~ /^now\(\)/i
-
-            # Otherwise return what we got from the database
-            # and hope for the best..
-            complete_trace(" Exiting default_value... defaulting to #{value}) ")
-            return value
-         end
-
-         def sql_type_name(type_name, length)
-            complete_trace(" in sql_type_name(#{type_name}, #{length}) ")
-            if(2==3) then
-               puts "\n In sql_type_name \n"
-               puts "\n-------------\n"
-               puts "type_name=#{type_name} and length=(#{length})"
-               puts "\n-------------\n"
-            end
-
-            if( (type_name=="INTEGER") && (length.to_s=="1") ) then
-               return "BOOLEAN"
-            end
-
-
-            #if(type_name=="VARCHAR" && length==255)
-            if(2==3)
-               then
-                  my_print_exception("in sql_type_name")
-               end
-               return "#{type_name}(#{length})" if ( type_name =~ /char/ )
-               type_name
-            end
-
-            def ingres_index_name(row = [])
-               complete_trace(" in ingres_index_name#{row}) ")
-
-               name = ""
-               name << "UNIQUE " if row[3]
-               name << "CLUSTERED " if row[4]
-               name << "INDEX"
-               name
-            end
-
-            def translate_sql(sql)
-               complete_trace(" in translate_sql(#{sql}) ")
-               # Change table.* to list of columns in table
-               while (sql =~ /SELECT.*\s(\w+)\.\*/)
-                  table = $1
-                  cols = columns(table)
-                  if ( cols.size == 0 ) then
-                     # Maybe this is a table alias
-                     sql =~ /FROM(.+?)(?:LEFT|OUTER|JOIN|WHERE|GROUP|HAVING|ORDER|RETURN|$)/
-                     $1 =~ /[\s|,](\w+)\s+#{table}[\s|,]/ # get the tablename for this alias
-                     cols = columns($1)
-                  end
-                  select_columns = []
-                  cols.each do |col|
-                     select_columns << table + '.' + col.name
-                  end
-                  sql.gsub!(table + '.*',select_columns.join(", ")) if select_columns
-               end
-
-               # Change JOIN clause to table list and WHERE condition
-
-               while (sql =~ /JOIN/)
-                  sql =~ /((LEFT )?(OUTER )?JOIN (\w+) ON )(.+?)(?:LEFT|OUTER|JOIN|WHERE|GROUP|HAVING|ORDER|RETURN|$)/
-                  join_clause = $1 + $5
-                  is_outer_join = $3
-                  join_table = $4
-                  join_condition = $5
-                  #join_condition.gsub!(/=/,"*") if is_outer_join
-                  if (sql =~ /WHERE/)
-                     sql.gsub!(/WHERE/,"WHERE (#{join_condition}) AND")
-                  else
-                     sql.gsub!(join_clause,"#{join_clause} WHERE #{join_condition}")
-                  end
-                  sql =~ /(FROM .+?)(?:LEFT|OUTER|JOIN|WHERE|$)/
-                  from_clause = $1
-                  sql.gsub!(from_clause,"#{from_clause}, #{join_table} ")
-                  sql.gsub!(join_clause,"")
-               end
-               sql = add_ordering(sql)
-               sql
-            end
-
-            # Ingres tends to return data in a different format depending
-            # on what queries were previously run, so we need to explicitly
-            # order all selects
-
-            def add_ordering (sql)
-               complete_trace(" in add_ordering(#{sql}) ")
-               if(sql !~ /(SELECT)|(select)/)
-                  return sql
-               end
-
-               # extract the next word after FROM... it's the table name
-               from_stmnt = sql.scan(/(FROM \w+)|(from \w+)/)
-               table_array = from_stmnt.to_s.scan(/\w+/)
-               table_name = table_array[1]
-
-               ordering_field = get_ordering_field(table_name)
-               if(ordering_field==nil) then
-                  return sql
-               end
-
-               # ORDER BY ordering_field if no explicit ORDER BY
-               # This will ensure that find(:first) returns the first inserted row
-               # or at least the same value every time
-               sql_original = sql
-               sql_temp = sql
-               if(sql_temp =~ /(SELECT)/) then
-                  if (sql_temp.upcase !~ /(COUNT)|(MAX)|(MIN)|(AVG)|(ANY)|(SUM)|(TRANSACTION)|(ROLLBACK)|(COMMIT)|(JOIN)/) then
-                     if (sql_temp !~ /(ORDER BY)|(GROUP BY)/)
-                        if (sql =~ /RETURN RESULTS 1/)
-                           sql.sub!(/RETURN RESULTS 1/,"ORDER BY #{ordering_field}")
-                           #sql.sub!(/RETURN RESULTS 1/," ")
-                        else
-                           sql << " ORDER BY #{ordering_field}"
-                        end
-                        # Ingres requires that anything you order by be in the select
-                        # TODO: ADDRESS CASE ISSUES
-                        if (sql =~ /(#{ordering_field})/ ) then
-
-                           # the original query didn't have an ID in it. Let's add one
-                           # unless it's already got a "SELECT *"
-                           if (sql !~ /(FIRST)/) then
-                              # insert ordering_field into the select list
-                              found_select_star = sql.gsub("SELECT *", "I found it!")
-                              # TODO: Is this right? It reads backwards (if it's working)
-                              # retool to read properly -jrr
-                              if (sql==found_select_star) then
-                                 sql.gsub!("SELECT", "SELECT #{ordering_field}, ")
-                              end
-                           else
-                              # we have a query with a "FIRST N" in it.
-                              # ID needs to go after the first.
-                              # example: "SELECT FIRST 7 id, name from COMPANIES.... "
-
-                              # skip the replacement if the select has a * in it
-                              found_select_star = sql.gsub("*", "I found it!")
-                              if (sql==found_select_star) then
-                                 sql.gsub!( /(FIRST \d+ )/, '\1 #{ordering_field}, ')
-                              end
-                           end
-                        end
-                     end
-                  end
-               end
-               #puts "\n sql coming exiting is:\n#{sql}\n\n"
-               sql
-            end
-
-            def update_nulls_after_insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
-               complete_trace(" in update_nulls_after_insert( #{sql}, #{name}, #{pk}, #{id_value}, #{sequence_name}) ")
-               # TODO: is this okay? :(
-
-               if(1) then return end
-               puts "\n In update_nulls_after_insert\n"
-
-               sql =~ /INSERT INTO (\w+) \((.*)\) VALUES\s*\((.*)\)/m
-               table = $1
-               cols = $2
-               values = $3
-               cols = cols.split(',')
-               values.gsub!(/'[^']*'/,"''")
-               values.gsub!(/"[^"]*"/,"\"\"")
-               values = values.split(',')
-               update_cols = []
-               values.each_index { |index| update_cols << cols[index] if values[index] =~ /\s*NULL\s*/ }
-               update_sql = "UPDATE #{table} SET"
-               update_cols.each { |col| update_sql << " #{col}=NULL," unless col.empty? }
-               update_sql.chop!()
-               update_sql << " WHERE #{pk}=#{quote(id_value)}"
-               execute(update_sql, name + " NULL Correction") if update_cols.size > 0
-            end
-         end
-      end
-   end
-
-#vim: ts=2 sw=2 expandtab

Copied: drivers/ruby/tags/ingres-ruby-1.3.0/ingres_adapter.rb (from rev 128, drivers/ruby/main/ingres_adapter.rb)
===================================================================
--- drivers/ruby/tags/ingres-ruby-1.3.0/ingres_adapter.rb	                        (rev 0)
+++ drivers/ruby/tags/ingres-ruby-1.3.0/ingres_adapter.rb	2008-07-01 18:00:01 UTC (rev 131)
@@ -0,0 +1,1095 @@
+#--
+# Copyright (c) 2007 Ingres Corporation
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as 
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+# ingres_adapter.rb
+#
+# History
+#       12/18/06 (Jared Richardson)
+#           Community developer provided original source 
+#           for Ingres Corp to use as basis for Ruby driver
+#       12/19/07 (grant.croker at ingres.com)
+#           Fix quote() to use the class variable rather than 
+#           the equivalent Ingres column type.   
+#       01/17/08 (grant.croker at ingres.com)
+#           Add GPL License header
+#       06/27/08 (grant.croker at ingres.com)
+#           Add support for Rails Migrations.
+#       06/27/08 (bruce.lunsford at ingres.com)
+#           Add support for Ingres datatypes float4, float8, and money
+#           as AR :float and Ruby Float; previously, Ingres floats
+#           were mapped to AR nil and Ruby String. Remove unneeded/unused
+#           code such as SMALLINT and xxx_simplified_type() methods.
+#           Add mapping for Ingres ANSI date/time formats and change
+#           INGRESDATE (=DATE in pre-ANSI Ingres) mapping from :date to
+#           :datetime.
+#       07/02/08 (grant.croker at ingres.com)
+#           Add quote_column_names() for quoting of table and column names. 
+#           Required for the ActiveRecord base unit tests
+#       07/02/08 (grant.croker at ingres.com)
+#           Fix data truncation for the ActiveRecord :text type
+#++
+
+
+
+require 'active_record/connection_adapters/abstract_adapter'
+require 'pp'
+
+#debug print routines
+
+PRINT_TRACES = false
+
+def debug_level
+   return 0
+end
+
+def debug_print (msg, context=nil)
+   puts "\nDebug Print::\n"
+   puts msg
+   if context then
+      puts context
+   end
+end
+
+def complete_trace (msg)
+   if(PRINT_TRACES) then
+      puts "\n#{msg}\n"
+   end
+end
+
+
+
+module ActiveRecord
+   class Base
+      # Establishes a connection to the database that's used by all Active Record objects
+      def self.ingres_connection(config) # :nodoc:
+         require_library_or_gem 'Ingres' unless self.class.const_defined?(:Ingres)
+
+         complete_trace("in ingres_connection(config) ")
+
+         ing = Ingres.new
+
+         config = config.symbolize_keys
+
+         if config.has_key?(:database)
+            database = config[:database]
+         else
+            raise ArgumentError, "No database specified. Missing argument: database."
+         end
+
+         if config.has_key?(:username)
+            username = config[:username].to_s
+            password = config[:password].to_s
+            conn = ing.connect_with_credentials(database, username, password)
+         else
+            # ingres allows a local connection w/o username and password
+            conn = ing.connect(database)
+         end
+
+         #return the connection adapter
+         ConnectionAdapters::IngresAdapter.new(conn, logger)
+      end
+   end
+
+   module ConnectionAdapters
+
+      class IngresColumn < Column #:nodoc:
+
+         def value_to_boolean (str)
+
+            if(str.to_i==0)
+               return 0
+            else
+               return 1
+            end
+         end
+
+         def initialize(name, default, sql_type_hash = nil, null = true)
+
+            complete_trace(" in initialize (#{name}, #{default}, #{sql_type_hash.inspect}, #{null})")
+
+            super(name, default, sql_type_hash["column_type"], null)
+
+         end
+
+         def type_cast(value)
+            complete_trace(" in type_cast(#{value}) w/@type=#{@type}")
+
+            return nil if value.nil?
+            case @type
+            when :string    then value
+            when :text      then value
+            when :float     then value.to_f
+            when :binary    then self.class.binary_to_string(value)
+            when :boolean   then self.class.value_to_boolean(value)
+            when :integer   then value.to_i rescue value ? 1 : 0
+            when :datetime  then self.class.string_to_time(value)
+            when :timestamp then self.class.string_to_time(value)
+            when :time      then self.class.string_to_dummy_time(value)
+            when :date
+               res = self.class.string_to_date(value)
+               if(@name =~ /_time$/ ) then
+                  value=value[11,19]
+                  value = "2000-01-01 " << value
+                  #res = self.class.string_to_dummy_time(value)
+                  res = Time.parse(value)
+               else
+                  res = self.class.string_to_date(value)
+               end
+               res
+            else
+               value
+            end
+         end
+
+         def type_cast_code(var_name)
+            complete_trace(" in type_cast_code(#{var_name}) ")
+            case type
+            when :string    then nil
+            when :text      then nil
+            when :integer   then "(#{var_name}.to_i rescue #{var_name} ? 1 : 0)"
+            when :float     then "#{var_name}.to_f"
+            when :datetime  then "#{self.class.name}.string_to_time(#{var_name})"
+            when :timestamp then "#{self.class.name}.string_to_time(#{var_name})"
+            when :time      then "#{self.class.name}.string_to_dummy_time(#{var_name})"
+            when :binary    then "#{self.class.name}.binary_to_string(#{var_name})"
+            when :boolean   then "#{self.class.name}.value_to_boolean(#{var_name})"
+
+            when :date
+               #str = "#{self.class.name}.string_to_date(#{var_name})"
+               str = "if(@name =~ /_time$/ ) then \n"
+               str << " #{var_name}=#{var_name}[11,19] \n"
+               str << " value = '2000-01-01' << #{var_name} \n"
+               str << " res = #{self.class.name}.string_to_time(#{var_name}) \n"
+               str << " else \n"
+               str << " res = #{self.class.name}.string_to_date(#{var_name}) \n"
+               str << " end\n"
+               # puts "\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"
+               # puts ">>#{str}<<"
+
+               str
+            else nil
+            end
+         end
+
+
+         private
+         def simplified_type(field_type)
+            complete_trace(" in simplified_type(#{field_type}) ")
+            case field_type
+            when /INTEGER/
+               :integer
+            when /FLOAT|MONEY/
+               :float
+            when /BOOLEAN/
+               :boolean
+            when /VARCHAR/
+               :string
+            when /CHAR/
+               :string
+            when /ANSIDATE/
+               :date
+            when /DATE|INGRESDATE/
+               :datetime
+            when /TIMESTAMP/
+               :timestamp
+            when /TIME/
+               :time
+            when /INTERVAL/    # No equivalent in Rails
+               :string
+            end
+         end
+      end
+
+
+      # This Ingres adapter works with the Ruby/Ingres driver written
+      # by Jared Richardson
+      #
+      # Options:
+      #
+      # * <tt>:username</tt> - Optional-Defaults to nothing
+      # * <tt>:password</tt> - Optional-Defaults to nothing
+      # * <tt>:database</tt> - The name of the database. No default, must be provided.
+      #
+      # Maintainer: jared at jaredrichardson.net
+      #
+      class IngresAdapter < AbstractAdapter
+         def adapter_name
+            'Ingres'
+         end
+
+         def native_database_types
+            complete_trace(" in native_database_type ")
+            {
+               :primary_key => "integer NOT NULL PRIMARY KEY",
+               :string      => { :name => "varchar", :limit => 255 },
+               :text        => { :name => "varchar", :limit => 32000 },
+               :integer     => { :name => "integer" },
+               :float       => { :name => "float" },
+               :datetime    => { :name => "ingresdate" },
+               :timestamp   => { :name => "timestamp" },
+               :time        => { :name => "time" },
+               :date        => { :name => "ansidate" }, #"date" pre-ansidate
+               :binary      => { :name => "blob" },
+               :boolean     => { :name => "tinyint" }
+            }
+         end
+
+         def get_data_size(id)
+            complete_trace(" in get_data_size(#{id}) ")
+            column_names = @connection.column_list_of_names
+            index = column_names.index(id)
+
+            if(index) then
+               data_sizes = @connection.data_sizes
+               res = data_sizes.at(index)
+            else
+               res = 0
+            end
+            res
+         end
+
+         def supports_migrations?
+            true
+         end
+
+         def prefetch_primary_key?(table_name = nil)
+            true
+         end
+
+         def default_sequence_name(table_name, primary_key) # :nodoc:
+            complete_trace(" in default_sequence_name(#{table_name}, #{primary_key}) ")
+            "#{table_name} #{primary_key}"
+         end
+
+         def next_sequence_value(sequence_name)
+            complete_trace(" in next_sequence_value ")
+
+            ary = sequence_name.split(' ')
+            if (!ary[1]) then
+               ary[0] =~ /(\w+)_nonstd_seq/
+               ary[0] = $1
+               if( ary[1]== nil) then
+                  ary[1]=get_primary_key
+               end
+            end
+
+            # ary[0] is the table name (e.g. ary[0]=topics)
+            # ary[1] is the index column (e.g. ary[1]=id)
+
+            # @connection.unique_row_id(ary[0], ary[1])
+
+            result_set = @connection.execute("select MAX ( #{ary[1]} ) FROM #{ary[0]} ")
+            inner_result_set = result_set[0]
+            max_id = inner_result_set[0]
+            if (max_id==1) then
+               # be sure this isn't an empty table
+               # the code that returns ints can return a 1 if the number is
+               # invalid or undefined. We want to be sure a 1 is really a 1
+               table_count = @connection.execute("select COUNT (*) FROM #{ary[0]} ")
+               table_count_inner_result_set = table_count[0]
+               actual_table_count = table_count_inner_result_set[0]
+               if(actual_table_count == 0) then
+                  # the table is empty. Set the id field to be one
+                  next_value = 1
+               else
+                  # the table isn't empty, which means the MAX id is really 1.
+                  # that means the table has a single entry. We should set the next
+                  # entry to be 2
+                  next_value = 2
+               end
+            else
+               max_id = 0 if max_id == "NULL"
+               next_value = max_id + 1
+            end
+            if (next_value == nil) then
+               puts "\n\n((((((((((((((( next_sequence_value returning nil \n\n"
+            end
+            if (next_value == 0) then
+               puts "\n\n((((((((((((((( next_sequence_value returning 0 \n\n"
+            end
+            return next_value
+         end
+
+
+         # QUOTING ==================================================
+
+         # COMMENT OUT following method for II_DATE_FORMAT=SWEDEN.
+         #def quoted_date(value)
+         # The following line is the original. It's from quoting.rb:
+         #    value.strftime("%Y-%m-%d %H:%M:%S")
+         # This fixed the date/time (US vs SWEDEN in II_DATE_FORMAT) issues -jrr
+         #  value.strftime("%m-%d-%Y %H:%M:%S")
+         #end
+
+         def quote(value, column = nil)
+            complete_trace(" in quote() ")
+            if column
+               complete_trace(" column= name::#{column.name}, @sql_type::#{column.sql_type}, @type=>#{value.class} ")
+            end
+
+            case value
+              when String
+                if column && column.type == :binary && column.class.respond_to?(:string_to_binary)
+                  "'#{@connection.insert_binary(value)}'"
+                else
+                  "'#{quote_string(value)}'"
+                end
+              when TrueClass then '1'
+              when FalseClass then '0'
+              when Fixnum, Bignum then force_numeric?(column) ? value.to_s : "'#{value.to_s}'"
+              when NilClass then "NULL"
+              when Time, DateTime        then "'#{value.strftime("%Y-%m-%d %H:%M:%S")}'"
+              else                       super
+            end
+
+         end
+
+         def force_numeric?(column)
+          (column.nil? || [:integer, :float, :decimal].include?(column.type))
+         end
+
+         # Quotes a string, escaping any ' (single quote) and \ (backslash)
+         # characters.
+         def quote_string(s)
+            complete_trace(" in quote_string(#{s}) ")
+            s.gsub(/'/, "''") # ' (for ruby-mode)
+         end
+
+         def quoted_true
+            "1"
+         end
+
+         def quoted_false
+            "0"
+         end
+
+         def quote_columns(column_name)
+            complete_trace(" in quote_columns(#{column_name})")
+            return column_name
+         end
+
+         # Quotes column names for use in SQL queries.
+         def quote_column_name(name) #:nodoc:
+            %("#{name}")
+         end
+
+         # DATABASE STATEMENTS ======================================
+
+         # Ingres does not support ALTER TABLE RENAME COL so we have to do it another way
+         #
+         # !!!!Note!!!!
+         # This method only handles tables and primary keys as generated by ActiveRecord
+         # If someone has modified the table structure or added additional indexes these 
+         # will be lost.
+         # TODO - handle secondary indexes and alternate base table structures
+         def rename_column(table_name, column_name, new_column_name) #:nodoc:
+           table_columns = columns(table_name)
+           #Strip the leading :
+           old_column_name = "#{column_name}"
+           no_table_columns = table_columns.size
+           count = 0
+           column_sql = ""
+           table_columns.each do |col|
+             count = count + 1 
+             if col.name == old_column_name then
+               column_sql << " #{col.name} as #{new_column_name}"
+             else
+               column_sql << " #{col.name}"
+             end
+             if (count < no_table_columns) then
+               column_sql << ", " 
+             end
+           end
+           pk_col = get_primary_key(table_name)
+           # Backup the current table renaming the chosen column
+           execute( <<-SQL_COPY, nil)
+             DECLARE GLOBAL TEMPORARY TABLE session.table_copy AS
+               SELECT #{column_sql}
+               FROM #{table_name}
+             ON COMMIT PRESERVE ROWS
+             WITH NORECOVERY
+           SQL_COPY
+
+           #Drop table_name
+           execute( <<-SQL_COPY, nil)
+             DROP TABLE #{table_name}
+           SQL_COPY
+
+           #Re-create table_name based on session.table_copy
+           execute( <<-SQL_COPY, nil)
+             CREATE TABLE #{table_name} AS
+               SELECT * FROM session.table_copy
+           SQL_COPY
+
+           #Add the Primary key back
+           execute( <<-SQL_COPY, nil)
+             ALTER TABLE #{table_name} ADD CONSTRAINT #{table_name[0..4]}_#{pk_col}_pk PRIMARY KEY (#{pk_col})
+           SQL_COPY
+
+           #Drop the GTT session.table_copy
+           execute( <<-SQL_COPY, nil)
+             DROP TABLE session.table_copy
+           SQL_COPY
+         end
+
+         def add_column(table_name, column_name, type, options = {})
+            complete_trace(" in add_column(#{table_name}, #{column_name}, #{type}, #{options}) ")
+
+            add_column_sql = "ALTER TABLE #{table_name} ADD #{column_name} #{type_to_sql(type)}"
+            if( (type.to_s=="string") && (options[:limit]!=nil) ) then
+               add_column_sql.gsub!("varchar(255)", "varchar(#{options[:limit]})")
+               # puts ("\ntype.to_s.class is #{type.to_s.class}")
+            end
+            execute(add_column_sql)
+         end
+
+         # Ingres can limit your number of replies using FIRST N
+         # but it doesn't understand offset.
+         # So I'm storing the values in @limit and ds_dataType at offset and
+         # I'll apply the variables later in apply_limit_and_offset!
+
+         def add_limit_offset!(sql, options) #:nodoc
+            complete_trace(" in add_limit_offset!(#{sql}, #{options}) ")
+            # reset the variables
+            @limit=nil
+            @offset=nil
+            if @limit = options[:limit]
+               unless @offset = options[:offset]
+                  sql.gsub!("SELECT ", "SELECT FIRST #{@limit} ")
+               end
+            end
+         end
+
+         def apply_limit_and_offset!(result_set)
+            complete_trace(" in apply_limit_and_offset!#{result_set}) ")
+            # ingres doesn't have the concept of offset, so I've got to
+            # apply the limit and offset here.
+            # This is a horribly inefficient thing to do.
+            # I'm not tracking the result set and returning a different bit
+            # each time. I'm re-running the entire query.
+            #
+            # Note that just a limit can be applied using the FIRST
+            # and it is in add_limit_offset!
+            #
+            if(1==2) then
+               puts "\n=====----------==========--------=======----\n"
+               puts "\n in apply_limit_and_offset!(result_set) "
+               puts "\n limit=#{@limit} offset=#{@offset}\n"
+               require 'pp'
+               puts "result_set=#{pp result_set}\n"
+               puts "\n=====----------==========--------=======----\n"
+               puts result_set[0]
+               puts result_set[1]
+
+               puts "\n=====----------==========--------=======----\n"
+            end
+            if @offset then
+               if @limit then
+                  # if there's a limit requested, respect it
+                  result_set = result_set[@offset , @limit]
+               else
+                  # otherwise, start at the offset and return the
+                  # rest of the resultset
+                  result_set = result_set[@offset, result_set.size]
+               end
+            end
+            result_set
+         end
+
+
+         def select_all(sql, name = nil) #:nodoc:
+            complete_trace(" in select_all(#{sql}, #{name}) ")
+            execute_with_result_set(sql, name)
+         end
+
+         def select_one(sql, name = nil) #:nodoc:
+            complete_trace(" in select_one(#{sql}, #{name}) ")
+            add_limit_offset!(sql,{:limit => 1})
+            results = select(sql, name)
+            results.first if results
+         end
+
+         def select_rows(sql, name = nil)
+            complete_trace(" in select_rows(#{sql}, #{name}) ")
+            result = select_all(sql, name)
+            rows = []
+            result.each do |row| 
+               rows << row.values_at("version")
+            end
+            rows
+         end
+
+         def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) #:nodoc:
+            complete_trace(" in insert(#{sql}, #{name}, #{pk}, #{id_value}, #{sequence_name}) ")
+            execute(sql, name)
+            update_nulls_after_insert(sql, name, pk, id_value, sequence_name)
+            id_value
+         end
+
+