<docbook><section><title>IODBCRubyHOWTO</title><title>iODBC and Ruby</title>iODBC and Ruby
<bridgehead class="http://www.w3.org/1999/xhtml:h2">Abstract</bridgehead>
<para>This HOWTO is intended to walk you through the process of installing and configuring iODBC, Ruby and the Ruby/ODBC bridge module with a goal of writing and executing simple scripts to effect a database connection.
 It is currently maintained by Tim Haynes of <ulink url="http://www.openlinksw.com/">OpenLink Software</ulink>, &lt;<ulink url="mailto:iodbc@openlinksw.com">iodbc@openlinksw.com</ulink>&gt;, that is iodbc at openlinksw.com.</para>
<para>We assume you have some familiarity with using either Terminal on Apple Mac OS X or the shell on a GNU/Linux platform such as Ubuntu, Debian, <ulink url="RedHat">RedHat</ulink>, or Fedora Core, etc.</para>
<bridgehead class="http://www.w3.org/1999/xhtml:h2">Required Components</bridgehead>
<bridgehead class="http://www.w3.org/1999/xhtml:h3">iODBC Driver Manager</bridgehead>
<para> We start by installing the iODBC Driver Manager.</para>
<bridgehead class="http://www.w3.org/1999/xhtml:h4">Linux</bridgehead>
<para> Some Linux distributions (Debian, Ubuntu, Gentoo) have their own packages  for iODBC, so you should only need to type a command such as one of</para>
<itemizedlist mark="bullet" spacing="compact"><listitem>sudo apt-get install libiodbc2 iodbc </listitem>
<listitem>sudo emerge libiodbc </listitem>
<listitem>sudo yum install iodbc</listitem>
</itemizedlist><para> to install it, and possibly some dependencies (GTK+ libraries for the  adminstrator utility), automatically.</para>
<bridgehead class="http://www.w3.org/1999/xhtml:h4"> Mac OS X</bridgehead>
<para> For Mac OS X users, we provide a DMG installer on our <ulink url="Downloads">Downloads</ulink>  page.
 This will install the iODBC Framework, development environment and  graphical configuration utility.</para>
<para> Note that this supersedes the version of iODBC supplied by Apple with Mac OS X,  as it resolves two bugs: </para>
<itemizedlist mark="bullet" spacing="compact"><listitem>on 64-bit machines, ruby would be built in 64-bit mode by default but     the system libiodbc is only 32-bit, making building the ruby-odbc bridge     impossible; </listitem>
<listitem>the handling of SQLError() in ruby-odbc.</listitem>
</itemizedlist><bridgehead class="http://www.w3.org/1999/xhtml:h4">Other Unix operating systems</bridgehead>
<para> On other unix operating systems, you need to compile iODBC from source.
 This  is generally easy:</para>
<itemizedlist mark="bullet" spacing="compact"><listitem><ulink url="Downloads">Download</ulink> the iODBC source tarball </listitem>
<listitem>unpack it using a command such as gzip -cd libiodbc-3.52.7.tar.gz| tar xvf - </listitem>
<listitem>./configure --prefix=/usr/local/iODBC/ </listitem>
<listitem>make </listitem>
<listitem>become root and run make install, e.g., su root -c &#39;make install&#39;</listitem>
</itemizedlist><para> Of course you can also build the same way on linux; the ./configure  script takes a few options you might want to vary, notably --with-prefix=  for where the files will be installed and --enable-gui for whether  to build the GTK+ Administrator or not.</para>
<para> If you wish to build from source on Mac OS X, after unpacking the archive, run </para>
<itemizedlist mark="bullet" spacing="compact"><listitem>cd mac </listitem>
<listitem>make </listitem>
<listitem>sudo make install</listitem>
</itemizedlist><para>This will build the Framework version and create a subdirectory under /usr/local/iODBC/ so that other applications (eg PHP, Perl, Ruby) can link against it without having to modify them to look for frameworks.</para>
<bridgehead class="http://www.w3.org/1999/xhtml:h4">Configuring and Testing iODBC</bridgehead>
<para>It is wise to test that iODBC works directly before trying to layer any Ruby ODBC module on top.
 Either:</para>
<itemizedlist mark="bullet" spacing="compact"><listitem>use the graphical Administrator application (<emphasis>iodbcadm-gtk</emphasis> on linux/unix or    <emphasis>iODBC Administrator.app</emphasis> (/Applications/iODBC/) on Mac OS X) to register an    ODBC driver, add a System or User DSN using the driver, and test it, or </listitem>
<listitem>edit your own odbc.ini (/etc/odbc.ini, ~/.odbc.ini, or $ODBCINI environment variable)    to contain something similar to the following:</listitem>
</itemizedlist><programlisting>[ODBC Data Sources]
pgdata = Native PostgreSQL ODBC driver

[pgdata]
Driver=/usr/lib/odbc/psqlodbcw.so
Host       = data
Server     = data
ServerName = data
Database   = me
UserName   = me
UID        = me
Port       = 5432
</programlisting><para> From the commandline you should be able to run iodbctest DSN=pgdata and it should attempt to connect:</para>
<programlisting>zsh, ubuntu libiodbc-3.52.7/ % iodbctest DSN=pgdata 
iODBC Demonstration program
This program shows an interactive SQL processor
Driver Manager: 03.52.0709.0909
Driver: 08.03.0200 (psqlodbcw.so)

SQL&gt;
</programlisting><para> The SQL&gt; prompt there shows iodbctest has connected and is now awaiting a SQL command as input; additionally it understands the command `tables&#39; which lists tables visible in the current database.</para>
<para>Note the `DSN=pgdata&#39; parameter: this is part of an ODBC connection string, not just a data-source name.
 As such it takes the form</para>
<programlisting>DSN=somedsn;[param=value[;]]*
</programlisting><para> where the parameters are specific to the ODBC driver being used.
 In this case, the PostgreSQL native ODBC driver requires Host, Database and Port, above.
For <ulink url="MySQL">MySQL</ulink> and <ulink url="OpenLink">OpenLink</ulink> drivers, the parameters vary.</para>
<para>The <ulink url="FAQ">iODBC FAQ</ulink> contains a section of common error messages in the event of something going wrong at this stage.</para>
<bridgehead class="http://www.w3.org/1999/xhtml:h3">Ruby</bridgehead>
<para>Ruby is an open-source, interpreted, dynamic, object-oriented scripting language in the same space as Perl, Python on the desktop and with the famous Ruby-on-Rails engine in web-space (to compare with PHP).</para>
<para>There are two ways in which Ruby interfaces with ODBC: a ruby-odbc binding module which presents the ODBC API at the Ruby layer with little abstraction, maintained by Christian Werner; and a DBD::ODBC module that provides a driver compatible with DBI (a database-interaction specification familiar to Perl users, now implemented in Ruby).
 The DBD::ODBC driver depends upon the ruby-odbc binding, so we continue building the packages in hierarchical order.</para>
<bridgehead class="http://www.w3.org/1999/xhtml:h4">Linux</bridgehead>
<para>Most Linux distributions have packages for <ulink url="http://www.ruby-lang.org/en/">Ruby</ulink> already.
 Remember if your distribution distinguishes between runtime and development versions packages, you will need to install the development libraries in order to compile other packages from source against them.
</para>
<itemizedlist mark="bullet" spacing="compact"><listitem>Debian/Ubuntu: sudo apt-get install ruby ruby-dev </listitem>
<listitem>Gentoo: sudo emerge -av ruby</listitem>
</itemizedlist><bridgehead class="http://www.w3.org/1999/xhtml:h4">Mac OS X</bridgehead>
<para>Mac OS X, from Tiger onwards, comes with Ruby 1.8 by default.
 No further installation is required, unless you really want to build it from source yourself.</para>
<bridgehead class="http://www.w3.org/1999/xhtml:h4">From Source</bridgehead>
<para>For other unix environments, it might be required to build Ruby from source.
That process is not documented here except to say that it follows a similar path to iODBC from source: download, unpack, run ./configure, make and sudo make install.</para>
<bridgehead class="http://www.w3.org/1999/xhtml:h3">Ruby/ODBC Binding</bridgehead>
<para>Christian Werner maintains the <ulink url="http://ch-werner.de/rubyodbc/">ruby-odbc binding module</ulink>.</para>
<bridgehead class="http://www.w3.org/1999/xhtml:h4">Linux</bridgehead>
<para>Some GNU/Linux distributions (debian and ubuntu in particular) have already packaged the ruby-odbc binding, so a simple</para>
<programlisting>zsh, ubuntu ruby/ % sudo apt-get install libodbc-ruby1.8 
</programlisting><para> is all that&#39;s required.</para>
<para>However, for better handling of SQLError(), we recommend you use the latest iODBC (3.52.7) and ruby-odbc module (0.9997) so you might still need to build from source, as follows.</para>
<bridgehead class="http://www.w3.org/1999/xhtml:h4"> Mac OS X, other Unix platforms: build from source</bridgehead>
<para>The following instructions apply equally to Linux, Mac OS X, and other Unix-like operating systems, as we&#39;re building from source here.</para>
<para>Download this and unpack it as usual:</para>
<programlisting>zsh, pizza C/ % tar xvfz ruby-odbc-0.9997.tar.gz
./ruby-odbc-0.9997/
./ruby-odbc-0.9997/doc/
./ruby-odbc-0.9997/doc/odbc.html
./ruby-odbc-0.9997/test/
...
zsh, pizza C/ % cd ruby-odbc-0.9997 
zsh, pizza ruby-odbc-0.9997/ % 
</programlisting><para> To configure it, run </para>
<programlisting>zsh, pizza ruby-odbc-0.9997/ % ruby extconf.rb --with-odbc-dir=/usr/local/iODBC
checking for version.h... yes
checking for sql.h... yes
checking for sqlext.h... yes
checking for SQLTCHAR in sqltypes.h... yes
checking for SQLLEN in sqltypes.h... yes
checking for SQLULEN in sqltypes.h... yes
checking for odbcinst.h... yes
checking for SQLAllocConnect() in -liodbc... yes
</programlisting><para>  <emphasis>Note</emphasis> three things: </para>
<itemizedlist mark="bullet" spacing="compact"><listitem>first, we tell it where to find the iODBC libraries using --with-odbc-dir    (which works well with Mac OS X, where ordinarily libraries are provided    using frameworks, so to avoid needing to use those, the iODBC installer    package provides a /usr/local/iODBC/ directory with symbolic links into the    Frameworks directory); </listitem>
<listitem>secondly, it must report successful checking using -liodbc,    not -lodbc - unless you&#39;ve symlinked the two libraries together; </listitem>
<listitem>thirdly, you need iODBC version 3.52.7 and ruby-odbc version 0.9997 to    fix a bug in the handling of SQLError()</listitem>
</itemizedlist><para>We continue to build and install it:</para>
<programlisting>zsh, pizza ruby-odbc-0.9997/ % make
/usr/bin/gcc-4.0 -I. -I. -I/usr/local/ruby/1.8/powerpc-darwin8 -I. \
	-DHAVE_VERSION_H -DHAVE_SQL_H -DHAVE_SQLEXT_H -DHAVE_TYPE_SQLTCHAR \
	-DHAVE_TYPE_SQLLEN -DHAVE_TYPE_SQLULEN -DHAVE_ODBCINST_H \ 
	-DHAVE_SQLINSTALLERERROR -I/usr/local/iODBC/include -I/opt/local/include \ 
	-D_XOPEN_SOURCE -D_DARWIN_C_SOURCE  -I/opt/local/include -fno-common \
	-O2  -fno-common -pipe -fno-common   \
	-c init.c
...
zsh, pizza ruby-odbc-0.9997/ % sudo make install
Password:
/usr/bin/install -m 0755 odbc.bundle /usr/local/ruby/site_ruby/1.8/powerpc-darwin8
</programlisting><para> To check that it built correctly, run one of the following commands to see the shared library dependencies; there should be a mention of `iodbc&#39; somewhere in the output:</para>
<para>On Mac OS X: </para>
<programlisting>zsh, pizza ruby-odbc-0.9997/ % otool -L /usr/local/ruby/site_ruby/1.8/powerpc-darwin8/odbc.bundle 
/usr/local/ruby/site_ruby/1.8/powerpc-darwin8/odbc.bundle:
        /usr/local/lib/libruby.dylib (compatibility version 1.8.0, current version 1.8.7)
        /usr/local/lib/libiodbcinst.1.dylib (compatibility version 2.0.0, current version 2.0.0)
        /usr/local/lib/libiodbc.1.dylib (compatibility version 2.0.0, current version 2.0.0)
</programlisting><para> On Linux/Unix:</para>
<programlisting>zsh, ubuntu ruby-odbc-0.9997/ % ldd /usr/lib/ruby/site_ruby/1.8/i486-linux/odbc.so 
[...]
        libc.so.6 =&gt; /lib/libc.so.6 (0xb7d0e000)
        libiodbc.so.2 =&gt; /usr/local/lib/libiodbc.so.2 (0xb7cc6000)
        libiodbcinst.so.2 =&gt; /usr/local/lib/libiodbcinst.so.2 (0xb7cb3000)
        /lib/ld-linux.so.2 (0xb7fd2000)
</programlisting><bridgehead class="http://www.w3.org/1999/xhtml:h4">Testing</bridgehead>
<para>Having installed the ruby-odbc binding module, you can write a simple ruby script to test it such as the attached which makes a connection and probes some metadata available through the ODBC connection:</para>
<itemizedlist mark="bullet" spacing="compact"><listitem><ulink url="IODBCRubyHOWTO/odbc-metadata.rb">odbc-metadata.rb</ulink></listitem>
</itemizedlist><programlisting>zsh, ubuntu ruby/ % ./odbc-metadata.rb pgdata &quot;&quot; &quot;&quot;
Connecting to [pgdata, , ]
Connected: true

Data-types:

Type integer:
Native: int4
  TYPE_NAME:           int4
  DATA_TYPE:           4
  PRECISION:           10
  LITERAL_PREFIX:      
  LITERAL_SUFFIX:      
  CREATE_PARAMS:       
  NULLABLE:            1
  CASE_SENSITIVE:      0
  SEARCHABLE:          2
  UNSIGNED_ATTRIBUTE:  0
  MONEY:               0
  AUTO_INCREMENT:      0
  LOCAL_TYPE_NAME:     
  MINIMUM_SCALE:       0
  MAXIMUM_SCALE:       0
  SQL_DATA_TYPE:       4
  SQL_DATETIME_SUB:    
  NUM_PREC_RADIX:      10
  INTERVAL_PRECISION:  0
...

Trying type SQL_CURSOR_ROLLBACK_BEHAVIOR (String): ret=[2]

Trying type SQL_DYNAMIC_CURSOR_ATTRIBUTES1 (String): ret=[0]

Trying type SQL_KEYWORDS (String): ret=[]

Trying type SQL_LIKE_ESCAPE_CLAUSE (String): ret=[N]

Trying type SQL_COLUMN_ALIAS (String): ret=[Y]

Trying type SQL_ORDER_BY_COLUMNS_IN_SELECT (String): ret=[N]
</programlisting><bridgehead class="http://www.w3.org/1999/xhtml:h3">Ruby/DBI DBD::ODBC Driver</bridgehead>
<para>The second method to connect Ruby to ODBC is using the DBI interface; this provides a higher-level interface, consisting of an controlling module (DBI) that invokes drivers for specific databases (DBD::&lt;something&gt; modules)  as required, one of which is DBD::ODBC.</para>
<bridgehead class="http://www.w3.org/1999/xhtml:h4">Cross-platform: Ruby GEM</bridgehead>
<para>Ruby has its own packaging system, known as rubygems, which includes the dbi module.</para>
<programlisting>zsh, pizza C/ % sudo gem install dbi dbd-odbc  --remote
Password:
Successfully installed dbi-0.4.3
Successfully installed dbd-odbc-0.2.5
2 gems installed
Installing ri documentation for dbi-0.4.3...
Installing ri documentation for dbd-odbc-0.2.5...
Installing RDoc documentation for dbi-0.4.3...
Installing RDoc documentation for dbd-odbc-0.2.5...
</programlisting><para> If you are using gems for maintaining ruby packages, no further installation is required after this.</para>
<bridgehead class="http://www.w3.org/1999/xhtml:h4">Linux Packages</bridgehead>
<para>As before, some GNU/Linux distributions (Debian and Ubuntu) already have packages for Ruby&#39;s DBI and DBD modules, so a simple</para>
<programlisting>sudo apt-get install libdbd-odbc-ruby1.8 
</programlisting><para> suffices, and will include the DBI module as a dependency too.</para>
<para> </para>
<bridgehead class="http://www.w3.org/1999/xhtml:h4"> Mac OS X and other Unix-like systems: building from source</bridgehead>
<para>On other platforms, if not using the gems above, you have the option to build DBI &amp; DBD::ODBC from source.</para>
<bridgehead class="http://www.w3.org/1999/xhtml:h5">DBI</bridgehead>
<para>Download the ruby-dbi module from <ulink url="http://ruby-dbi.rubyforge.org/">ruby-forge</ulink> and unpack it:</para>
<programlisting>zsh, ubuntu C/ % tar xvfz dbi-0.4.3.tar.gz
dbi-0.4.3/
dbi-0.4.3/build/
dbi-0.4.3/build/rake_task_lib.rb
dbi-0.4.3/build/Rakefile.dbi.rb
dbi-0.4.3/Rakefile
...
zsh, ubuntu C/ % cd dbi-0.4.3 
zsh, ubuntu dbi-0.4.3/ % ls
bin/    ChangeLog  lib/     Rakefile  setup.rb
build/  examples/  LICENSE  README    test/
</programlisting><para> Then run the following 3 commands to build and install it:</para>
<itemizedlist mark="bullet" spacing="compact"><listitem>ruby setup.rb config </listitem>
<listitem>ruby setup.rb setup </listitem>
<listitem>sudo ruby setup.rb install</listitem>
</itemizedlist><programlisting>zsh, ubuntu dbi-0.4.3/ % ruby setup.rb config
---&gt; bin
&lt;--- bin
---&gt; lib
---&gt; lib/dbi
---&gt; lib/dbi/utils
&lt;--- lib/dbi/utils
---&gt; lib/dbi/handles
&lt;--- lib/dbi/handles
---&gt; lib/dbi/base_classes
&lt;--- lib/dbi/base_classes
---&gt; lib/dbi/sql
&lt;--- lib/dbi/sql
&lt;--- lib/dbi
&lt;--- lib

zsh, ubuntu dbi-0.4.3/ % ruby setup.rb setup 
---&gt; bin
updating shebang: test_broken_dbi
updating shebang: dbi
&lt;--- bin
---&gt; lib
---&gt; lib/dbi
---&gt; lib/dbi/utils
&lt;--- lib/dbi/utils
---&gt; lib/dbi/handles
&lt;--- lib/dbi/handles
---&gt; lib/dbi/base_classes
&lt;--- lib/dbi/base_classes
---&gt; lib/dbi/sql
&lt;--- lib/dbi/sql
&lt;--- lib/dbi
&lt;--- lib

zsh, ubuntu dbi-0.4.3/ % sudo ruby setup.rb install
rm -f InstalledFiles
---&gt; bin
mkdir -p /usr/local/stow/ruby/bin
install test_broken_dbi /usr/local/stow/ruby/bin/
install dbi /usr/local/stow/ruby/bin/
&lt;--- bin
---&gt; lib
mkdir -p /usr/local/stow/ruby/lib/ruby/site_ruby/1.9.1
install dbi.rb /usr/local/stow/ruby/lib/ruby/site_ruby/1.9.1/
...
</programlisting><para> </para>
<bridgehead class="http://www.w3.org/1999/xhtml:h5">DBD::ODBC</bridgehead>
<para>The installation of ruby dbd-odbc follows a similar path to the dbi module.</para>
<para>Download and unpack dbd-odbc from <ulink url="http://rubyforge.org/frs/?group_id=234&amp;release_id=36729">ruby-forge</ulink>:</para>
<programlisting>zsh, ubuntu C/ % tar xvfz dbd-odbc-0.2.5.tar.gz 
dbd-odbc-0.2.5/
dbd-odbc-0.2.5/ChangeLog
dbd-odbc-0.2.5/README
dbd-odbc-0.2.5/lib/
dbd-odbc-0.2.5/lib/dbd/
dbd-odbc-0.2.5/lib/dbd/odbc/
zsh, ubuntu dbd-odbc-0.2.5/ % ls
build/  ChangeLog  lib/  LICENSE  Rakefile  README  setup.rb  test/
</programlisting><para>Then run the following 3 commands to build and install it:</para>
<itemizedlist mark="bullet" spacing="compact"><listitem>ruby setup.rb config </listitem>
<listitem>ruby setup.rb setup </listitem>
<listitem>sudo ruby setup.rb install</listitem>
</itemizedlist><programlisting>zsh, ubuntu dbd-odbc-0.2.5/ % ruby setup.rb config
---&gt; lib
---&gt; lib/dbd
---&gt; lib/dbd/odbc
&lt;--- lib/dbd/odbc
&lt;--- lib/dbd
&lt;--- lib

zsh, ubuntu dbd-odbc-0.2.5/ % ruby setup.rb setup 
---&gt; lib
---&gt; lib/dbd
---&gt; lib/dbd/odbc
&lt;--- lib/dbd/odbc
&lt;--- lib/dbd
&lt;--- lib

zsh, ubuntu dbd-odbc-0.2.5/ % sudo ruby setup.rb install
rm -f InstalledFiles
---&gt; lib
mkdir -p /usr/local/stow/ruby/lib/ruby/site_ruby/1.9.1
---&gt; lib/dbd
mkdir -p /usr/local/stow/ruby/lib/ruby/site_ruby/1.9.1/dbd
install ODBC.rb /usr/local/stow/ruby/lib/ruby/site_ruby/1.9.1/dbd
---&gt; lib/dbd/odbc
... 
</programlisting><para> </para>
<bridgehead class="http://www.w3.org/1999/xhtml:h5">Testing Ruby, DBI, ODBC</bridgehead>
<para>The attached script is a quick demonstration of some of DBI&#39;s capabilities, going via the ODBC driver.</para>
<itemizedlist mark="bullet" spacing="compact"><listitem><ulink url="IODBCRubyHOWTO/odbc-test-dbd.rb">odbc-test-dbd.rb</ulink></listitem>
</itemizedlist><programlisting>zsh, ubuntu C/ % ./odbc-test-dbd.rb pgdata &quot;&quot; &quot;&quot;
[1, &quot;This is a varchar 10&quot;]
[2, &quot;This is a varchar 40&quot;]
[3, &quot;This is a varchar 90&quot;]
[4, &quot;This is a varchar 160&quot;]
[5, &quot;This is a varchar 250&quot;]
[6, &quot;This is a varchar 360&quot;]
[7, &quot;This is a varchar 490&quot;]
[8, &quot;This is a varchar 640&quot;]
[9, &quot;This is a varchar 810&quot;]
[10, &quot;This is a varchar 1000&quot;]
</programlisting><para> First the script connects; then it drops and recreates a table called `test&#39;; then it inserts 10 rows and selects them back, before closing off the statement and connection handles.</para>
<para> </para>
</section></docbook>