ffi-sybase 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +4 -0
 - data/Gemfile +4 -0
 - data/LICENSE +20 -0
 - data/README +25 -0
 - data/Rakefile +2 -0
 - data/TODO +10 -0
 - data/examples/sp_who.rb +20 -0
 - data/ffi-sybase.gemspec +23 -0
 - data/lib/ffi-sybase.rb +20 -0
 - data/lib/sybase/command.rb +209 -0
 - data/lib/sybase/connection.rb +132 -0
 - data/lib/sybase/constants.rb +165 -0
 - data/lib/sybase/context.rb +71 -0
 - data/lib/sybase/lib.rb +264 -0
 - data/lib/sybase/structs/client_message.rb +33 -0
 - data/lib/sybase/structs/column_data.rb +60 -0
 - data/lib/sybase/structs/data_format.rb +63 -0
 - data/lib/sybase/structs/message.rb +27 -0
 - data/lib/sybase/structs/server_message.rb +38 -0
 - data/lib/sybase/version.rb +3 -0
 - metadata +86 -0
 
    
        data/.gitignore
    ADDED
    
    
    
        data/Gemfile
    ADDED
    
    
    
        data/LICENSE
    ADDED
    
    | 
         @@ -0,0 +1,20 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            Copyright (c) 2011 Jari Bakken
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            Permission is hereby granted, free of charge, to any person obtaining
         
     | 
| 
      
 4 
     | 
    
         
            +
            a copy of this software and associated documentation files (the
         
     | 
| 
      
 5 
     | 
    
         
            +
            "Software"), to deal in the Software without restriction, including
         
     | 
| 
      
 6 
     | 
    
         
            +
            without limitation the rights to use, copy, modify, merge, publish,
         
     | 
| 
      
 7 
     | 
    
         
            +
            distribute, sublicense, and/or sell copies of the Software, and to
         
     | 
| 
      
 8 
     | 
    
         
            +
            permit persons to whom the Software is furnished to do so, subject to
         
     | 
| 
      
 9 
     | 
    
         
            +
            the following conditions:
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            The above copyright notice and this permission notice shall be
         
     | 
| 
      
 12 
     | 
    
         
            +
            included in all copies or substantial portions of the Software.
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
         
     | 
| 
      
 15 
     | 
    
         
            +
            EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
         
     | 
| 
      
 16 
     | 
    
         
            +
            MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
         
     | 
| 
      
 17 
     | 
    
         
            +
            NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
         
     | 
| 
      
 18 
     | 
    
         
            +
            LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
         
     | 
| 
      
 19 
     | 
    
         
            +
            OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
         
     | 
| 
      
 20 
     | 
    
         
            +
            WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
         
     | 
    
        data/README
    ADDED
    
    | 
         @@ -0,0 +1,25 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            = ffi-sybase
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            Ruby/FFI bindings for Sybase's Open Client library.
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            = See also
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            * http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.infocenter.dc35570.1550/html/clcprgde/title.htm
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            = Dependencies
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            * ffi
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            == Note on Patches/Pull Requests
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            * Fork the project.
         
     | 
| 
      
 16 
     | 
    
         
            +
            * Make your feature addition or bug fix.
         
     | 
| 
      
 17 
     | 
    
         
            +
            * Add tests for it. This is important so I don't break it in a
         
     | 
| 
      
 18 
     | 
    
         
            +
              future version unintentionally.
         
     | 
| 
      
 19 
     | 
    
         
            +
            * Commit, do not mess with rakefile, version, or history.
         
     | 
| 
      
 20 
     | 
    
         
            +
              (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
         
     | 
| 
      
 21 
     | 
    
         
            +
            * Send me a pull request. Bonus points for topic branches.
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            == Copyright
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
            Copyright (c) 2011 Jari Bakken. See LICENSE for details.
         
     | 
    
        data/Rakefile
    ADDED
    
    
    
        data/TODO
    ADDED
    
    
    
        data/examples/sp_who.rb
    ADDED
    
    | 
         @@ -0,0 +1,20 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            $LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'pp'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'ffi-sybase'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            unless ARGV.size == 3
         
     | 
| 
      
 6 
     | 
    
         
            +
              abort("USAGE: #{$PROGRAM_NAME} <db> <user> <pass>")
         
     | 
| 
      
 7 
     | 
    
         
            +
            end
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            db, user, pass = *ARGV
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            Sybase::Context.new do |ctx|
         
     | 
| 
      
 12 
     | 
    
         
            +
              ctx.callbacks.library { |message| puts "library : #{message}"  }
         
     | 
| 
      
 13 
     | 
    
         
            +
              ctx.callbacks.client  { |message| puts "client  : #{message}"  }
         
     | 
| 
      
 14 
     | 
    
         
            +
              ctx.callbacks.server  { |message| puts "server  : #{message}"  }
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
              Sybase::Connection.new(ctx, :username => user, :password => pass) do |conn|
         
     | 
| 
      
 17 
     | 
    
         
            +
                conn.connect db
         
     | 
| 
      
 18 
     | 
    
         
            +
                pp Sybase::Command.new(conn, "sp_who").execute
         
     | 
| 
      
 19 
     | 
    
         
            +
              end
         
     | 
| 
      
 20 
     | 
    
         
            +
            end
         
     | 
    
        data/ffi-sybase.gemspec
    ADDED
    
    | 
         @@ -0,0 +1,23 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # -*- encoding: utf-8 -*-
         
     | 
| 
      
 2 
     | 
    
         
            +
            $:.push File.expand_path("../lib", __FILE__)
         
     | 
| 
      
 3 
     | 
    
         
            +
            require "sybase/version"
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            Gem::Specification.new do |s|
         
     | 
| 
      
 6 
     | 
    
         
            +
              s.name        = "ffi-sybase"
         
     | 
| 
      
 7 
     | 
    
         
            +
              s.version     = Sybase::VERSION
         
     | 
| 
      
 8 
     | 
    
         
            +
              s.platform    = Gem::Platform::RUBY
         
     | 
| 
      
 9 
     | 
    
         
            +
              s.authors     = ["Jari Bakken"]
         
     | 
| 
      
 10 
     | 
    
         
            +
              s.email       = ["jari.bakken@gmail.com"]
         
     | 
| 
      
 11 
     | 
    
         
            +
              s.homepage    = "http://github.com/jarib/ffi-sybase"
         
     | 
| 
      
 12 
     | 
    
         
            +
              s.summary     = %q{Ruby/FFI bindings for Sybase OCS}
         
     | 
| 
      
 13 
     | 
    
         
            +
              s.description = %q{Ruby/FFI bindings for Sybase's Open Client library.}
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
              s.rubyforge_project = "ffi-sybase"
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
              s.add_dependency "ffi", ">= 0.6.3"
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
              s.files         = `git ls-files`.split("\n")
         
     | 
| 
      
 20 
     | 
    
         
            +
              s.test_files    = `git ls-files -- {test,spec,features}/*`.split("\n")
         
     | 
| 
      
 21 
     | 
    
         
            +
              s.executables   = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
         
     | 
| 
      
 22 
     | 
    
         
            +
              s.require_paths = ["lib"]
         
     | 
| 
      
 23 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/ffi-sybase.rb
    ADDED
    
    | 
         @@ -0,0 +1,20 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #!/usr/bin/env ruby
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'socket'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'ffi'
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            module Sybase
         
     | 
| 
      
 7 
     | 
    
         
            +
              class Error < StandardError; end
         
     | 
| 
      
 8 
     | 
    
         
            +
            end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            require "sybase/version"
         
     | 
| 
      
 11 
     | 
    
         
            +
            require "sybase/constants"
         
     | 
| 
      
 12 
     | 
    
         
            +
            require "sybase/structs/message"
         
     | 
| 
      
 13 
     | 
    
         
            +
            require "sybase/structs/client_message"
         
     | 
| 
      
 14 
     | 
    
         
            +
            require "sybase/structs/server_message"
         
     | 
| 
      
 15 
     | 
    
         
            +
            require "sybase/structs/column_data"
         
     | 
| 
      
 16 
     | 
    
         
            +
            require "sybase/structs/data_format"
         
     | 
| 
      
 17 
     | 
    
         
            +
            require "sybase/lib"
         
     | 
| 
      
 18 
     | 
    
         
            +
            require "sybase/context"
         
     | 
| 
      
 19 
     | 
    
         
            +
            require "sybase/connection"
         
     | 
| 
      
 20 
     | 
    
         
            +
            require "sybase/command"
         
     | 
| 
         @@ -0,0 +1,209 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Sybase
         
     | 
| 
      
 2 
     | 
    
         
            +
              class Command
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
                def initialize(connection, str)
         
     | 
| 
      
 5 
     | 
    
         
            +
                  FFI::MemoryPointer.new(:pointer) do |ptr|
         
     | 
| 
      
 6 
     | 
    
         
            +
                    Lib.check Lib.ct_cmd_alloc(connection, ptr), "ct_cmd_alloc"
         
     | 
| 
      
 7 
     | 
    
         
            +
                    @ptr = FFI::AutoPointer.new(ptr.read_pointer, Lib.method(:ct_cmd_drop))
         
     | 
| 
      
 8 
     | 
    
         
            +
                  end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                  @str = str.to_s
         
     | 
| 
      
 11 
     | 
    
         
            +
                end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                def execute
         
     | 
| 
      
 14 
     | 
    
         
            +
                  set_command
         
     | 
| 
      
 15 
     | 
    
         
            +
                  send
         
     | 
| 
      
 16 
     | 
    
         
            +
                  results
         
     | 
| 
      
 17 
     | 
    
         
            +
                ensure
         
     | 
| 
      
 18 
     | 
    
         
            +
                  finish
         
     | 
| 
      
 19 
     | 
    
         
            +
                end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                def finish
         
     | 
| 
      
 22 
     | 
    
         
            +
                  to_ptr.free
         
     | 
| 
      
 23 
     | 
    
         
            +
                  @ptr = nil
         
     | 
| 
      
 24 
     | 
    
         
            +
                end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                def to_ptr
         
     | 
| 
      
 27 
     | 
    
         
            +
                  @ptr or raise "command #{self} already ran or was not initialized"
         
     | 
| 
      
 28 
     | 
    
         
            +
                end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                private
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                def set_command
         
     | 
| 
      
 33 
     | 
    
         
            +
                  Lib.check Lib.ct_command(to_ptr, CS_LANG_CMD, @str, @str.bytesize, CS_UNUSED)
         
     | 
| 
      
 34 
     | 
    
         
            +
                end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                def send
         
     | 
| 
      
 37 
     | 
    
         
            +
                  Lib.check Lib.ct_send(to_ptr), "ct_send failed"
         
     | 
| 
      
 38 
     | 
    
         
            +
                end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                def cancel
         
     | 
| 
      
 41 
     | 
    
         
            +
                  Lib.ct_cancel(nil, to_ptr, CS_CANCEL_CURRENT)
         
     | 
| 
      
 42 
     | 
    
         
            +
                end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                COMMAND_RESULTS = {
         
     | 
| 
      
 45 
     | 
    
         
            +
                  CS_CMD_SUCCEED    => :succeed,
         
     | 
| 
      
 46 
     | 
    
         
            +
                  CS_CMD_DONE       => :done,
         
     | 
| 
      
 47 
     | 
    
         
            +
                  CS_CMD_FAIL       => :fail,
         
     | 
| 
      
 48 
     | 
    
         
            +
                  CS_ROW_RESULT     => :row,
         
     | 
| 
      
 49 
     | 
    
         
            +
                  CS_CURSOR_RESULT  => :cursor,
         
     | 
| 
      
 50 
     | 
    
         
            +
                  CS_PARAM_RESULT   => :param,
         
     | 
| 
      
 51 
     | 
    
         
            +
                  CS_COMPUTE_RESULT => :compute,
         
     | 
| 
      
 52 
     | 
    
         
            +
                  CS_STATUS_RESULT  => :status
         
     | 
| 
      
 53 
     | 
    
         
            +
                }
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                def results
         
     | 
| 
      
 56 
     | 
    
         
            +
                  intptr = FFI::MemoryPointer.new(:int)
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                  state = :initial
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
                  returned = []
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                  while successful? intptr
         
     | 
| 
      
 63 
     | 
    
         
            +
                    restype = intptr.read_int
         
     | 
| 
      
 64 
     | 
    
         
            +
                    restype = COMMAND_RESULTS[restype] || restype
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
                    case restype
         
     | 
| 
      
 67 
     | 
    
         
            +
                    when :succeed, # no row - e.g. insert/update
         
     | 
| 
      
 68 
     | 
    
         
            +
                         :done     # results completely processed
         
     | 
| 
      
 69 
     | 
    
         
            +
                      returned << Result.new(restype, nil, result_info(CS_ROW_COUNT), result_info(CS_TRANS_STATE))
         
     | 
| 
      
 70 
     | 
    
         
            +
                    when :fail
         
     | 
| 
      
 71 
     | 
    
         
            +
                      returned << Result.new(restype, nil, result_info(CS_ROW_COUNT), result_info(CS_TRANS_STATE))
         
     | 
| 
      
 72 
     | 
    
         
            +
                    when :row,
         
     | 
| 
      
 73 
     | 
    
         
            +
                         :cursor,
         
     | 
| 
      
 74 
     | 
    
         
            +
                         :param,
         
     | 
| 
      
 75 
     | 
    
         
            +
                         :compute,
         
     | 
| 
      
 76 
     | 
    
         
            +
                         :status
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
                      columns, rows = fetch_data
         
     | 
| 
      
 79 
     | 
    
         
            +
                      returned << Result.new(restype, :columns => columns, :rows => rows)
         
     | 
| 
      
 80 
     | 
    
         
            +
                    else
         
     | 
| 
      
 81 
     | 
    
         
            +
                      returned << Result.new(restype, nil, result_info(CS_ROW_COUNT), result_info(CS_TRANS_STATE))
         
     | 
| 
      
 82 
     | 
    
         
            +
                    end
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
                    # check context timeout?
         
     | 
| 
      
 85 
     | 
    
         
            +
                  end
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
                  returned
         
     | 
| 
      
 88 
     | 
    
         
            +
                end
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
                class Result
         
     | 
| 
      
 91 
     | 
    
         
            +
                  def initialize(type, data, row_count = nil, transaction_state = nil)
         
     | 
| 
      
 92 
     | 
    
         
            +
                    @type              = type
         
     | 
| 
      
 93 
     | 
    
         
            +
                    @data              = data
         
     | 
| 
      
 94 
     | 
    
         
            +
                    @row_count         = row_count
         
     | 
| 
      
 95 
     | 
    
         
            +
                    @transaction_state = transaction_state
         
     | 
| 
      
 96 
     | 
    
         
            +
                  end
         
     | 
| 
      
 97 
     | 
    
         
            +
                end # Result
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
      
 99 
     | 
    
         
            +
                def successful?(intptr)
         
     | 
| 
      
 100 
     | 
    
         
            +
                  @return_code = Lib.ct_results(to_ptr, intptr)
         
     | 
| 
      
 101 
     | 
    
         
            +
                  @return_code == CS_SUCCEED
         
     | 
| 
      
 102 
     | 
    
         
            +
                end
         
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
      
 104 
     | 
    
         
            +
                def fetch_data
         
     | 
| 
      
 105 
     | 
    
         
            +
                  num_cols = fetch_column_count
         
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
      
 107 
     | 
    
         
            +
                  column_datas = Array.new(num_cols) { ColumnData.new }
         
     | 
| 
      
 108 
     | 
    
         
            +
             
     | 
| 
      
 109 
     | 
    
         
            +
                  num_cols.times do |i|
         
     | 
| 
      
 110 
     | 
    
         
            +
                    cd = column_datas[i]
         
     | 
| 
      
 111 
     | 
    
         
            +
                    df = cd.format
         
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
      
 113 
     | 
    
         
            +
                    Lib.check Lib.ct_describe(to_ptr, i + 1, df)
         
     | 
| 
      
 114 
     | 
    
         
            +
                    type = df[:datatype]
         
     | 
| 
      
 115 
     | 
    
         
            +
             
     | 
| 
      
 116 
     | 
    
         
            +
                    case type
         
     | 
| 
      
 117 
     | 
    
         
            +
                    when CS_TINYINT_TYPE,
         
     | 
| 
      
 118 
     | 
    
         
            +
                         CS_SMALLINT_TYPE,
         
     | 
| 
      
 119 
     | 
    
         
            +
                         CS_INT_TYPE,
         
     | 
| 
      
 120 
     | 
    
         
            +
                         CS_BIT_TYPE,
         
     | 
| 
      
 121 
     | 
    
         
            +
                         CS_DECIMAL_TYPE,
         
     | 
| 
      
 122 
     | 
    
         
            +
                         CS_NUMERIC_TYPE
         
     | 
| 
      
 123 
     | 
    
         
            +
                      df[:maxlength] = FFI.type_size(:int)
         
     | 
| 
      
 124 
     | 
    
         
            +
                      df[:datatype]  = CS_INT_TYPE
         
     | 
| 
      
 125 
     | 
    
         
            +
                      df[:format]    = CS_FMT_UNUSED
         
     | 
| 
      
 126 
     | 
    
         
            +
             
     | 
| 
      
 127 
     | 
    
         
            +
                      cd.int_pointer!
         
     | 
| 
      
 128 
     | 
    
         
            +
                    when CS_REAL_TYPE, CS_FLOAT_TYPE
         
     | 
| 
      
 129 
     | 
    
         
            +
                      # not sure about this
         
     | 
| 
      
 130 
     | 
    
         
            +
                      df[:maxlength] = FFI.type_size(:double)
         
     | 
| 
      
 131 
     | 
    
         
            +
                      df[:datatype]  = CS_FLOAT_TYPE
         
     | 
| 
      
 132 
     | 
    
         
            +
                      df[:format]    = CS_FMT_UNUSED
         
     | 
| 
      
 133 
     | 
    
         
            +
             
     | 
| 
      
 134 
     | 
    
         
            +
                      cd.double_pointer!
         
     | 
| 
      
 135 
     | 
    
         
            +
                    else # treat as String
         
     | 
| 
      
 136 
     | 
    
         
            +
                      df[:maxlength] = Lib.display_length(df) + 1
         
     | 
| 
      
 137 
     | 
    
         
            +
             
     | 
| 
      
 138 
     | 
    
         
            +
                      if type == CS_IMAGE_TYPE
         
     | 
| 
      
 139 
     | 
    
         
            +
                        df[:format] = CS_FMT_UNUSED
         
     | 
| 
      
 140 
     | 
    
         
            +
                      else
         
     | 
| 
      
 141 
     | 
    
         
            +
                        df[:format] = CS_FMT_NULLTERM
         
     | 
| 
      
 142 
     | 
    
         
            +
                        df[:datatype] = CS_CHAR_TYPE
         
     | 
| 
      
 143 
     | 
    
         
            +
                      end
         
     | 
| 
      
 144 
     | 
    
         
            +
             
     | 
| 
      
 145 
     | 
    
         
            +
                      cd.char_pointer!(df[:maxlength])
         
     | 
| 
      
 146 
     | 
    
         
            +
                    end
         
     | 
| 
      
 147 
     | 
    
         
            +
             
     | 
| 
      
 148 
     | 
    
         
            +
                    bind i, df, cd
         
     | 
| 
      
 149 
     | 
    
         
            +
                  end
         
     | 
| 
      
 150 
     | 
    
         
            +
             
     | 
| 
      
 151 
     | 
    
         
            +
                  rows_read_ptr = FFI::MemoryPointer.new(:int)
         
     | 
| 
      
 152 
     | 
    
         
            +
                  row_count     = 0
         
     | 
| 
      
 153 
     | 
    
         
            +
             
     | 
| 
      
 154 
     | 
    
         
            +
                  columns       = column_datas.map { |cd| cd.format.name }
         
     | 
| 
      
 155 
     | 
    
         
            +
                  values        = []
         
     | 
| 
      
 156 
     | 
    
         
            +
             
     | 
| 
      
 157 
     | 
    
         
            +
                  while (code = fetch_row(rows_read_ptr)) == CS_SUCCEED || code == CS_ROW_FAIL
         
     | 
| 
      
 158 
     | 
    
         
            +
                    # increment row count
         
     | 
| 
      
 159 
     | 
    
         
            +
                    row_count += rows_read_ptr.read_int
         
     | 
| 
      
 160 
     | 
    
         
            +
             
     | 
| 
      
 161 
     | 
    
         
            +
                    if code == CS_ROW_FAIL
         
     | 
| 
      
 162 
     | 
    
         
            +
                      raise Error, "error on row #{row_count}"
         
     | 
| 
      
 163 
     | 
    
         
            +
                    end
         
     | 
| 
      
 164 
     | 
    
         
            +
             
     | 
| 
      
 165 
     | 
    
         
            +
                    values << column_datas.map { |e| e.value }
         
     | 
| 
      
 166 
     | 
    
         
            +
                  end
         
     | 
| 
      
 167 
     | 
    
         
            +
             
     | 
| 
      
 168 
     | 
    
         
            +
                  # done processing rows, check final return code
         
     | 
| 
      
 169 
     | 
    
         
            +
                  case code
         
     | 
| 
      
 170 
     | 
    
         
            +
                  when CS_END_DATA
         
     | 
| 
      
 171 
     | 
    
         
            +
                    # all good
         
     | 
| 
      
 172 
     | 
    
         
            +
                  when CS_FAIL
         
     | 
| 
      
 173 
     | 
    
         
            +
                    raise Error, "ct_fetch() failed"
         
     | 
| 
      
 174 
     | 
    
         
            +
                  else
         
     | 
| 
      
 175 
     | 
    
         
            +
                    raise Error, "unexpected return code: #{code}"
         
     | 
| 
      
 176 
     | 
    
         
            +
                  end
         
     | 
| 
      
 177 
     | 
    
         
            +
             
     | 
| 
      
 178 
     | 
    
         
            +
                  [columns, values]
         
     | 
| 
      
 179 
     | 
    
         
            +
                ensure
         
     | 
| 
      
 180 
     | 
    
         
            +
                  # ?
         
     | 
| 
      
 181 
     | 
    
         
            +
                end
         
     | 
| 
      
 182 
     | 
    
         
            +
             
     | 
| 
      
 183 
     | 
    
         
            +
                def fetch_row(rows_read_ptr)
         
     | 
| 
      
 184 
     | 
    
         
            +
                  Lib.ct_fetch(to_ptr, CS_UNUSED, CS_UNUSED, CS_UNUSED, rows_read_ptr)
         
     | 
| 
      
 185 
     | 
    
         
            +
                end
         
     | 
| 
      
 186 
     | 
    
         
            +
             
     | 
| 
      
 187 
     | 
    
         
            +
                def bind(index, data_format, column_data)
         
     | 
| 
      
 188 
     | 
    
         
            +
                  Lib.check Lib.ct_bind(to_ptr, index + 1, data_format, column_data.pointer, column_data.valuelen_pointer, column_data.indicator_pointer)
         
     | 
| 
      
 189 
     | 
    
         
            +
                end
         
     | 
| 
      
 190 
     | 
    
         
            +
             
     | 
| 
      
 191 
     | 
    
         
            +
                def fetch_column_count
         
     | 
| 
      
 192 
     | 
    
         
            +
                  num_cols = result_info(CS_NUMDATA)
         
     | 
| 
      
 193 
     | 
    
         
            +
             
     | 
| 
      
 194 
     | 
    
         
            +
                  if num_cols <= 0
         
     | 
| 
      
 195 
     | 
    
         
            +
                    cancel
         
     | 
| 
      
 196 
     | 
    
         
            +
                    raise Error, "bad column count (#{num_cols})"
         
     | 
| 
      
 197 
     | 
    
         
            +
                  end
         
     | 
| 
      
 198 
     | 
    
         
            +
             
     | 
| 
      
 199 
     | 
    
         
            +
                  num_cols
         
     | 
| 
      
 200 
     | 
    
         
            +
                end
         
     | 
| 
      
 201 
     | 
    
         
            +
             
     | 
| 
      
 202 
     | 
    
         
            +
                def result_info(operation)
         
     | 
| 
      
 203 
     | 
    
         
            +
                  int_ptr = FFI::MemoryPointer.new(:int)
         
     | 
| 
      
 204 
     | 
    
         
            +
                  Lib.check Lib.ct_res_info(to_ptr, operation, int_ptr, CS_UNUSED, nil), "ct_res_info failed"
         
     | 
| 
      
 205 
     | 
    
         
            +
                  num_cols = int_ptr.read_int
         
     | 
| 
      
 206 
     | 
    
         
            +
                end
         
     | 
| 
      
 207 
     | 
    
         
            +
             
     | 
| 
      
 208 
     | 
    
         
            +
              end # Command
         
     | 
| 
      
 209 
     | 
    
         
            +
            end # Sybase
         
     | 
| 
         @@ -0,0 +1,132 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Sybase
         
     | 
| 
      
 2 
     | 
    
         
            +
              class Connection
         
     | 
| 
      
 3 
     | 
    
         
            +
                PROPERTIES = {
         
     | 
| 
      
 4 
     | 
    
         
            +
                  :username    => [ CS_USERNAME,    :string ],
         
     | 
| 
      
 5 
     | 
    
         
            +
                  :password    => [ CS_PASSWORD,    :string ],
         
     | 
| 
      
 6 
     | 
    
         
            +
                  :appname     => [ CS_APPNAME,     :string ],
         
     | 
| 
      
 7 
     | 
    
         
            +
                  :tds_version => [ CS_TDS_VERSION, :int    ],
         
     | 
| 
      
 8 
     | 
    
         
            +
                  :hostname    => [ CS_HOSTNAME,    :string ]
         
     | 
| 
      
 9 
     | 
    
         
            +
                }
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                def initialize(context, opts ={})
         
     | 
| 
      
 13 
     | 
    
         
            +
                  @context = context
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                  FFI::MemoryPointer.new(:pointer) { |ptr|
         
     | 
| 
      
 16 
     | 
    
         
            +
                    Lib.check Lib.ct_con_alloc(context, ptr), "ct_con_alloc"
         
     | 
| 
      
 17 
     | 
    
         
            +
                    @ptr = FFI::AutoPointer.new(ptr.read_pointer, Lib.method(:ct_con_drop))
         
     | 
| 
      
 18 
     | 
    
         
            +
                  }
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                  opts.each do |key, value|
         
     | 
| 
      
 21 
     | 
    
         
            +
                    self[key] = value
         
     | 
| 
      
 22 
     | 
    
         
            +
                  end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                  unless opts.has_key?(:hostname)
         
     | 
| 
      
 25 
     | 
    
         
            +
                    self[:hostname] = Socket.gethostname
         
     | 
| 
      
 26 
     | 
    
         
            +
                  end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                  if block_given?
         
     | 
| 
      
 29 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 30 
     | 
    
         
            +
                      yield self
         
     | 
| 
      
 31 
     | 
    
         
            +
                    ensure
         
     | 
| 
      
 32 
     | 
    
         
            +
                      close
         
     | 
| 
      
 33 
     | 
    
         
            +
                    end
         
     | 
| 
      
 34 
     | 
    
         
            +
                  end
         
     | 
| 
      
 35 
     | 
    
         
            +
                end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                def debug!
         
     | 
| 
      
 38 
     | 
    
         
            +
                  Lib.check Lib.ct_debug(@context, to_ptr, CS_SET_FLAG, CS_DBG_ALL, nil, CS_UNUSED)
         
     | 
| 
      
 39 
     | 
    
         
            +
                end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                def close
         
     | 
| 
      
 42 
     | 
    
         
            +
                  Lib.check Lib.ct_close(@ptr, CS_UNUSED), "ct_close"
         
     | 
| 
      
 43 
     | 
    
         
            +
                end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                def [](key)
         
     | 
| 
      
 46 
     | 
    
         
            +
                  property, type = property_type_for(key)
         
     | 
| 
      
 47 
     | 
    
         
            +
                  case type
         
     | 
| 
      
 48 
     | 
    
         
            +
                  when :string
         
     | 
| 
      
 49 
     | 
    
         
            +
                    get_string_property property
         
     | 
| 
      
 50 
     | 
    
         
            +
                  when :int
         
     | 
| 
      
 51 
     | 
    
         
            +
                    get_int_property property
         
     | 
| 
      
 52 
     | 
    
         
            +
                  end
         
     | 
| 
      
 53 
     | 
    
         
            +
                end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                def []=(key, value)
         
     | 
| 
      
 56 
     | 
    
         
            +
                  property, type = property_type_for(key)
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                  case type
         
     | 
| 
      
 59 
     | 
    
         
            +
                  when :string
         
     | 
| 
      
 60 
     | 
    
         
            +
                    set_string_property property, value
         
     | 
| 
      
 61 
     | 
    
         
            +
                  when :int
         
     | 
| 
      
 62 
     | 
    
         
            +
                    set_int_property property, value
         
     | 
| 
      
 63 
     | 
    
         
            +
                  else
         
     | 
| 
      
 64 
     | 
    
         
            +
                    raise Error, "invalid type: #{type.inspect}"
         
     | 
| 
      
 65 
     | 
    
         
            +
                  end
         
     | 
| 
      
 66 
     | 
    
         
            +
                end
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                def property_type_for(key)
         
     | 
| 
      
 69 
     | 
    
         
            +
                  PROPERTIES.fetch(key) { |key|
         
     | 
| 
      
 70 
     | 
    
         
            +
                    raise ArgumentError, "invalid option: #{key.inspect}, expected one of #{PROPERTIES.keys.inspect}"
         
     | 
| 
      
 71 
     | 
    
         
            +
                  }
         
     | 
| 
      
 72 
     | 
    
         
            +
                end
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
                def username=(user)
         
     | 
| 
      
 75 
     | 
    
         
            +
                  set_string CS_USERNAME, user
         
     | 
| 
      
 76 
     | 
    
         
            +
                end
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
                def username
         
     | 
| 
      
 79 
     | 
    
         
            +
                  get_string CS_USERNAME
         
     | 
| 
      
 80 
     | 
    
         
            +
                end
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
                def password=(password)
         
     | 
| 
      
 83 
     | 
    
         
            +
                  set_string CS_PASSWORD, password
         
     | 
| 
      
 84 
     | 
    
         
            +
                end
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
                def password
         
     | 
| 
      
 87 
     | 
    
         
            +
                  get_string CS_PASSWORD
         
     | 
| 
      
 88 
     | 
    
         
            +
                end
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
                def appname=(name)
         
     | 
| 
      
 91 
     | 
    
         
            +
                  set_string CS_APPNAME, name
         
     | 
| 
      
 92 
     | 
    
         
            +
                end
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
                def appname
         
     | 
| 
      
 95 
     | 
    
         
            +
                  get_string CS_APPNAME, name
         
     | 
| 
      
 96 
     | 
    
         
            +
                end
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
                def connect(server)
         
     | 
| 
      
 99 
     | 
    
         
            +
                  server = server.to_s
         
     | 
| 
      
 100 
     | 
    
         
            +
                  Lib.check Lib.ct_connect(@ptr, server,  server.bytesize), "connect(#{server.inspect}) failed"
         
     | 
| 
      
 101 
     | 
    
         
            +
                end
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
      
 103 
     | 
    
         
            +
                def to_ptr
         
     | 
| 
      
 104 
     | 
    
         
            +
                  @ptr
         
     | 
| 
      
 105 
     | 
    
         
            +
                end
         
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
      
 107 
     | 
    
         
            +
                private
         
     | 
| 
      
 108 
     | 
    
         
            +
             
     | 
| 
      
 109 
     | 
    
         
            +
                def set_string_property(property, string)
         
     | 
| 
      
 110 
     | 
    
         
            +
                  Lib.check Lib.ct_con_props(@ptr, CS_SET, property, string.to_s, CS_NULLTERM, nil), "ct_con_prop(#{property} => #{string.inspect}) failed"
         
     | 
| 
      
 111 
     | 
    
         
            +
                end
         
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
      
 113 
     | 
    
         
            +
                def get_string_property(property)
         
     | 
| 
      
 114 
     | 
    
         
            +
                  FFI::MemoryPointer.new(:string) { |ptr| get_property(property, ptr) }.read_string
         
     | 
| 
      
 115 
     | 
    
         
            +
                end
         
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
      
 117 
     | 
    
         
            +
                def get_int_property(property)
         
     | 
| 
      
 118 
     | 
    
         
            +
                  FFI::MemoryPointer.new(:int) { |ptr| get_property(property, ptr) }.read_int
         
     | 
| 
      
 119 
     | 
    
         
            +
                end
         
     | 
| 
      
 120 
     | 
    
         
            +
             
     | 
| 
      
 121 
     | 
    
         
            +
                def set_int_property(property, int)
         
     | 
| 
      
 122 
     | 
    
         
            +
                  ptr = FFI::MemoryPointer.new(:int)
         
     | 
| 
      
 123 
     | 
    
         
            +
                  ptr.write_int(int)
         
     | 
| 
      
 124 
     | 
    
         
            +
             
     | 
| 
      
 125 
     | 
    
         
            +
                  Lib.check Lib.ct_con_props(@ptr, CS_SET, property, ptr, CS_UNUSED, nil), "ct_con_prop(#{property} => #{int.inspect}) failed"
         
     | 
| 
      
 126 
     | 
    
         
            +
                end
         
     | 
| 
      
 127 
     | 
    
         
            +
             
     | 
| 
      
 128 
     | 
    
         
            +
                def get_property(property, ptr)
         
     | 
| 
      
 129 
     | 
    
         
            +
                  Lib.check Lib.ct_con_props(@ptr, CS_GET, property, ptr, CS_UNUSED, nil), "ct_con_prop(CS_GET, #{property}) failed"
         
     | 
| 
      
 130 
     | 
    
         
            +
                end
         
     | 
| 
      
 131 
     | 
    
         
            +
              end # Connection
         
     | 
| 
      
 132 
     | 
    
         
            +
            end # Sybase
         
     | 
| 
         @@ -0,0 +1,165 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Sybase
         
     | 
| 
      
 2 
     | 
    
         
            +
              DEFAULT_CTLIB_VERSION = 15001
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
              MAX_CHAR_BUF          = 1024
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
              CS_CONV_ERR           = -100
         
     | 
| 
      
 7 
     | 
    
         
            +
              CS_EXTERNAL_ERR       = -200
         
     | 
| 
      
 8 
     | 
    
         
            +
              CS_INTERNAL_ERR       = -300
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
              CS_TDS_40             = 7360
         
     | 
| 
      
 11 
     | 
    
         
            +
              CS_TDS_42             = 7361
         
     | 
| 
      
 12 
     | 
    
         
            +
              CS_TDS_46             = 7362
         
     | 
| 
      
 13 
     | 
    
         
            +
              CS_TDS_495            = 7363
         
     | 
| 
      
 14 
     | 
    
         
            +
              CS_TDS_50             = 7364
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
              CS_SET_FLAG           = 1700
         
     | 
| 
      
 17 
     | 
    
         
            +
              CS_CLEAR_FLAG         = 1701
         
     | 
| 
      
 18 
     | 
    
         
            +
              CS_DBG_ALL            = 1
         
     | 
| 
      
 19 
     | 
    
         
            +
              CS_DBG_ASYNC          = 2
         
     | 
| 
      
 20 
     | 
    
         
            +
              CS_DBG_ERROR          = 4
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
              CS_CLIENTMSG_CB       = 3
         
     | 
| 
      
 23 
     | 
    
         
            +
              CS_GET                = 33
         
     | 
| 
      
 24 
     | 
    
         
            +
              CS_MAX_CHAR           = 256
         
     | 
| 
      
 25 
     | 
    
         
            +
              CS_MAX_NAME           = 255
         
     | 
| 
      
 26 
     | 
    
         
            +
              CS_MAX_MSG            = 1024
         
     | 
| 
      
 27 
     | 
    
         
            +
              CS_MESSAGE_CB         = 9119
         
     | 
| 
      
 28 
     | 
    
         
            +
              CS_NULLTERM           = -9
         
     | 
| 
      
 29 
     | 
    
         
            +
              CS_SERVERMSG_CB       = 2
         
     | 
| 
      
 30 
     | 
    
         
            +
              CS_SET                = 34
         
     | 
| 
      
 31 
     | 
    
         
            +
              CS_SQLSTATE_SIZE      = 8
         
     | 
| 
      
 32 
     | 
    
         
            +
              CS_SUCCEED            = 1
         
     | 
| 
      
 33 
     | 
    
         
            +
              CS_FAIL               = 0
         
     | 
| 
      
 34 
     | 
    
         
            +
              CS_UNUSED             = -99999
         
     | 
| 
      
 35 
     | 
    
         
            +
              CS_CANCEL_CURRENT     = 6000
         
     | 
| 
      
 36 
     | 
    
         
            +
              CS_FMT_UNUSED         = 0
         
     | 
| 
      
 37 
     | 
    
         
            +
              CS_FMT_NULLTERM       = 1
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
              CS_SYNC_IO = 8111
         
     | 
| 
      
 40 
     | 
    
         
            +
              CS_ASYNC_IO = 8112
         
     | 
| 
      
 41 
     | 
    
         
            +
              CS_DEFER_IO = 8113
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
              # server options
         
     | 
| 
      
 44 
     | 
    
         
            +
              CS_OPT_CHARSET        = 5010
         
     | 
| 
      
 45 
     | 
    
         
            +
              CS_OPT_PARSEONLY      = 5018
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
              # ct_command types
         
     | 
| 
      
 48 
     | 
    
         
            +
              CS_LANG_CMD           = 148
         
     | 
| 
      
 49 
     | 
    
         
            +
              CS_RPC_CMD            = 149
         
     | 
| 
      
 50 
     | 
    
         
            +
              CS_MSG_CMD            = 150
         
     | 
| 
      
 51 
     | 
    
         
            +
              CS_SEND_DATA_CMD      = 152
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
              # connection properties
         
     | 
| 
      
 54 
     | 
    
         
            +
              CS_USERNAME           = 9100
         
     | 
| 
      
 55 
     | 
    
         
            +
              CS_PASSWORD           = 9101
         
     | 
| 
      
 56 
     | 
    
         
            +
              CS_APPNAME            = 9102
         
     | 
| 
      
 57 
     | 
    
         
            +
              CS_HOSTNAME           = 9103
         
     | 
| 
      
 58 
     | 
    
         
            +
              CS_LOGIN_STATUS       = 9104
         
     | 
| 
      
 59 
     | 
    
         
            +
              CS_TDS_VERSION        = 9105
         
     | 
| 
      
 60 
     | 
    
         
            +
              CS_CHARSETCNV         = 9106
         
     | 
| 
      
 61 
     | 
    
         
            +
              CS_PACKETSIZE         = 9107
         
     | 
| 
      
 62 
     | 
    
         
            +
              CS_USERDATA           = 9108
         
     | 
| 
      
 63 
     | 
    
         
            +
              CS_COMMBLOCK          = 9109
         
     | 
| 
      
 64 
     | 
    
         
            +
              CS_NETIO              = 9110
         
     | 
| 
      
 65 
     | 
    
         
            +
              CS_NOINTERRUPT        = 9111
         
     | 
| 
      
 66 
     | 
    
         
            +
              CS_TEXTLIMIT          = 9112
         
     | 
| 
      
 67 
     | 
    
         
            +
              CS_HIDDEN_KEYS        = 9113
         
     | 
| 
      
 68 
     | 
    
         
            +
              CS_VERSION            = 9114
         
     | 
| 
      
 69 
     | 
    
         
            +
              CS_IFILE              = 9115
         
     | 
| 
      
 70 
     | 
    
         
            +
              CS_LOGIN_TIMEOUT      = 9116
         
     | 
| 
      
 71 
     | 
    
         
            +
              CS_TIMEOUT            = 9117
         
     | 
| 
      
 72 
     | 
    
         
            +
              CS_MAX_CONNECT        = 9118
         
     | 
| 
      
 73 
     | 
    
         
            +
              CS_EXPOSE_FMTS        = 9120
         
     | 
| 
      
 74 
     | 
    
         
            +
              CS_EXTRA_INF          = 9121
         
     | 
| 
      
 75 
     | 
    
         
            +
              CS_TRANSACTION_NAME   = 9122
         
     | 
| 
      
 76 
     | 
    
         
            +
              CS_ANSI_BINDS         = 9123
         
     | 
| 
      
 77 
     | 
    
         
            +
              CS_BULK_LOGIN         = 9124
         
     | 
| 
      
 78 
     | 
    
         
            +
              CS_LOC_PROP           = 9125
         
     | 
| 
      
 79 
     | 
    
         
            +
              CS_CUR_STATUS         = 9126
         
     | 
| 
      
 80 
     | 
    
         
            +
              CS_CUR_ID             = 9127
         
     | 
| 
      
 81 
     | 
    
         
            +
              CS_CUR_NAME           = 9128
         
     | 
| 
      
 82 
     | 
    
         
            +
              CS_CUR_ROWCOUNT       = 9129
         
     | 
| 
      
 83 
     | 
    
         
            +
              CS_PARENT_HANDLE      = 9130
         
     | 
| 
      
 84 
     | 
    
         
            +
              CS_EED_CMD            = 9131
         
     | 
| 
      
 85 
     | 
    
         
            +
              CS_DIAG_TIMEOUT       = 9132
         
     | 
| 
      
 86 
     | 
    
         
            +
              CS_DISABLE_POLL       = 9133
         
     | 
| 
      
 87 
     | 
    
         
            +
              CS_NOTIF_CMD          = 9134
         
     | 
| 
      
 88 
     | 
    
         
            +
              CS_SEC_ENCRYPTION     = 9135
         
     | 
| 
      
 89 
     | 
    
         
            +
              CS_SEC_CHALLENGE      = 9136
         
     | 
| 
      
 90 
     | 
    
         
            +
              CS_SEC_NEGOTIATE      = 9137
         
     | 
| 
      
 91 
     | 
    
         
            +
              CS_MEM_POOL           = 9138
         
     | 
| 
      
 92 
     | 
    
         
            +
              CS_USER_ALLOC         = 9139
         
     | 
| 
      
 93 
     | 
    
         
            +
              CS_USER_FREE          = 9140
         
     | 
| 
      
 94 
     | 
    
         
            +
              CS_ENDPOINT           = 9141
         
     | 
| 
      
 95 
     | 
    
         
            +
              CS_NO_TRUNCATE        = 9142
         
     | 
| 
      
 96 
     | 
    
         
            +
              CS_CON_STATUS         = 9143
         
     | 
| 
      
 97 
     | 
    
         
            +
              CS_VER_STRING         = 9144
         
     | 
| 
      
 98 
     | 
    
         
            +
              CS_ASYNC_NOTIFS       = 9145
         
     | 
| 
      
 99 
     | 
    
         
            +
              CS_SERVERNAME         = 9146
         
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
      
 101 
     | 
    
         
            +
              CS_SEND_BULK_CMD      = 153
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
      
 103 
     | 
    
         
            +
              # ct_results
         
     | 
| 
      
 104 
     | 
    
         
            +
              CS_ROW_RESULT         = 4040
         
     | 
| 
      
 105 
     | 
    
         
            +
              CS_CURSOR_RESULT      = 4041
         
     | 
| 
      
 106 
     | 
    
         
            +
              CS_PARAM_RESULT       = 4042
         
     | 
| 
      
 107 
     | 
    
         
            +
              CS_STATUS_RESULT      = 4043
         
     | 
| 
      
 108 
     | 
    
         
            +
              CS_MSG_RESULT         = 4044
         
     | 
| 
      
 109 
     | 
    
         
            +
              CS_COMPUTE_RESULT     = 4045
         
     | 
| 
      
 110 
     | 
    
         
            +
              CS_CMD_DONE           = 4046
         
     | 
| 
      
 111 
     | 
    
         
            +
              CS_CMD_SUCCEED        = 4047
         
     | 
| 
      
 112 
     | 
    
         
            +
              CS_CMD_FAIL           = 4048
         
     | 
| 
      
 113 
     | 
    
         
            +
              CS_ROWFMT_RESULT      = 4049
         
     | 
| 
      
 114 
     | 
    
         
            +
              CS_COMPUTEFMT_RESULT  = 4050
         
     | 
| 
      
 115 
     | 
    
         
            +
              CS_DESCRIBE_RESULT    = 4051
         
     | 
| 
      
 116 
     | 
    
         
            +
              CS_END_RESULTS        = CS_EXTERNAL_ERR - 5
         
     | 
| 
      
 117 
     | 
    
         
            +
             
     | 
| 
      
 118 
     | 
    
         
            +
              # ct_res_info
         
     | 
| 
      
 119 
     | 
    
         
            +
              CS_ROW_COUNT          = 800
         
     | 
| 
      
 120 
     | 
    
         
            +
              CS_NUMDATA            = 803
         
     | 
| 
      
 121 
     | 
    
         
            +
              CS_MSGTYPE            = 806
         
     | 
| 
      
 122 
     | 
    
         
            +
              CS_TRANS_STATE        = 808
         
     | 
| 
      
 123 
     | 
    
         
            +
             
     | 
| 
      
 124 
     | 
    
         
            +
              # ct_fetch
         
     | 
| 
      
 125 
     | 
    
         
            +
              CS_ROW_FAIL           = CS_EXTERNAL_ERR - 3
         
     | 
| 
      
 126 
     | 
    
         
            +
              CS_END_DATA           = CS_EXTERNAL_ERR - 4
         
     | 
| 
      
 127 
     | 
    
         
            +
             
     | 
| 
      
 128 
     | 
    
         
            +
              # data types
         
     | 
| 
      
 129 
     | 
    
         
            +
              CS_ILLEGAL_TYPE       = -1
         
     | 
| 
      
 130 
     | 
    
         
            +
              CS_CHAR_TYPE          = 0
         
     | 
| 
      
 131 
     | 
    
         
            +
              CS_BINARY_TYPE        = 1
         
     | 
| 
      
 132 
     | 
    
         
            +
              CS_LONGCHAR_TYPE      = 2
         
     | 
| 
      
 133 
     | 
    
         
            +
              CS_LONGBINARY_TYPE    = 3
         
     | 
| 
      
 134 
     | 
    
         
            +
              CS_TEXT_TYPE          = 4
         
     | 
| 
      
 135 
     | 
    
         
            +
              CS_IMAGE_TYPE         = 5
         
     | 
| 
      
 136 
     | 
    
         
            +
              CS_TINYINT_TYPE       = 6
         
     | 
| 
      
 137 
     | 
    
         
            +
              CS_SMALLINT_TYPE      = 7
         
     | 
| 
      
 138 
     | 
    
         
            +
              CS_INT_TYPE           = 8
         
     | 
| 
      
 139 
     | 
    
         
            +
              CS_REAL_TYPE          = 9
         
     | 
| 
      
 140 
     | 
    
         
            +
              CS_FLOAT_TYPE         = 10
         
     | 
| 
      
 141 
     | 
    
         
            +
              CS_BIT_TYPE           = 11
         
     | 
| 
      
 142 
     | 
    
         
            +
              CS_DATETIME_TYPE      = 12
         
     | 
| 
      
 143 
     | 
    
         
            +
              CS_DATETIME4_TYPE     = 13
         
     | 
| 
      
 144 
     | 
    
         
            +
              CS_MONEY_TYPE         = 14
         
     | 
| 
      
 145 
     | 
    
         
            +
              CS_MONEY4_TYPE        = 15
         
     | 
| 
      
 146 
     | 
    
         
            +
              CS_NUMERIC_TYPE       = 16
         
     | 
| 
      
 147 
     | 
    
         
            +
              CS_DECIMAL_TYPE       = 17
         
     | 
| 
      
 148 
     | 
    
         
            +
              CS_VARCHAR_TYPE       = 18
         
     | 
| 
      
 149 
     | 
    
         
            +
              CS_VARBINARY_TYPE     = 19
         
     | 
| 
      
 150 
     | 
    
         
            +
              CS_LONG_TYPE          = 20
         
     | 
| 
      
 151 
     | 
    
         
            +
              CS_SENSITIVITY_TYPE   = 21
         
     | 
| 
      
 152 
     | 
    
         
            +
              CS_BOUNDARY_TYPE      = 22
         
     | 
| 
      
 153 
     | 
    
         
            +
              CS_VOID_TYPE          = 23
         
     | 
| 
      
 154 
     | 
    
         
            +
              CS_USHORT_TYPE        = 24
         
     | 
| 
      
 155 
     | 
    
         
            +
              CS_UNICHAR_TYPE       = 25
         
     | 
| 
      
 156 
     | 
    
         
            +
              CS_BLOB_TYPE          = 26
         
     | 
| 
      
 157 
     | 
    
         
            +
              CS_DATE_TYPE          = 27
         
     | 
| 
      
 158 
     | 
    
         
            +
              CS_TIME_TYPE          = 28
         
     | 
| 
      
 159 
     | 
    
         
            +
              CS_UNITEXT_TYPE       = 29
         
     | 
| 
      
 160 
     | 
    
         
            +
              CS_BIGINT_TYPE        = 30
         
     | 
| 
      
 161 
     | 
    
         
            +
              CS_USMALLINT_TYPE     = 31
         
     | 
| 
      
 162 
     | 
    
         
            +
              CS_UINT_TYPE          = 32
         
     | 
| 
      
 163 
     | 
    
         
            +
              CS_UBIGINT_TYPE       = 33
         
     | 
| 
      
 164 
     | 
    
         
            +
              CS_XML_TYPE           = 34
         
     | 
| 
      
 165 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,71 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Sybase
         
     | 
| 
      
 2 
     | 
    
         
            +
              class Context
         
     | 
| 
      
 3 
     | 
    
         
            +
                def initialize(version = DEFAULT_CTLIB_VERSION)
         
     | 
| 
      
 4 
     | 
    
         
            +
                  @version = Integer(version)
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
                  FFI::MemoryPointer.new(:pointer) do |ptr|
         
     | 
| 
      
 7 
     | 
    
         
            +
                    Lib.check Lib.cs_ctx_alloc(@version, ptr), "cs_ctx_alloc failed"
         
     | 
| 
      
 8 
     | 
    
         
            +
                    @ptr = FFI::AutoPointer.new(ptr.read_pointer, Lib.method(:cs_ctx_drop))
         
     | 
| 
      
 9 
     | 
    
         
            +
                  end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                  Lib.check Lib.ct_init(@ptr, @version), "ct_init failed"
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                  if block_given?
         
     | 
| 
      
 14 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 15 
     | 
    
         
            +
                      yield self
         
     | 
| 
      
 16 
     | 
    
         
            +
                    ensure
         
     | 
| 
      
 17 
     | 
    
         
            +
                      exit
         
     | 
| 
      
 18 
     | 
    
         
            +
                    end
         
     | 
| 
      
 19 
     | 
    
         
            +
                  end
         
     | 
| 
      
 20 
     | 
    
         
            +
                end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                def sync=(bool)
         
     | 
| 
      
 23 
     | 
    
         
            +
                  FFI::MemoryPointer.new(:int) do |ptr|
         
     | 
| 
      
 24 
     | 
    
         
            +
                    ptr.write_int(bool ? CS_SYNC_IO : CS_ASYNC_IO) # CS_DEFER_IO ?
         
     | 
| 
      
 25 
     | 
    
         
            +
                    Lib.check Lib.ct_config(@ptr, CS_SET, CS_NETIO, ptr, CS_UNUSED, nil)
         
     | 
| 
      
 26 
     | 
    
         
            +
                  end
         
     | 
| 
      
 27 
     | 
    
         
            +
                end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                def callbacks
         
     | 
| 
      
 30 
     | 
    
         
            +
                  @callbacks ||= Callbacks.new self
         
     | 
| 
      
 31 
     | 
    
         
            +
                end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                def to_ptr
         
     | 
| 
      
 34 
     | 
    
         
            +
                  @ptr
         
     | 
| 
      
 35 
     | 
    
         
            +
                end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                def exit
         
     | 
| 
      
 38 
     | 
    
         
            +
                  Lib.check Lib.ct_exit(@ptr, CS_UNUSED), "ct_exit failed"
         
     | 
| 
      
 39 
     | 
    
         
            +
                end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                private
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                class Callbacks
         
     | 
| 
      
 44 
     | 
    
         
            +
                  def initialize(context)
         
     | 
| 
      
 45 
     | 
    
         
            +
                    @context = context
         
     | 
| 
      
 46 
     | 
    
         
            +
                  end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                  def library(&cb)
         
     | 
| 
      
 49 
     | 
    
         
            +
                    actual_callback = FFI::Function.new(:int, [:pointer, :pointer]) { |context, message|
         
     | 
| 
      
 50 
     | 
    
         
            +
                      cb.call ClientMessage.new(message)
         
     | 
| 
      
 51 
     | 
    
         
            +
                      CS_SUCCEED
         
     | 
| 
      
 52 
     | 
    
         
            +
                    }
         
     | 
| 
      
 53 
     | 
    
         
            +
                    Lib.check Lib.cs_config(@context, CS_SET, CS_MESSAGE_CB, actual_callback, CS_UNUSED, nil)
         
     | 
| 
      
 54 
     | 
    
         
            +
                  end
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
                  def client(&cb)
         
     | 
| 
      
 57 
     | 
    
         
            +
                    Lib.check Lib.ct_callback(@context, nil, CS_SET, CS_CLIENTMSG_CB, lambda { |context, connection, message|
         
     | 
| 
      
 58 
     | 
    
         
            +
                      cb.call ClientMessage.new(message)
         
     | 
| 
      
 59 
     | 
    
         
            +
                      CS_SUCCEED
         
     | 
| 
      
 60 
     | 
    
         
            +
                    })
         
     | 
| 
      
 61 
     | 
    
         
            +
                  end
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                  def server(&cb)
         
     | 
| 
      
 64 
     | 
    
         
            +
                    Lib.check Lib.ct_callback(@context, nil, CS_SET, CS_SERVERMSG_CB, lambda { |context, connection, message|
         
     | 
| 
      
 65 
     | 
    
         
            +
                        cb.call ServerMessage.new(message)
         
     | 
| 
      
 66 
     | 
    
         
            +
                        CS_SUCCEED
         
     | 
| 
      
 67 
     | 
    
         
            +
                    })
         
     | 
| 
      
 68 
     | 
    
         
            +
                  end
         
     | 
| 
      
 69 
     | 
    
         
            +
                end # Callbacks
         
     | 
| 
      
 70 
     | 
    
         
            +
              end # Context
         
     | 
| 
      
 71 
     | 
    
         
            +
            end # Sybase
         
     | 
    
        data/lib/sybase/lib.rb
    ADDED
    
    | 
         @@ -0,0 +1,264 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Sybase
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Lib
         
     | 
| 
      
 3 
     | 
    
         
            +
                extend FFI::Library
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
                suffix = RUBY_VERSION < '1.9' ? '' : '_r'
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                if FFI.type_size(:pointer) == 8
         
     | 
| 
      
 8 
     | 
    
         
            +
                  ffi_lib "sybct64#{suffix}"
         
     | 
| 
      
 9 
     | 
    
         
            +
                else
         
     | 
| 
      
 10 
     | 
    
         
            +
                  ffi_lib "sybct#{suffix}"
         
     | 
| 
      
 11 
     | 
    
         
            +
                end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                # extern CS_RETCODE CS_PUBLIC cs_ctx_alloc PROTOTYPE((
         
     | 
| 
      
 14 
     | 
    
         
            +
                #     CS_INT version,
         
     | 
| 
      
 15 
     | 
    
         
            +
                #     CS_CONTEXT **outptr
         
     | 
| 
      
 16 
     | 
    
         
            +
                #     ));
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                attach_function :cs_ctx_alloc, [:int, :pointer], :int
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                # extern CS_RETCODE CS_PUBLIC cs_ctx_drop PROTOTYPE((
         
     | 
| 
      
 21 
     | 
    
         
            +
                #     CS_CONTEXT *context
         
     | 
| 
      
 22 
     | 
    
         
            +
                #     ));
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                attach_function :cs_ctx_drop, [:pointer], :int
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                # extern CS_RETCODE CS_PUBLIC ct_init PROTOTYPE((
         
     | 
| 
      
 27 
     | 
    
         
            +
                #     CS_CONTEXT *context,
         
     | 
| 
      
 28 
     | 
    
         
            +
                #     CS_INT version
         
     | 
| 
      
 29 
     | 
    
         
            +
                #     ));
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                attach_function :ct_init, [:pointer, :int], :int
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                # extern CS_RETCODE CS_PUBLIC ct_config PROTOTYPE((
         
     | 
| 
      
 34 
     | 
    
         
            +
                #     CS_CONTEXT *context,
         
     | 
| 
      
 35 
     | 
    
         
            +
                #     CS_INT action,
         
     | 
| 
      
 36 
     | 
    
         
            +
                #     CS_INT property,
         
     | 
| 
      
 37 
     | 
    
         
            +
                #     CS_VOID *buf,
         
     | 
| 
      
 38 
     | 
    
         
            +
                #     CS_INT buflen,
         
     | 
| 
      
 39 
     | 
    
         
            +
                #     CS_INT *outlen
         
     | 
| 
      
 40 
     | 
    
         
            +
                #     ));
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                attach_function :ct_config, [:pointer, :int, :int, :pointer, :int, :pointer], :int
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                # extern CS_RETCODE CS_PUBLIC cs_config PROTOTYPE((
         
     | 
| 
      
 45 
     | 
    
         
            +
                #     CS_CONTEXT *context,
         
     | 
| 
      
 46 
     | 
    
         
            +
                #     CS_INT action,
         
     | 
| 
      
 47 
     | 
    
         
            +
                #     CS_INT property,
         
     | 
| 
      
 48 
     | 
    
         
            +
                #     CS_VOID *buf,
         
     | 
| 
      
 49 
     | 
    
         
            +
                #     CS_INT buflen,
         
     | 
| 
      
 50 
     | 
    
         
            +
                #     CS_INT *outlen
         
     | 
| 
      
 51 
     | 
    
         
            +
                #     ));
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                attach_function :cs_config, [:pointer, :int, :int, :pointer, :int, :pointer], :int
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                callback :cs_clientmsg_cb, [:pointer, :pointer, :pointer], :int
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                # extern CS_RETCODE CS_PUBLIC ct_callback PROTOTYPE((
         
     | 
| 
      
 60 
     | 
    
         
            +
                #     CS_CONTEXT *context,
         
     | 
| 
      
 61 
     | 
    
         
            +
                #     CS_CONNECTION *connection,
         
     | 
| 
      
 62 
     | 
    
         
            +
                #     CS_INT action,
         
     | 
| 
      
 63 
     | 
    
         
            +
                #     CS_INT type,
         
     | 
| 
      
 64 
     | 
    
         
            +
                #     CS_VOID *func
         
     | 
| 
      
 65 
     | 
    
         
            +
                #     ));
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
                attach_function :ct_callback, [:pointer, :pointer, :int, :int, :cs_clientmsg_cb], :int
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
                # extern CS_RETCODE CS_PUBLIC ct_con_alloc PROTOTYPE((
         
     | 
| 
      
 70 
     | 
    
         
            +
                #     CS_CONTEXT *context,
         
     | 
| 
      
 71 
     | 
    
         
            +
                #     CS_CONNECTION **connection
         
     | 
| 
      
 72 
     | 
    
         
            +
                #     ));
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
                attach_function :ct_con_alloc, [:pointer, :pointer], :int
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
                # extern CS_RETCODE CS_PUBLIC ct_con_props PROTOTYPE((
         
     | 
| 
      
 77 
     | 
    
         
            +
                #     CS_CONNECTION *connection,
         
     | 
| 
      
 78 
     | 
    
         
            +
                #     CS_INT action,
         
     | 
| 
      
 79 
     | 
    
         
            +
                #     CS_INT property,
         
     | 
| 
      
 80 
     | 
    
         
            +
                #     CS_VOID *buf,
         
     | 
| 
      
 81 
     | 
    
         
            +
                #     CS_INT buflen,
         
     | 
| 
      
 82 
     | 
    
         
            +
                #     CS_INT *outlen
         
     | 
| 
      
 83 
     | 
    
         
            +
                #     ));
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
                attach_function :ct_con_props, [:pointer, :int, :int, :pointer, :int, :pointer], :int
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
                # extern CS_RETCODE CS_PUBLIC ct_connect PROTOTYPE((
         
     | 
| 
      
 88 
     | 
    
         
            +
                #     CS_CONNECTION *connection,
         
     | 
| 
      
 89 
     | 
    
         
            +
                #     CS_CHAR *server_name,
         
     | 
| 
      
 90 
     | 
    
         
            +
                #     CS_INT snamelen
         
     | 
| 
      
 91 
     | 
    
         
            +
                #     ));
         
     | 
| 
      
 92 
     | 
    
         
            +
             
     | 
| 
      
 93 
     | 
    
         
            +
                attach_function :ct_connect, [:pointer, :pointer, :int], :int
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
      
 95 
     | 
    
         
            +
                # extern CS_RETCODE CS_PUBLIC ct_close PROTOTYPE((
         
     | 
| 
      
 96 
     | 
    
         
            +
                #     CS_CONNECTION *connection,
         
     | 
| 
      
 97 
     | 
    
         
            +
                #     CS_INT option
         
     | 
| 
      
 98 
     | 
    
         
            +
                #     ));
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
                attach_function :ct_close, [:pointer, :int], :int
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
      
 102 
     | 
    
         
            +
                # extern CS_RETCODE CS_PUBLIC ct_cmd_alloc PROTOTYPE((
         
     | 
| 
      
 103 
     | 
    
         
            +
                #     CS_CONNECTION *connection,
         
     | 
| 
      
 104 
     | 
    
         
            +
                #     CS_COMMAND **cmdptr
         
     | 
| 
      
 105 
     | 
    
         
            +
                #     ));
         
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
      
 107 
     | 
    
         
            +
                attach_function :ct_cmd_alloc, [:pointer, :pointer], :int
         
     | 
| 
      
 108 
     | 
    
         
            +
             
     | 
| 
      
 109 
     | 
    
         
            +
                # extern CS_RETCODE CS_PUBLIC ct_cmd_drop PROTOTYPE((
         
     | 
| 
      
 110 
     | 
    
         
            +
                #     CS_COMMAND *cmd
         
     | 
| 
      
 111 
     | 
    
         
            +
                #     ));
         
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
      
 113 
     | 
    
         
            +
                attach_function :ct_cmd_drop, [:pointer], :int
         
     | 
| 
      
 114 
     | 
    
         
            +
             
     | 
| 
      
 115 
     | 
    
         
            +
                # extern CS_RETCODE CS_PUBLIC ct_cmd_props PROTOTYPE((
         
     | 
| 
      
 116 
     | 
    
         
            +
                #     CS_COMMAND *cmd,
         
     | 
| 
      
 117 
     | 
    
         
            +
                #     CS_INT action,
         
     | 
| 
      
 118 
     | 
    
         
            +
                #     CS_INT property,
         
     | 
| 
      
 119 
     | 
    
         
            +
                #     CS_VOID *buf,
         
     | 
| 
      
 120 
     | 
    
         
            +
                #     CS_INT buflen,
         
     | 
| 
      
 121 
     | 
    
         
            +
                #     CS_INT *outlen
         
     | 
| 
      
 122 
     | 
    
         
            +
                #     ));
         
     | 
| 
      
 123 
     | 
    
         
            +
             
     | 
| 
      
 124 
     | 
    
         
            +
                attach_function :ct_cmd_props, [:pointer, :int, :int, :pointer, :int, :pointer], :int
         
     | 
| 
      
 125 
     | 
    
         
            +
             
     | 
| 
      
 126 
     | 
    
         
            +
                # extern CS_RETCODE CS_PUBLIC ct_command PROTOTYPE((
         
     | 
| 
      
 127 
     | 
    
         
            +
                #     CS_COMMAND *cmd,
         
     | 
| 
      
 128 
     | 
    
         
            +
                #     CS_INT type,
         
     | 
| 
      
 129 
     | 
    
         
            +
                #     CS_CHAR *buf,
         
     | 
| 
      
 130 
     | 
    
         
            +
                #     CS_INT buflen,
         
     | 
| 
      
 131 
     | 
    
         
            +
                #     CS_INT option
         
     | 
| 
      
 132 
     | 
    
         
            +
                #     ));
         
     | 
| 
      
 133 
     | 
    
         
            +
             
     | 
| 
      
 134 
     | 
    
         
            +
                attach_function :ct_command, [:pointer, :int, :string, :int, :int], :int
         
     | 
| 
      
 135 
     | 
    
         
            +
             
     | 
| 
      
 136 
     | 
    
         
            +
                # extern CS_RETCODE CS_PUBLIC ct_send PROTOTYPE((
         
     | 
| 
      
 137 
     | 
    
         
            +
                #     CS_COMMAND *cmd
         
     | 
| 
      
 138 
     | 
    
         
            +
                #     ));
         
     | 
| 
      
 139 
     | 
    
         
            +
             
     | 
| 
      
 140 
     | 
    
         
            +
                attach_function :ct_send, [:pointer], :int
         
     | 
| 
      
 141 
     | 
    
         
            +
             
     | 
| 
      
 142 
     | 
    
         
            +
                # extern CS_RETCODE CS_PUBLIC ct_results PROTOTYPE((
         
     | 
| 
      
 143 
     | 
    
         
            +
                #     CS_COMMAND *cmd,
         
     | 
| 
      
 144 
     | 
    
         
            +
                #     CS_INT *result_type
         
     | 
| 
      
 145 
     | 
    
         
            +
                #     ));
         
     | 
| 
      
 146 
     | 
    
         
            +
             
     | 
| 
      
 147 
     | 
    
         
            +
                attach_function :ct_results, [:pointer, :pointer], :int
         
     | 
| 
      
 148 
     | 
    
         
            +
             
     | 
| 
      
 149 
     | 
    
         
            +
                # extern CS_RETCODE CS_PUBLIC ct_close PROTOTYPE((
         
     | 
| 
      
 150 
     | 
    
         
            +
                #     CS_CONNECTION *connection,
         
     | 
| 
      
 151 
     | 
    
         
            +
                #     CS_INT option
         
     | 
| 
      
 152 
     | 
    
         
            +
                #     ));
         
     | 
| 
      
 153 
     | 
    
         
            +
             
     | 
| 
      
 154 
     | 
    
         
            +
                attach_function :close, [:pointer, :int], :int
         
     | 
| 
      
 155 
     | 
    
         
            +
             
     | 
| 
      
 156 
     | 
    
         
            +
                # extern CS_RETCODE CS_PUBLIC ct_exit PROTOTYPE((
         
     | 
| 
      
 157 
     | 
    
         
            +
                #     CS_CONTEXT *context,
         
     | 
| 
      
 158 
     | 
    
         
            +
                #     CS_INT option
         
     | 
| 
      
 159 
     | 
    
         
            +
                #     ));
         
     | 
| 
      
 160 
     | 
    
         
            +
             
     | 
| 
      
 161 
     | 
    
         
            +
                attach_function :ct_exit, [:pointer, :int], :int
         
     | 
| 
      
 162 
     | 
    
         
            +
             
     | 
| 
      
 163 
     | 
    
         
            +
                # extern CS_RETCODE CS_PUBLIC ct_con_drop PROTOTYPE((
         
     | 
| 
      
 164 
     | 
    
         
            +
                #     CS_CONNECTION *connection
         
     | 
| 
      
 165 
     | 
    
         
            +
                #     ));
         
     | 
| 
      
 166 
     | 
    
         
            +
             
     | 
| 
      
 167 
     | 
    
         
            +
                attach_function :ct_con_drop, [:pointer], :int
         
     | 
| 
      
 168 
     | 
    
         
            +
             
     | 
| 
      
 169 
     | 
    
         
            +
                # extern CS_RETCODE CS_PUBLIC ct_cancel PROTOTYPE((
         
     | 
| 
      
 170 
     | 
    
         
            +
                #   CS_CONNECTION *connection,
         
     | 
| 
      
 171 
     | 
    
         
            +
                #   CS_COMMAND *cmd,
         
     | 
| 
      
 172 
     | 
    
         
            +
                #   CS_INT type
         
     | 
| 
      
 173 
     | 
    
         
            +
                #   ));
         
     | 
| 
      
 174 
     | 
    
         
            +
             
     | 
| 
      
 175 
     | 
    
         
            +
                attach_function :ct_cancel, [:pointer, :pointer, :int], :int
         
     | 
| 
      
 176 
     | 
    
         
            +
             
     | 
| 
      
 177 
     | 
    
         
            +
                # extern CS_RETCODE CS_PUBLIC ct_res_info PROTOTYPE((
         
     | 
| 
      
 178 
     | 
    
         
            +
                #   CS_COMMAND *cmd,
         
     | 
| 
      
 179 
     | 
    
         
            +
                #   CS_INT operation,
         
     | 
| 
      
 180 
     | 
    
         
            +
                #   CS_VOID *buf,
         
     | 
| 
      
 181 
     | 
    
         
            +
                #   CS_INT buflen,
         
     | 
| 
      
 182 
     | 
    
         
            +
                #   CS_INT *outlen
         
     | 
| 
      
 183 
     | 
    
         
            +
                #   ));
         
     | 
| 
      
 184 
     | 
    
         
            +
             
     | 
| 
      
 185 
     | 
    
         
            +
                attach_function :ct_res_info, [:pointer, :int, :pointer, :int, :pointer], :int
         
     | 
| 
      
 186 
     | 
    
         
            +
             
     | 
| 
      
 187 
     | 
    
         
            +
             
     | 
| 
      
 188 
     | 
    
         
            +
                # extern CS_RETCODE CS_PUBLIC ct_describe PROTOTYPE((
         
     | 
| 
      
 189 
     | 
    
         
            +
                #     CS_COMMAND *cmd,
         
     | 
| 
      
 190 
     | 
    
         
            +
                #     CS_INT item,
         
     | 
| 
      
 191 
     | 
    
         
            +
                #     CS_DATAFMT *datafmt
         
     | 
| 
      
 192 
     | 
    
         
            +
                #     ));
         
     | 
| 
      
 193 
     | 
    
         
            +
             
     | 
| 
      
 194 
     | 
    
         
            +
                attach_function :ct_describe, [:pointer, :int, :pointer], :int
         
     | 
| 
      
 195 
     | 
    
         
            +
             
     | 
| 
      
 196 
     | 
    
         
            +
                # extern CS_RETCODE CS_PUBLIC ct_bind PROTOTYPE((
         
     | 
| 
      
 197 
     | 
    
         
            +
                #   CS_COMMAND *cmd,
         
     | 
| 
      
 198 
     | 
    
         
            +
                #   CS_INT item,
         
     | 
| 
      
 199 
     | 
    
         
            +
                #   CS_DATAFMT *datafmt,
         
     | 
| 
      
 200 
     | 
    
         
            +
                #   CS_VOID *buf,
         
     | 
| 
      
 201 
     | 
    
         
            +
                #   CS_INT *outputlen,
         
     | 
| 
      
 202 
     | 
    
         
            +
                #   CS_SMALLINT *indicator
         
     | 
| 
      
 203 
     | 
    
         
            +
                #   ));
         
     | 
| 
      
 204 
     | 
    
         
            +
             
     | 
| 
      
 205 
     | 
    
         
            +
                attach_function :ct_bind, [:pointer, :int, :pointer, :pointer, :pointer, :pointer], :int
         
     | 
| 
      
 206 
     | 
    
         
            +
             
     | 
| 
      
 207 
     | 
    
         
            +
                # extern CS_RETCODE CS_PUBLIC ct_fetch PROTOTYPE((
         
     | 
| 
      
 208 
     | 
    
         
            +
                #   CS_COMMAND *cmd,
         
     | 
| 
      
 209 
     | 
    
         
            +
                #   CS_INT type,
         
     | 
| 
      
 210 
     | 
    
         
            +
                #   CS_INT offset,
         
     | 
| 
      
 211 
     | 
    
         
            +
                #   CS_INT option,
         
     | 
| 
      
 212 
     | 
    
         
            +
                #   CS_INT *count
         
     | 
| 
      
 213 
     | 
    
         
            +
                #   ));
         
     | 
| 
      
 214 
     | 
    
         
            +
             
     | 
| 
      
 215 
     | 
    
         
            +
                attach_function :ct_fetch, [:pointer, :int, :int, :int, :pointer], :int
         
     | 
| 
      
 216 
     | 
    
         
            +
             
     | 
| 
      
 217 
     | 
    
         
            +
                # extern CS_RETCODE CS_PUBLIC ct_debug PROTOTYPE((
         
     | 
| 
      
 218 
     | 
    
         
            +
                #     CS_CONTEXT *context,
         
     | 
| 
      
 219 
     | 
    
         
            +
                #     CS_CONNECTION *connection,
         
     | 
| 
      
 220 
     | 
    
         
            +
                #     CS_INT operation,
         
     | 
| 
      
 221 
     | 
    
         
            +
                #     CS_INT flag,
         
     | 
| 
      
 222 
     | 
    
         
            +
                #     CS_CHAR *filename,
         
     | 
| 
      
 223 
     | 
    
         
            +
                #     CS_INT fnamelen
         
     | 
| 
      
 224 
     | 
    
         
            +
                #     ));
         
     | 
| 
      
 225 
     | 
    
         
            +
             
     | 
| 
      
 226 
     | 
    
         
            +
                attach_function :ct_debug, [:pointer, :pointer, :int, :int, :pointer, :int], :int
         
     | 
| 
      
 227 
     | 
    
         
            +
             
     | 
| 
      
 228 
     | 
    
         
            +
                def self.check(code, msg = "error")
         
     | 
| 
      
 229 
     | 
    
         
            +
                  if code != CS_SUCCEED
         
     | 
| 
      
 230 
     | 
    
         
            +
                    raise Error, msg
         
     | 
| 
      
 231 
     | 
    
         
            +
                  end
         
     | 
| 
      
 232 
     | 
    
         
            +
                end
         
     | 
| 
      
 233 
     | 
    
         
            +
             
     | 
| 
      
 234 
     | 
    
         
            +
                def self.display_length(data_format)
         
     | 
| 
      
 235 
     | 
    
         
            +
                  len = case data_format[:datatype]
         
     | 
| 
      
 236 
     | 
    
         
            +
                        when CS_CHAR_TYPE, CS_LONGCHAR_TYPE, CS_VARCHAR_TYPE, CS_TEXT_TYPE, CS_IMAGE_TYPE
         
     | 
| 
      
 237 
     | 
    
         
            +
                          [data_format[:maxlength], MAX_CHAR_BUF].min
         
     | 
| 
      
 238 
     | 
    
         
            +
                        when CS_UNICHAR_TYPE
         
     | 
| 
      
 239 
     | 
    
         
            +
                          [data_format[:maxlength] / 2, MAX_CHAR_BUF].min
         
     | 
| 
      
 240 
     | 
    
         
            +
                        when CS_BINARY_TYPE, CS_VARBINARY_TYPE
         
     | 
| 
      
 241 
     | 
    
         
            +
                          [(2 * data_format[:maxlength]) + 2, MAX_CHAR_BUF].min
         
     | 
| 
      
 242 
     | 
    
         
            +
                        when CS_BIT_TYPE, CS_TINYINT_TYPE
         
     | 
| 
      
 243 
     | 
    
         
            +
                          3
         
     | 
| 
      
 244 
     | 
    
         
            +
                        when CS_SMALLINT_TYPE
         
     | 
| 
      
 245 
     | 
    
         
            +
                          6
         
     | 
| 
      
 246 
     | 
    
         
            +
                        when CS_INT_TYPE
         
     | 
| 
      
 247 
     | 
    
         
            +
                          11
         
     | 
| 
      
 248 
     | 
    
         
            +
                        when CS_REAL_TYPE, CS_FLOAT_TYPE
         
     | 
| 
      
 249 
     | 
    
         
            +
                          20
         
     | 
| 
      
 250 
     | 
    
         
            +
                        when CS_MONEY_TYPE, CS_MONEY4_TYPE
         
     | 
| 
      
 251 
     | 
    
         
            +
                          24
         
     | 
| 
      
 252 
     | 
    
         
            +
                        when CS_DATETIME_TYPE, CS_DATETIME4_TYPE
         
     | 
| 
      
 253 
     | 
    
         
            +
                          30
         
     | 
| 
      
 254 
     | 
    
         
            +
                        when CS_NUMERIC_TYPE, CS_DECIMAL_TYPE
         
     | 
| 
      
 255 
     | 
    
         
            +
                          CS_MAX_PREC + 2
         
     | 
| 
      
 256 
     | 
    
         
            +
                        else
         
     | 
| 
      
 257 
     | 
    
         
            +
                          12
         
     | 
| 
      
 258 
     | 
    
         
            +
                        end
         
     | 
| 
      
 259 
     | 
    
         
            +
             
     | 
| 
      
 260 
     | 
    
         
            +
             
     | 
| 
      
 261 
     | 
    
         
            +
                  [data_format[:name].size + 1, len].max
         
     | 
| 
      
 262 
     | 
    
         
            +
                end
         
     | 
| 
      
 263 
     | 
    
         
            +
              end # Lib
         
     | 
| 
      
 264 
     | 
    
         
            +
            end # Sybase
         
     | 
| 
         @@ -0,0 +1,33 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Sybase
         
     | 
| 
      
 2 
     | 
    
         
            +
              # typedef struct _cs_clientmsg
         
     | 
| 
      
 3 
     | 
    
         
            +
              # {
         
     | 
| 
      
 4 
     | 
    
         
            +
              #   CS_INT          severity;
         
     | 
| 
      
 5 
     | 
    
         
            +
              #   CS_MSGNUM       msgnumber;
         
     | 
| 
      
 6 
     | 
    
         
            +
              #   CS_CHAR         msgstring[CS_MAX_MSG];
         
     | 
| 
      
 7 
     | 
    
         
            +
              #   CS_INT          msgstringlen;
         
     | 
| 
      
 8 
     | 
    
         
            +
              #   CS_INT          osnumber;
         
     | 
| 
      
 9 
     | 
    
         
            +
              #   CS_CHAR         osstring[CS_MAX_MSG];
         
     | 
| 
      
 10 
     | 
    
         
            +
              #   CS_INT          osstringlen;
         
     | 
| 
      
 11 
     | 
    
         
            +
              #   CS_INT          status;
         
     | 
| 
      
 12 
     | 
    
         
            +
              #   CS_BYTE         sqlstate[CS_SQLSTATE_SIZE];
         
     | 
| 
      
 13 
     | 
    
         
            +
              #   CS_INT          sqlstatelen;
         
     | 
| 
      
 14 
     | 
    
         
            +
              # } CS_CLIENTMSG;
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
              class ClientMessage < Message
         
     | 
| 
      
 17 
     | 
    
         
            +
                layout :severity,     :int,
         
     | 
| 
      
 18 
     | 
    
         
            +
                       :msgnumber,    :uint,
         
     | 
| 
      
 19 
     | 
    
         
            +
                       :msgstring,    [:char, CS_MAX_MSG],
         
     | 
| 
      
 20 
     | 
    
         
            +
                       :msgstringlen, :int,
         
     | 
| 
      
 21 
     | 
    
         
            +
                       :osnumber,     :int,
         
     | 
| 
      
 22 
     | 
    
         
            +
                       :osstring,     [:char, CS_MAX_MSG],
         
     | 
| 
      
 23 
     | 
    
         
            +
                       :osstringlen,  :int,
         
     | 
| 
      
 24 
     | 
    
         
            +
                       :status,       :int,
         
     | 
| 
      
 25 
     | 
    
         
            +
                       :sqlstate,     [:uchar, CS_SQLSTATE_SIZE],
         
     | 
| 
      
 26 
     | 
    
         
            +
                       :sqlstatelen,  :int
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                def text
         
     | 
| 
      
 29 
     | 
    
         
            +
                  self[:msgstring].to_s.chomp
         
     | 
| 
      
 30 
     | 
    
         
            +
                end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
              end # ClientMessage
         
     | 
| 
      
 33 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,60 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Sybase
         
     | 
| 
      
 2 
     | 
    
         
            +
              class ColumnData
         
     | 
| 
      
 3 
     | 
    
         
            +
                attr_reader :pointer, :type, :format
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
                def initialize
         
     | 
| 
      
 6 
     | 
    
         
            +
                  @pointer = nil
         
     | 
| 
      
 7 
     | 
    
         
            +
                  @type = nil
         
     | 
| 
      
 8 
     | 
    
         
            +
                  @format = DataFormat.new
         
     | 
| 
      
 9 
     | 
    
         
            +
                end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                def inspect
         
     | 
| 
      
 12 
     | 
    
         
            +
                  "#<#{self.class}:0x#{(hash*2).to_s(16)} type=#{type.inspect} valuelen=#{valuelen} indicator=#{indicator}>"
         
     | 
| 
      
 13 
     | 
    
         
            +
                end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                def char_pointer!(size = 256)
         
     | 
| 
      
 16 
     | 
    
         
            +
                  @type = :char
         
     | 
| 
      
 17 
     | 
    
         
            +
                  @pointer = FFI::MemoryPointer.new(@type, size)
         
     | 
| 
      
 18 
     | 
    
         
            +
                end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                def int_pointer!
         
     | 
| 
      
 21 
     | 
    
         
            +
                  @type = :int
         
     | 
| 
      
 22 
     | 
    
         
            +
                  @pointer = FFI::MemoryPointer.new(@type)
         
     | 
| 
      
 23 
     | 
    
         
            +
                end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                def double_pointer!
         
     | 
| 
      
 26 
     | 
    
         
            +
                  @type = :double
         
     | 
| 
      
 27 
     | 
    
         
            +
                  @pointer = FFI::MemoryPointer.new(@type)
         
     | 
| 
      
 28 
     | 
    
         
            +
                end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                def valuelen_pointer
         
     | 
| 
      
 31 
     | 
    
         
            +
                  @valuelen_ptr ||= FFI::MemoryPointer.new(:int)
         
     | 
| 
      
 32 
     | 
    
         
            +
                end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                def indicator_pointer
         
     | 
| 
      
 35 
     | 
    
         
            +
                  @indicator_ptr ||= FFI::MemoryPointer.new(:int)
         
     | 
| 
      
 36 
     | 
    
         
            +
                end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                def valuelen
         
     | 
| 
      
 39 
     | 
    
         
            +
                  valuelen_pointer.read_int
         
     | 
| 
      
 40 
     | 
    
         
            +
                end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                def indicator
         
     | 
| 
      
 43 
     | 
    
         
            +
                  indicator_pointer.read_int
         
     | 
| 
      
 44 
     | 
    
         
            +
                end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                def value
         
     | 
| 
      
 47 
     | 
    
         
            +
                  case @type
         
     | 
| 
      
 48 
     | 
    
         
            +
                  when :int
         
     | 
| 
      
 49 
     | 
    
         
            +
                    @pointer.read_int
         
     | 
| 
      
 50 
     | 
    
         
            +
                  when :char
         
     | 
| 
      
 51 
     | 
    
         
            +
                    @pointer.get_bytes(0, valuelen - 1)
         
     | 
| 
      
 52 
     | 
    
         
            +
                  when :double
         
     | 
| 
      
 53 
     | 
    
         
            +
                    @pointer.read_double
         
     | 
| 
      
 54 
     | 
    
         
            +
                  else
         
     | 
| 
      
 55 
     | 
    
         
            +
                    raise Error, "uknown type #{type}"
         
     | 
| 
      
 56 
     | 
    
         
            +
                  end
         
     | 
| 
      
 57 
     | 
    
         
            +
                end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
              end
         
     | 
| 
      
 60 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,63 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Sybase
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
              # typedef struct _cs_datafmt
         
     | 
| 
      
 4 
     | 
    
         
            +
              # {
         
     | 
| 
      
 5 
     | 
    
         
            +
              #   CS_CHAR   name[CS_MAX_NAME]; // CS_MAX_CHAR if >= Sybase 15
         
     | 
| 
      
 6 
     | 
    
         
            +
              #   CS_INT    namelen;
         
     | 
| 
      
 7 
     | 
    
         
            +
              #   CS_INT    datatype;
         
     | 
| 
      
 8 
     | 
    
         
            +
              #   CS_INT    format;
         
     | 
| 
      
 9 
     | 
    
         
            +
              #   CS_INT    maxlength;
         
     | 
| 
      
 10 
     | 
    
         
            +
              #   CS_INT    scale;
         
     | 
| 
      
 11 
     | 
    
         
            +
              #   CS_INT    precision;
         
     | 
| 
      
 12 
     | 
    
         
            +
              #   CS_INT    status;
         
     | 
| 
      
 13 
     | 
    
         
            +
              #   CS_INT    count;
         
     | 
| 
      
 14 
     | 
    
         
            +
              #   CS_INT    usertype;
         
     | 
| 
      
 15 
     | 
    
         
            +
              #   CS_LOCALE *locale;
         
     | 
| 
      
 16 
     | 
    
         
            +
              # } CS_DATAFMT;
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
              class DataFormat < FFI::Struct
         
     | 
| 
      
 20 
     | 
    
         
            +
                attr_accessor :ruby_type
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                layout :name,       [:char, CS_MAX_CHAR],
         
     | 
| 
      
 23 
     | 
    
         
            +
                       :namelen,    :int,
         
     | 
| 
      
 24 
     | 
    
         
            +
                       :datatype,   :int,
         
     | 
| 
      
 25 
     | 
    
         
            +
                       :format,     :int,
         
     | 
| 
      
 26 
     | 
    
         
            +
                       :maxlength,  :int,
         
     | 
| 
      
 27 
     | 
    
         
            +
                       :scale,      :int,
         
     | 
| 
      
 28 
     | 
    
         
            +
                       :precision,  :int,
         
     | 
| 
      
 29 
     | 
    
         
            +
                       :status,     :int,
         
     | 
| 
      
 30 
     | 
    
         
            +
                       :count,      :int,
         
     | 
| 
      
 31 
     | 
    
         
            +
                       :usertype,   :int,
         
     | 
| 
      
 32 
     | 
    
         
            +
                       :locale,     :pointer
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                INTS = [:namelen, :datatype, :format, :maxlength, :scale, :precision, :status, :count, :usertype]
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                def reset!
         
     | 
| 
      
 37 
     | 
    
         
            +
                  INTS.each { |key| self[key] = 0 }
         
     | 
| 
      
 38 
     | 
    
         
            +
                end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                def inspect
         
     | 
| 
      
 41 
     | 
    
         
            +
                  "#<%s name=%s namelen=%d datatype=%d format=%d maxlength=%d scale=%d precision=%d status=%d count=%d usertype=%d locale=%s address=%x>" % [
         
     | 
| 
      
 42 
     | 
    
         
            +
                    self.class.name,
         
     | 
| 
      
 43 
     | 
    
         
            +
                    name.inspect,
         
     | 
| 
      
 44 
     | 
    
         
            +
                    self[:namelen],
         
     | 
| 
      
 45 
     | 
    
         
            +
                    self[:datatype],
         
     | 
| 
      
 46 
     | 
    
         
            +
                    self[:format],
         
     | 
| 
      
 47 
     | 
    
         
            +
                    self[:maxlength],
         
     | 
| 
      
 48 
     | 
    
         
            +
                    self[:scale],
         
     | 
| 
      
 49 
     | 
    
         
            +
                    self[:precision],
         
     | 
| 
      
 50 
     | 
    
         
            +
                    self[:status],
         
     | 
| 
      
 51 
     | 
    
         
            +
                    self[:count],
         
     | 
| 
      
 52 
     | 
    
         
            +
                    self[:usertype],
         
     | 
| 
      
 53 
     | 
    
         
            +
                    self[:locale].inspect,
         
     | 
| 
      
 54 
     | 
    
         
            +
                    to_ptr.address
         
     | 
| 
      
 55 
     | 
    
         
            +
                  ]
         
     | 
| 
      
 56 
     | 
    
         
            +
                end
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                def name
         
     | 
| 
      
 59 
     | 
    
         
            +
                  self[:name].to_s
         
     | 
| 
      
 60 
     | 
    
         
            +
                end
         
     | 
| 
      
 61 
     | 
    
         
            +
              end
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,27 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Sybase
         
     | 
| 
      
 2 
     | 
    
         
            +
              class Message < FFI::Struct
         
     | 
| 
      
 3 
     | 
    
         
            +
                def severity
         
     | 
| 
      
 4 
     | 
    
         
            +
                  (self[:severity] >> 8) & 0xff
         
     | 
| 
      
 5 
     | 
    
         
            +
                end
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                def number
         
     | 
| 
      
 8 
     | 
    
         
            +
                  self[:msgnumber] & 0xff
         
     | 
| 
      
 9 
     | 
    
         
            +
                end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                def origin
         
     | 
| 
      
 12 
     | 
    
         
            +
                  (self[:msgnumber]) >> 16 & 0xff
         
     | 
| 
      
 13 
     | 
    
         
            +
                end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                def layer
         
     | 
| 
      
 16 
     | 
    
         
            +
                  (self[:msgnumber] >> 24) & 0x44
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                def inspect
         
     | 
| 
      
 20 
     | 
    
         
            +
                  "#<%s text=%s severity=%d number=%d origin=%d layer=%d>" % [self.class.name, text.inspect, severity, number, origin, layer]
         
     | 
| 
      
 21 
     | 
    
         
            +
                end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                def to_s
         
     | 
| 
      
 24 
     | 
    
         
            +
                  "%s (severity=%d number=%d origin=%d layer=%d)" % [text, severity, number, origin, layer]
         
     | 
| 
      
 25 
     | 
    
         
            +
                end
         
     | 
| 
      
 26 
     | 
    
         
            +
              end
         
     | 
| 
      
 27 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,38 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Sybase
         
     | 
| 
      
 2 
     | 
    
         
            +
              # typedef struct _cs_servermsg
         
     | 
| 
      
 3 
     | 
    
         
            +
              # {
         
     | 
| 
      
 4 
     | 
    
         
            +
              #   CS_MSGNUM msgnumber;
         
     | 
| 
      
 5 
     | 
    
         
            +
              #   CS_INT            state;
         
     | 
| 
      
 6 
     | 
    
         
            +
              #   CS_INT            severity;
         
     | 
| 
      
 7 
     | 
    
         
            +
              #   CS_CHAR           text[CS_MAX_MSG];
         
     | 
| 
      
 8 
     | 
    
         
            +
              #   CS_INT            textlen;
         
     | 
| 
      
 9 
     | 
    
         
            +
              #   CS_CHAR           svrname[CS_MAX_CHAR];
         
     | 
| 
      
 10 
     | 
    
         
            +
              #   CS_INT            svrnlen;
         
     | 
| 
      
 11 
     | 
    
         
            +
              #   CS_CHAR           proc[CS_MAX_CHAR];
         
     | 
| 
      
 12 
     | 
    
         
            +
              #   CS_INT            proclen;
         
     | 
| 
      
 13 
     | 
    
         
            +
              #   CS_INT            line;
         
     | 
| 
      
 14 
     | 
    
         
            +
              #   CS_INT            status;
         
     | 
| 
      
 15 
     | 
    
         
            +
              #   CS_BYTE           sqlstate[CS_SQLSTATE_SIZE];
         
     | 
| 
      
 16 
     | 
    
         
            +
              #   CS_INT            sqlstatelen;
         
     | 
| 
      
 17 
     | 
    
         
            +
              # } CS_SERVERMSG;
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
              class ServerMessage < Message
         
     | 
| 
      
 20 
     | 
    
         
            +
                layout :msgnumber,   :uint,
         
     | 
| 
      
 21 
     | 
    
         
            +
                       :state,       :int,
         
     | 
| 
      
 22 
     | 
    
         
            +
                       :severity,    :int,
         
     | 
| 
      
 23 
     | 
    
         
            +
                       :text,        [:char, CS_MAX_MSG],
         
     | 
| 
      
 24 
     | 
    
         
            +
                       :textlen,     :int,
         
     | 
| 
      
 25 
     | 
    
         
            +
                       :svrname,     [:char, CS_MAX_CHAR],
         
     | 
| 
      
 26 
     | 
    
         
            +
                       :svrnlen,     :int,
         
     | 
| 
      
 27 
     | 
    
         
            +
                       :proc,        [:char, CS_MAX_CHAR],
         
     | 
| 
      
 28 
     | 
    
         
            +
                       :proclen,     :int,
         
     | 
| 
      
 29 
     | 
    
         
            +
                       :line,        :int,
         
     | 
| 
      
 30 
     | 
    
         
            +
                       :status,      :int,
         
     | 
| 
      
 31 
     | 
    
         
            +
                       :sqlstate,    [:uchar, CS_SQLSTATE_SIZE],
         
     | 
| 
      
 32 
     | 
    
         
            +
                       :sqlstatelen, :int
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                def text
         
     | 
| 
      
 35 
     | 
    
         
            +
                  self[:text].to_s.chomp
         
     | 
| 
      
 36 
     | 
    
         
            +
                end
         
     | 
| 
      
 37 
     | 
    
         
            +
              end
         
     | 
| 
      
 38 
     | 
    
         
            +
            end
         
     | 
    
        metadata
    ADDED
    
    | 
         @@ -0,0 +1,86 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            --- !ruby/object:Gem::Specification 
         
     | 
| 
      
 2 
     | 
    
         
            +
            name: ffi-sybase
         
     | 
| 
      
 3 
     | 
    
         
            +
            version: !ruby/object:Gem::Version 
         
     | 
| 
      
 4 
     | 
    
         
            +
              prerelease: 
         
     | 
| 
      
 5 
     | 
    
         
            +
              version: 0.0.1
         
     | 
| 
      
 6 
     | 
    
         
            +
            platform: ruby
         
     | 
| 
      
 7 
     | 
    
         
            +
            authors: 
         
     | 
| 
      
 8 
     | 
    
         
            +
            - Jari Bakken
         
     | 
| 
      
 9 
     | 
    
         
            +
            autorequire: 
         
     | 
| 
      
 10 
     | 
    
         
            +
            bindir: bin
         
     | 
| 
      
 11 
     | 
    
         
            +
            cert_chain: []
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            date: 2011-03-19 00:00:00 +01:00
         
     | 
| 
      
 14 
     | 
    
         
            +
            default_executable: 
         
     | 
| 
      
 15 
     | 
    
         
            +
            dependencies: 
         
     | 
| 
      
 16 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency 
         
     | 
| 
      
 17 
     | 
    
         
            +
              name: ffi
         
     | 
| 
      
 18 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 19 
     | 
    
         
            +
              requirement: &id001 !ruby/object:Gem::Requirement 
         
     | 
| 
      
 20 
     | 
    
         
            +
                none: false
         
     | 
| 
      
 21 
     | 
    
         
            +
                requirements: 
         
     | 
| 
      
 22 
     | 
    
         
            +
                - - ">="
         
     | 
| 
      
 23 
     | 
    
         
            +
                  - !ruby/object:Gem::Version 
         
     | 
| 
      
 24 
     | 
    
         
            +
                    version: 0.6.3
         
     | 
| 
      
 25 
     | 
    
         
            +
              type: :runtime
         
     | 
| 
      
 26 
     | 
    
         
            +
              version_requirements: *id001
         
     | 
| 
      
 27 
     | 
    
         
            +
            description: Ruby/FFI bindings for Sybase's Open Client library.
         
     | 
| 
      
 28 
     | 
    
         
            +
            email: 
         
     | 
| 
      
 29 
     | 
    
         
            +
            - jari.bakken@gmail.com
         
     | 
| 
      
 30 
     | 
    
         
            +
            executables: []
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
            extensions: []
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
            extra_rdoc_files: []
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
            files: 
         
     | 
| 
      
 37 
     | 
    
         
            +
            - .gitignore
         
     | 
| 
      
 38 
     | 
    
         
            +
            - Gemfile
         
     | 
| 
      
 39 
     | 
    
         
            +
            - LICENSE
         
     | 
| 
      
 40 
     | 
    
         
            +
            - README
         
     | 
| 
      
 41 
     | 
    
         
            +
            - Rakefile
         
     | 
| 
      
 42 
     | 
    
         
            +
            - TODO
         
     | 
| 
      
 43 
     | 
    
         
            +
            - examples/sp_who.rb
         
     | 
| 
      
 44 
     | 
    
         
            +
            - ffi-sybase.gemspec
         
     | 
| 
      
 45 
     | 
    
         
            +
            - lib/ffi-sybase.rb
         
     | 
| 
      
 46 
     | 
    
         
            +
            - lib/sybase/command.rb
         
     | 
| 
      
 47 
     | 
    
         
            +
            - lib/sybase/connection.rb
         
     | 
| 
      
 48 
     | 
    
         
            +
            - lib/sybase/constants.rb
         
     | 
| 
      
 49 
     | 
    
         
            +
            - lib/sybase/context.rb
         
     | 
| 
      
 50 
     | 
    
         
            +
            - lib/sybase/lib.rb
         
     | 
| 
      
 51 
     | 
    
         
            +
            - lib/sybase/structs/client_message.rb
         
     | 
| 
      
 52 
     | 
    
         
            +
            - lib/sybase/structs/column_data.rb
         
     | 
| 
      
 53 
     | 
    
         
            +
            - lib/sybase/structs/data_format.rb
         
     | 
| 
      
 54 
     | 
    
         
            +
            - lib/sybase/structs/message.rb
         
     | 
| 
      
 55 
     | 
    
         
            +
            - lib/sybase/structs/server_message.rb
         
     | 
| 
      
 56 
     | 
    
         
            +
            - lib/sybase/version.rb
         
     | 
| 
      
 57 
     | 
    
         
            +
            has_rdoc: true
         
     | 
| 
      
 58 
     | 
    
         
            +
            homepage: http://github.com/jarib/ffi-sybase
         
     | 
| 
      
 59 
     | 
    
         
            +
            licenses: []
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
            post_install_message: 
         
     | 
| 
      
 62 
     | 
    
         
            +
            rdoc_options: []
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
            require_paths: 
         
     | 
| 
      
 65 
     | 
    
         
            +
            - lib
         
     | 
| 
      
 66 
     | 
    
         
            +
            required_ruby_version: !ruby/object:Gem::Requirement 
         
     | 
| 
      
 67 
     | 
    
         
            +
              none: false
         
     | 
| 
      
 68 
     | 
    
         
            +
              requirements: 
         
     | 
| 
      
 69 
     | 
    
         
            +
              - - ">="
         
     | 
| 
      
 70 
     | 
    
         
            +
                - !ruby/object:Gem::Version 
         
     | 
| 
      
 71 
     | 
    
         
            +
                  version: "0"
         
     | 
| 
      
 72 
     | 
    
         
            +
            required_rubygems_version: !ruby/object:Gem::Requirement 
         
     | 
| 
      
 73 
     | 
    
         
            +
              none: false
         
     | 
| 
      
 74 
     | 
    
         
            +
              requirements: 
         
     | 
| 
      
 75 
     | 
    
         
            +
              - - ">="
         
     | 
| 
      
 76 
     | 
    
         
            +
                - !ruby/object:Gem::Version 
         
     | 
| 
      
 77 
     | 
    
         
            +
                  version: "0"
         
     | 
| 
      
 78 
     | 
    
         
            +
            requirements: []
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
            rubyforge_project: ffi-sybase
         
     | 
| 
      
 81 
     | 
    
         
            +
            rubygems_version: 1.5.2
         
     | 
| 
      
 82 
     | 
    
         
            +
            signing_key: 
         
     | 
| 
      
 83 
     | 
    
         
            +
            specification_version: 3
         
     | 
| 
      
 84 
     | 
    
         
            +
            summary: Ruby/FFI bindings for Sybase OCS
         
     | 
| 
      
 85 
     | 
    
         
            +
            test_files: []
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     |