Ruby on Rails
HowToSetupSybaseAdapterOnRails

These instructions for Sybase on Linux. To setup on Win32 with Visual Studio, go to SybaseASEonWin32. To set up on Mac OS X, go to HowToSetupSybaseAdapterOnRailsOnOSX

Used SybaseASE 12.5.1 client on Suse 7.3

  1. Insall Sybase Open Client for linux (machine i worked on already had it installed so i did not have to do that)
  2. Check if you can access Sybase using isql
  3. Setup Sybase Home Directory which should ls the following ( make sure to make it addequate to your path )
    
    user@workstation:~> ls -la $SYBASE
    total 1124
    drwxrwx---    2       4096 2006-06-26 16:34 .
    drwxr-xr-x   66       8192 2006-06-27 10:52 ..
    lrwxrwxrwx    1         46 2006-06-26 16:33 OCS -> SYBSclnt/12.5.0/sybase/OCS-12_5/
    lrwxrwxrwx    1         45 2006-06-23 12:57 charsets -> SYBSclnt/12.5.0/sybase/charsets
    lrwxrwxrwx    1         43 2006-06-23 12:57 config -> SYBSclnt/12.5.0/sybase/config
    -rw-rw----    1      31271 2006-06-23 12:56 interfaces
    -rwxrwx---    1    1101573 2006-06-23 12:55 isql
    lrwxrwxrwx    1         44 2006-06-23 12:57 locales -> SYBSclnt/12.5.0/sybase/locales
    -rw-rw----    1       1142 2006-06-23 12:57 sybinit.err
    tpdev@nyeqlnx006:~>
    
  4. Make sure that your interfaces file is properly setup.
  5. Add enviroment variables
    
    SYBASE=/home/user/Sybase
    export SYBASE
    
    SYBASE_LIB=/home/user/Sybase/OCS/lib
    export SYBASE_LIB
    
    #To Add To Path
    #I also added locales directory ( not sure if needed but that might be the one that fixed it for me)
    export PATH=.:${PATH}:$SYBASE:$SYBASE/OCS/lib:$SYBASE/locales
    
    #NOTE: I have locales also added to that LIB path
    
    export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:$SYBASE:$SYBASE/OCS/lib:$SYBASE/locales
    
    
  6. Download Ruby Sybase Library
  7. Edit extconfig.rb
    
    gunzip  sybct-ruby-0.2.8.tar.gz
    tar -xvf  sybct-ruby-0.2.8.tar
    cd  sybct-ruby-0.2.8
    vi extconfig.rb
    # Set sybase variable to point to your $SYBASE directory I've use the full path
    sybase = "/home/user/SYBASE" 
    # I did not change anything else
    make 
    make install
    
  8. Copy sybct.o sybct.so sybct.rb sybsql.rb to your ruby path to find what it is do:
    
    user@worskattion> irb
    irb(main):001:0> $LOAD_PATH
    => ["/usr/local/lib/ruby/site_ruby/1.8", "/usr/local/lib/ruby/site_ruby/1.8/i686-linux", "/usr/local/lib/ruby/site_ruby", "/export/applications/usr/local/lib/ruby/1.8", "/usr/local/lib/ruby/1.8/i686-linux", "."]
    

    in my case it was ../lib/ruby/site_ruby/1.8/i686-linux

NOTE: in ASE15 libct.so. is called libsybct.so.. the same applies to other 3 files. ( found by Rasika Ranaweera )

  1. Run some tests
    
    $bash: irb
    irb(main):001:0> require 'sybsql'
    => true
    

    if you did not succeed you would get the folowing error while including ‘sybsql’ from irb
    
    $bash: irb
    irb(main):001:0> require 'sybsql'
    LoadError: libsybtcl.so: cannot open shared object file: No such file or directory - /usr/local/lib/ruby/site_ruby/1.8/i686-linux/sybct.so
            from /usr/local/lib/ruby/site_ruby/1.8/i686-linux/sybct.so
            from /usr/local/lib/ruby/site_ruby/1.8/i686-linux/sybct.rb:3
            from /usr/local/lib/ruby/site_ruby/1.8/i686-linux/sybsql.rb:4
            from (irb):1
    

    and if you are to start rails app that uses sybase_adapter you would get the following:
    
    database configuration specifies nonexistent sybase adapter (ActiveRecord::AdapterNotFound)
    

    One more test to run would be using ruby isql
    
    cd sybct-ruby-0.2.8/
    
    tpdev@nyeqlnx006:~/sybct-ruby-0.2.8> ruby -I . ./sample/isql.rb -S HOSTNAMEFROMINTERFACE -U username -P password
    
    !! MAX ROWCOUNT 2000 !!
    1-> select count(*) from sysobjects
    2-> go
    <- select count(*) from sysobjects
    restype =ROW_RESULT
    
    ----
    1870
    
    (row count = 1, tran state = 'completed')
    3-> quit
    EOF
    
  2. Finally lets get Sybase to be on Rails
    Edit you config/database.yml to look as following
    
    development:
      adapter: sybase
      host: NyDbHost
      database: dbName
      username: someUser
      password: somePassoword
    
    production:
      development
    

    host: should refer to host name that was set up in the $SYBASE/interfaces file.

This is about it.
It took me about a week to get it running. Sybase support unfortenutly is very poor had to talk to many people in order to shed some light on that problem. I do thank them deeply.
GregoryBluvshteyn

Work Arounds

noconvert ( Words of gratitude to bitsweat – on helping resolvin the issue )

In my legacy database I found PKs and FKs with the type of string. They used a string type but the value still remained numeric which would make sybase adapter to convert them to integer rather then leaving them be. I could not do update since my keys were automatically converted to integer. This are results of some tests.

Fixture


first:
  org_id: "1234" 
  org_legal: "Some legal name" 
  group_legal: "Some group legal name" 
  org_short: "Test" 

Test of default test assert_true


Loaded suite test/unit/paragon_counter_party_test
Started
E
Finished in 0.443311 seconds.

  1) Error:
test_truth(ParagonCounterPartyTest):
ActiveRecord::StatementInvalid: RuntimeError: SQL Command Failed for Fixture Insert: INSERT INTO Paragon_Counterparty ([org_short], [org_legal], [group_legal], [org_id]) VALUES ('Test', 'Some legal name', 'Some group legal name', 1234)
Message: Implicit conversion from datatype 'INT' to 'VARCHAR' is not allowed.  Use the CONVERT function to run this query.
: INSERT INTO Paragon_Counterparty ([org_short], [org_legal], [group_legal], [org_id]) VALUES ('Test', 'Some legal name', 'Some group legal name', 1234)

This article is pertinent to activerecord-1.14.3 – will be fixed in 1.2

Changes that needed to be done in your activerecord sybase adapter.
\[lib/ruby/gems/1.8/gems/activerecord-1.14.3/lib/active_record/connection_adapters/sybase_adapter.rb]


#sybase_connection method add 

@numconvert = config.has_key?(:numconvert) ? config[:numconvert] : true 

#quote method 
#change 
  elsif value =~ /^[+-]?[0-9]+$/o 
#to
  elsif @numconvert && force_numeric?(column) && value =~ /^[+-]?[0-9]+$/o 

#add following method somwhere under quote method def force_numeric?(column) (column.nil? || [:integer, :float, :decimal].include?(column.type)) end

Changes that needed to be done in config/database.yaml

config/database.yaml add

numconvert: false

Question:

Is “Sybase Open Client for linux” the apparently proprietary software at: http://www.sybase.com/products/allproductsa-z/softwaredeveloperkit/openclient . If so, then I’m not certain our Sybase license allows us to use this software. Am I then out of luck? I was able to get PHP to talk to Sybase using the open source FreeTDS product. It’s frustrating to require a commercial product to do the same with Ruby/Rails.

Any advice?

reconnects

This adapter didn’t support reconnects so I submitted a patch at http://dev.rubyonrails.org/ticket/8400
I needed reconnects in order to use this in production since bouncing the webserver if we lose the DB connection isn’t really acceptable.

FreeTDS

I was having problems compiling against the latest OCS libraries. The compilation succeeded, but the connection attempts always failed, and no user name/password was being sent to the server.

I switched to the latest version of FreeTDS, and compiled against those. Everything worked perfectly.