tiny_tds 0.6.2-x64-mingw32
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.
- checksums.yaml +15 -0
- data/.gitignore +19 -0
- data/CHANGELOG +180 -0
- data/Gemfile +3 -0
- data/MIT-LICENSE +23 -0
- data/README.md +385 -0
- data/Rakefile +114 -0
- data/compile/rake-compiler-dev-box.patch +31 -0
- data/ext/patch/Makefile.in.diff +29 -0
- data/ext/patch/dblib-30-char-username.diff +11 -0
- data/ext/patch/sspi_w_kerberos.diff +42 -0
- data/ext/tiny_tds/client.c +408 -0
- data/ext/tiny_tds/client.h +46 -0
- data/ext/tiny_tds/extconf.rb +102 -0
- data/ext/tiny_tds/result.c +599 -0
- data/ext/tiny_tds/result.h +36 -0
- data/ext/tiny_tds/tiny_tds_ext.c +12 -0
- data/ext/tiny_tds/tiny_tds_ext.h +15 -0
- data/lib/tiny_tds.rb +19 -0
- data/lib/tiny_tds/client.rb +96 -0
- data/lib/tiny_tds/error.rb +29 -0
- data/lib/tiny_tds/result.rb +8 -0
- data/lib/tiny_tds/version.rb +3 -0
- data/tasks/ports.rake +79 -0
- data/test/benchmark/query.rb +77 -0
- data/test/benchmark/query_odbc.rb +106 -0
- data/test/benchmark/query_tinytds.rb +126 -0
- data/test/client_test.rb +170 -0
- data/test/result_test.rb +732 -0
- data/test/schema/1px.gif +0 -0
- data/test/schema/sqlserver_2000.sql +138 -0
- data/test/schema/sqlserver_2005.sql +138 -0
- data/test/schema/sqlserver_2008.sql +138 -0
- data/test/schema/sqlserver_azure.sql +138 -0
- data/test/schema/sybase_ase.sql +138 -0
- data/test/schema_test.rb +305 -0
- data/test/test_helper.rb +195 -0
- data/test/thread_test.rb +95 -0
- metadata +171 -0
| @@ -0,0 +1,36 @@ | |
| 1 | 
            +
             | 
| 2 | 
            +
            #ifndef TINYTDS_RESULT_H
         | 
| 3 | 
            +
            #define TINYTDS_RESULT_H
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            #ifndef DBSETLDBNAME
         | 
| 6 | 
            +
              typedef tds_sysdep_int64_type DBBIGINT;  /* For FreeTDS 0.82 */
         | 
| 7 | 
            +
            #endif
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            void init_tinytds_result();
         | 
| 10 | 
            +
            VALUE rb_tinytds_new_result_obj(tinytds_client_wrapper *cwrap);
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            typedef struct {
         | 
| 13 | 
            +
              tinytds_client_wrapper *cwrap;
         | 
| 14 | 
            +
              DBPROCESS *client;
         | 
| 15 | 
            +
              VALUE local_offset;
         | 
| 16 | 
            +
              VALUE fields;
         | 
| 17 | 
            +
              VALUE fields_processed;
         | 
| 18 | 
            +
              VALUE results;
         | 
| 19 | 
            +
              rb_encoding *encoding;
         | 
| 20 | 
            +
              VALUE dbresults_retcodes;
         | 
| 21 | 
            +
              unsigned int number_of_results;
         | 
| 22 | 
            +
              unsigned int number_of_fields;
         | 
| 23 | 
            +
              unsigned long number_of_rows;
         | 
| 24 | 
            +
            } tinytds_result_wrapper;
         | 
| 25 | 
            +
             | 
| 26 | 
            +
             | 
| 27 | 
            +
            // Lib Macros
         | 
| 28 | 
            +
             | 
| 29 | 
            +
            #define GET_RESULT_WRAPPER(self) \
         | 
| 30 | 
            +
              tinytds_result_wrapper *rwrap; \
         | 
| 31 | 
            +
              Data_Get_Struct(self, tinytds_result_wrapper, rwrap)
         | 
| 32 | 
            +
             | 
| 33 | 
            +
             | 
| 34 | 
            +
             | 
| 35 | 
            +
             | 
| 36 | 
            +
            #endif
         | 
    
        data/lib/tiny_tds.rb
    ADDED
    
    | @@ -0,0 +1,19 @@ | |
| 1 | 
            +
            # encoding: UTF-8
         | 
| 2 | 
            +
            require 'date'
         | 
| 3 | 
            +
            require 'bigdecimal'
         | 
| 4 | 
            +
            require 'rational' unless RUBY_VERSION >= '1.9.2'
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            require 'tiny_tds/version'
         | 
| 7 | 
            +
            require 'tiny_tds/error'
         | 
| 8 | 
            +
            require 'tiny_tds/client'
         | 
| 9 | 
            +
            require 'tiny_tds/result'
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            # Support multiple ruby versions, fat binaries under Windows.
         | 
| 12 | 
            +
            begin
         | 
| 13 | 
            +
              RUBY_VERSION =~ /(\d+.\d+)/
         | 
| 14 | 
            +
              require "tiny_tds/#{$1}/tiny_tds"
         | 
| 15 | 
            +
            rescue LoadError
         | 
| 16 | 
            +
              require 'tiny_tds/tiny_tds'
         | 
| 17 | 
            +
            end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
             | 
| @@ -0,0 +1,96 @@ | |
| 1 | 
            +
            module TinyTds
         | 
| 2 | 
            +
              class Client
         | 
| 3 | 
            +
                
         | 
| 4 | 
            +
                # From sybdb.h comments:
         | 
| 5 | 
            +
                # DBVERSION_xxx are used with dbsetversion()
         | 
| 6 | 
            +
                # 
         | 
| 7 | 
            +
                TDS_VERSIONS_SETTERS = {
         | 
| 8 | 
            +
                  'unknown' => 0,
         | 
| 9 | 
            +
                  '46'      => 1,
         | 
| 10 | 
            +
                  '100'     => 2,
         | 
| 11 | 
            +
                  '42'      => 3,
         | 
| 12 | 
            +
                  '70'      => 4,
         | 
| 13 | 
            +
                  '71'      => 5,
         | 
| 14 | 
            +
                  '80'      => 5,
         | 
| 15 | 
            +
                  '72'      => 6,
         | 
| 16 | 
            +
                  '90'      => 6
         | 
| 17 | 
            +
                }.freeze
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                # From sybdb.h comments:
         | 
| 20 | 
            +
                # DBTDS_xxx are returned by DBTDS()
         | 
| 21 | 
            +
                # The integer values of the constants are poorly chosen.
         | 
| 22 | 
            +
                # 
         | 
| 23 | 
            +
                TDS_VERSIONS_GETTERS = {
         | 
| 24 | 
            +
                  0  => {:name => 'DBTDS_UNKNOWN',        :description => 'Unknown'},
         | 
| 25 | 
            +
                  1  => {:name => 'DBTDS_2_0',            :description => 'Pre 4.0 SQL Server'},
         | 
| 26 | 
            +
                  2  => {:name => 'DBTDS_3_4',            :description => 'Microsoft SQL Server (3.0)'},
         | 
| 27 | 
            +
                  3  => {:name => 'DBTDS_4_0',            :description => '4.0 SQL Server'},
         | 
| 28 | 
            +
                  4  => {:name => 'DBTDS_4_2',            :description => '4.2 SQL Server'},
         | 
| 29 | 
            +
                  5  => {:name => 'DBTDS_4_6',            :description => '2.0 OpenServer and 4.6 SQL Server.'},
         | 
| 30 | 
            +
                  6  => {:name => 'DBTDS_4_9_5',          :description => '4.9.5 (NCR) SQL Server'},
         | 
| 31 | 
            +
                  7  => {:name => 'DBTDS_5_0',            :description => '5.0 SQL Server'},
         | 
| 32 | 
            +
                  8  => {:name => 'DBTDS_7_0',            :description => 'Microsoft SQL Server 7.0'},
         | 
| 33 | 
            +
                  9  => {:name => 'DBTDS_7_1/DBTDS_8_0',  :description => 'Microsoft SQL Server 2000'},
         | 
| 34 | 
            +
                  10 => {:name => 'DBTDS_7_2/DBTDS_9_0',  :description => 'Microsoft SQL Server 2005'}
         | 
| 35 | 
            +
                }.freeze
         | 
| 36 | 
            +
                
         | 
| 37 | 
            +
                @@default_query_options = {
         | 
| 38 | 
            +
                  :as => :hash,
         | 
| 39 | 
            +
                  :symbolize_keys => false,
         | 
| 40 | 
            +
                  :cache_rows => true,
         | 
| 41 | 
            +
                  :timezone => :local,
         | 
| 42 | 
            +
                  :empty_sets => true
         | 
| 43 | 
            +
                }
         | 
| 44 | 
            +
                
         | 
| 45 | 
            +
                attr_reader :query_options
         | 
| 46 | 
            +
                
         | 
| 47 | 
            +
                class << self
         | 
| 48 | 
            +
                  
         | 
| 49 | 
            +
                  def default_query_options
         | 
| 50 | 
            +
                    @@default_query_options
         | 
| 51 | 
            +
                  end
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                  # Most, if not all, iconv encoding names can be found by ruby. Just in case, you can 
         | 
| 54 | 
            +
                  # overide this method to return a string name that Encoding.find would work with. Default 
         | 
| 55 | 
            +
                  # is to return the passed encoding.
         | 
| 56 | 
            +
                  def transpose_iconv_encoding(encoding)
         | 
| 57 | 
            +
                    encoding
         | 
| 58 | 
            +
                  end
         | 
| 59 | 
            +
                  
         | 
| 60 | 
            +
                end
         | 
| 61 | 
            +
             | 
| 62 | 
            +
             | 
| 63 | 
            +
                def initialize(opts={})
         | 
| 64 | 
            +
                  if opts[:password] && opts[:password].to_s.strip != ''
         | 
| 65 | 
            +
                    opts[:password] = opts[:password].to_s
         | 
| 66 | 
            +
                    warn 'FreeTDS may have issues with passwords longer than 30 characters!' if opts[:password].length > 30
         | 
| 67 | 
            +
                  end
         | 
| 68 | 
            +
                  raise ArgumentError, 'missing :host option if no :dataserver given' if opts[:dataserver].to_s.empty? && opts[:host].to_s.empty?
         | 
| 69 | 
            +
                  @query_options = @@default_query_options.dup
         | 
| 70 | 
            +
                  opts[:appname] ||= 'TinyTds'
         | 
| 71 | 
            +
                  opts[:tds_version] = TDS_VERSIONS_SETTERS[opts[:tds_version].to_s] || TDS_VERSIONS_SETTERS['71']
         | 
| 72 | 
            +
                  opts[:login_timeout] ||= 60
         | 
| 73 | 
            +
                  opts[:timeout] ||= 5
         | 
| 74 | 
            +
                  opts[:encoding] = (opts[:encoding].nil? || opts[:encoding].downcase == 'utf8') ? 'UTF-8' : opts[:encoding].upcase
         | 
| 75 | 
            +
                  opts[:port] ||= 1433
         | 
| 76 | 
            +
                  opts[:dataserver] = "#{opts[:host]}:#{opts[:port]}" if opts[:dataserver].to_s.empty?
         | 
| 77 | 
            +
                  connect(opts)
         | 
| 78 | 
            +
                end
         | 
| 79 | 
            +
                
         | 
| 80 | 
            +
                def tds_version_info
         | 
| 81 | 
            +
                  info = TDS_VERSIONS_GETTERS[tds_version]
         | 
| 82 | 
            +
                  "#{info[:name]} - #{info[:description]}" if info
         | 
| 83 | 
            +
                end
         | 
| 84 | 
            +
             | 
| 85 | 
            +
                def active?
         | 
| 86 | 
            +
                  !closed? && !dead?
         | 
| 87 | 
            +
                end
         | 
| 88 | 
            +
             | 
| 89 | 
            +
                private
         | 
| 90 | 
            +
                
         | 
| 91 | 
            +
                def self.local_offset
         | 
| 92 | 
            +
                  ::Time.local(2010).utc_offset.to_r / 86400
         | 
| 93 | 
            +
                end
         | 
| 94 | 
            +
                
         | 
| 95 | 
            +
              end
         | 
| 96 | 
            +
            end
         | 
| @@ -0,0 +1,29 @@ | |
| 1 | 
            +
            module TinyTds  
         | 
| 2 | 
            +
              class Error < StandardError
         | 
| 3 | 
            +
                
         | 
| 4 | 
            +
                SEVERITIES = [
         | 
| 5 | 
            +
                  {:number => 1,   :severity => 'EXINFO',         :explanation => 'Informational, non-error.'},
         | 
| 6 | 
            +
                  {:number => 2,   :severity => 'EXUSER',         :explanation => 'User error.'},
         | 
| 7 | 
            +
                  {:number => 3,   :severity => 'EXNONFATAL',     :explanation => 'Non-fatal error.'},
         | 
| 8 | 
            +
                  {:number => 4,   :severity => 'EXCONVERSION',   :explanation => 'Error in DB-Library data conversion.'},
         | 
| 9 | 
            +
                  {:number => 5,   :severity => 'EXSERVER',       :explanation => 'The Server has returned an error flag.'},
         | 
| 10 | 
            +
                  {:number => 6,   :severity => 'EXTIME',         :explanation => 'We have exceeded our timeout period while waiting for a response from the Server - the DBPROCESS is still alive.'},
         | 
| 11 | 
            +
                  {:number => 7,   :severity => 'EXPROGRAM',      :explanation => 'Coding error in user program.'},
         | 
| 12 | 
            +
                  {:number => 8,   :severity => 'EXRESOURCE',     :explanation => 'Running out of resources - the DBPROCESS may be dead.'},
         | 
| 13 | 
            +
                  {:number => 9,   :severity => 'EXCOMM',         :explanation => 'Failure in communication with Server - the DBPROCESS is dead.'},
         | 
| 14 | 
            +
                  {:number => 10,  :severity => 'EXFATAL',        :explanation => 'Fatal error - the DBPROCESS is dead.'},
         | 
| 15 | 
            +
                  {:number => 11,  :severity => 'EXCONSISTENCY',  :explanation => 'Internal software error - notify Sybase Technical Support.'}
         | 
| 16 | 
            +
                ].freeze
         | 
| 17 | 
            +
                
         | 
| 18 | 
            +
                attr_accessor :source, :severity, :db_error_number, :os_error_number
         | 
| 19 | 
            +
                
         | 
| 20 | 
            +
                def initialize(message)
         | 
| 21 | 
            +
                  super
         | 
| 22 | 
            +
                  @severity = nil
         | 
| 23 | 
            +
                  @db_error_number = nil
         | 
| 24 | 
            +
                  @os_error_number = nil
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
             | 
| 28 | 
            +
              end
         | 
| 29 | 
            +
            end
         | 
    
        data/tasks/ports.rake
    ADDED
    
    | @@ -0,0 +1,79 @@ | |
| 1 | 
            +
            require 'mini_portile'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            # If your using 0.82, you may have to make a conf file to get it to work. For example:
         | 
| 4 | 
            +
            # $ export FREETDSCONF='/opt/local/etc/freetds/freetds.conf'
         | 
| 5 | 
            +
            ICONV_VERSION = "1.14"
         | 
| 6 | 
            +
            FREETDS_VERSION = ENV['TINYTDS_FREETDS_VERSION'] || "0.91"
         | 
| 7 | 
            +
            FREETDS_VERSION_INFO = Hash.new { |h,k|
         | 
| 8 | 
            +
              h[k] = {:files => "ftp://ftp.astron.com/pub/freetds/stable/freetds-#{k}.tar.gz"}
         | 
| 9 | 
            +
            }.merge({
         | 
| 10 | 
            +
              "0.82" => {:files => "ftp://ftp.astron.com/pub/freetds/old/0.82/freetds-0.82.tar.gz"},
         | 
| 11 | 
            +
              "0.91" => {:files => "ftp://ftp.astron.com/pub/freetds/stable/freetds-0.91.tar.gz"},
         | 
| 12 | 
            +
              "current" => {:files => "ftp://ftp.astron.com/pub/freetds/current/freetds-current.tgz"}
         | 
| 13 | 
            +
            })
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            # all ports depends on this directory to exist
         | 
| 16 | 
            +
            directory "ports"
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            def define_libiconv_recipe(platform, host)
         | 
| 19 | 
            +
              recipe = MiniPortile.new "libiconv", ICONV_VERSION
         | 
| 20 | 
            +
              recipe.files << "http://ftp.gnu.org/pub/gnu/libiconv/libiconv-#{ICONV_VERSION}.tar.gz"
         | 
| 21 | 
            +
              recipe.host = host
         | 
| 22 | 
            +
             | 
| 23 | 
            +
              desc "Compile libiconv for '#{platform}' (#{host})"
         | 
| 24 | 
            +
              task "ports:libiconv:#{platform}" => ["ports"] do
         | 
| 25 | 
            +
                checkpoint = "ports/.#{recipe.name}-#{recipe.version}-#{recipe.host}.installed"
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                unless File.exist?(checkpoint)
         | 
| 28 | 
            +
                  # always produce position independent code
         | 
| 29 | 
            +
                  recipe.configure_options << "CFLAGS='-fPIC'"
         | 
| 30 | 
            +
                  recipe.cook
         | 
| 31 | 
            +
                  touch checkpoint
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
              end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
              recipe
         | 
| 36 | 
            +
            end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
            def define_freetds_recipe(platform, host, libiconv)
         | 
| 39 | 
            +
              recipe = MiniPortile.new "freetds", FREETDS_VERSION
         | 
| 40 | 
            +
              recipe.files << FREETDS_VERSION_INFO[FREETDS_VERSION][:files]
         | 
| 41 | 
            +
              recipe.host = host
         | 
| 42 | 
            +
             | 
| 43 | 
            +
              if recipe.respond_to?(:patch_files) && FREETDS_VERSION == "0.91"
         | 
| 44 | 
            +
                recipe.patch_files << File.expand_path(File.join('..', '..', 'ext', 'patch', 'sspi_w_kerberos.diff'), __FILE__)
         | 
| 45 | 
            +
                recipe.patch_files << File.expand_path(File.join('..', '..', 'ext', 'patch', 'dblib-30-char-username.diff'), __FILE__)
         | 
| 46 | 
            +
                unless RUBY_PLATFORM =~ /mswin|mingw/
         | 
| 47 | 
            +
                  recipe.patch_files << File.expand_path(File.join('..', '..', 'ext', 'patch', 'Makefile.in.diff'), __FILE__)
         | 
| 48 | 
            +
                end
         | 
| 49 | 
            +
              end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
              desc "Compile freetds for '#{platform}' (#{host})"
         | 
| 52 | 
            +
              task "ports:freetds:#{platform}" => ["ports", "ports:libiconv:#{platform}"] do
         | 
| 53 | 
            +
                checkpoint = "ports/.#{recipe.name}-#{recipe.version}-#{recipe.host}.installed"
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                unless File.exist?(checkpoint)
         | 
| 56 | 
            +
                  with_tdsver = ENV['TINYTDS_FREETDS_VERSION'] =~ /0\.8/ ? "--with-tdsver=8.0" : "--with-tdsver=7.1"
         | 
| 57 | 
            +
                  for_windows = recipe.host =~ /mswin|mingw/i
         | 
| 58 | 
            +
                  recipe.configure_options << '--with-pic'
         | 
| 59 | 
            +
                  recipe.configure_options << "--with-libiconv-prefix=#{libiconv.path}"
         | 
| 60 | 
            +
                  recipe.configure_options << '--sysconfdir="C:/Sites"' if for_windows
         | 
| 61 | 
            +
                  recipe.configure_options << '--enable-sspi' if for_windows
         | 
| 62 | 
            +
                  recipe.configure_options << "--disable-odbc"
         | 
| 63 | 
            +
                  recipe.configure_options << with_tdsver
         | 
| 64 | 
            +
                  recipe.cook
         | 
| 65 | 
            +
                  touch checkpoint
         | 
| 66 | 
            +
                end
         | 
| 67 | 
            +
              end
         | 
| 68 | 
            +
             | 
| 69 | 
            +
              recipe
         | 
| 70 | 
            +
            end
         | 
| 71 | 
            +
             | 
| 72 | 
            +
            # native compilation of ports
         | 
| 73 | 
            +
            host = RbConfig::CONFIG["host"]
         | 
| 74 | 
            +
            libiconv = define_libiconv_recipe(RUBY_PLATFORM, host)
         | 
| 75 | 
            +
            freetds  = define_freetds_recipe(RUBY_PLATFORM, host, libiconv)
         | 
| 76 | 
            +
             | 
| 77 | 
            +
            # compile native FreeTDS
         | 
| 78 | 
            +
            desc "Compile native freetds"
         | 
| 79 | 
            +
            task "ports:freetds" => ["ports:freetds:#{RUBY_PLATFORM}"]
         | 
| @@ -0,0 +1,77 @@ | |
| 1 | 
            +
            $:.unshift File.expand_path('../../../lib',__FILE__)
         | 
| 2 | 
            +
            require 'rubygems'
         | 
| 3 | 
            +
            require 'bench_press'
         | 
| 4 | 
            +
            require 'tiny_tds'
         | 
| 5 | 
            +
            require 'odbc'
         | 
| 6 | 
            +
            require 'odbc_utf8'
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            extend BenchPress
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            author 'Ken Collins'
         | 
| 11 | 
            +
            summary 'Query everything.'
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            reps 1_000
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            @odbc = ODBC.connect ENV['TINYTDS_UNIT_DATASERVER'], 'tinytds', ''
         | 
| 16 | 
            +
            @odbc.use_time = true
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            @odbc_utf8 = ODBC_UTF8.connect ENV['TINYTDS_UNIT_DATASERVER'], 'tinytds', ''
         | 
| 19 | 
            +
            @odbc_utf8.use_time = true
         | 
| 20 | 
            +
             | 
| 21 | 
            +
            @tinytds = TinyTds::Client.new(
         | 
| 22 | 
            +
              :dataserver    => ENV['TINYTDS_UNIT_DATASERVER'],
         | 
| 23 | 
            +
              :username      => 'tinytds',
         | 
| 24 | 
            +
              :password      => '',
         | 
| 25 | 
            +
              :database      => 'tinytdstest',
         | 
| 26 | 
            +
              :appname       => 'TinyTds Dev',
         | 
| 27 | 
            +
              :login_timeout => 5,
         | 
| 28 | 
            +
              :timeout       => 5 )
         | 
| 29 | 
            +
             | 
| 30 | 
            +
            @query_all = "SELECT * FROM [datatypes]"
         | 
| 31 | 
            +
             | 
| 32 | 
            +
             | 
| 33 | 
            +
            measure "ODBC (ascii-8bit)" do
         | 
| 34 | 
            +
              h = @odbc.run(@query_all)
         | 
| 35 | 
            +
              h.fetch_all
         | 
| 36 | 
            +
              h.drop
         | 
| 37 | 
            +
            end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
            # measure "ODBC (utf8)" do
         | 
| 40 | 
            +
            #   h = @odbc_utf8.run(@query_all)
         | 
| 41 | 
            +
            #   h.fetch_all
         | 
| 42 | 
            +
            #   h.drop
         | 
| 43 | 
            +
            # end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
            measure "TinyTDS (row caching)" do
         | 
| 46 | 
            +
              @tinytds.execute(@query_all).each
         | 
| 47 | 
            +
            end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
            measure "TinyTDS (no caching)" do
         | 
| 50 | 
            +
              @tinytds.execute(@query_all).each(:cache_rows => false)
         | 
| 51 | 
            +
            end
         | 
| 52 | 
            +
             | 
| 53 | 
            +
             | 
| 54 | 
            +
             | 
| 55 | 
            +
            =begin
         | 
| 56 | 
            +
             | 
| 57 | 
            +
            Author: Ken Collins  
         | 
| 58 | 
            +
            Date: January 22, 2011  
         | 
| 59 | 
            +
            Summary: Query everything.  
         | 
| 60 | 
            +
             | 
| 61 | 
            +
            System Information
         | 
| 62 | 
            +
            ------------------
         | 
| 63 | 
            +
                Operating System:    Mac OS X 10.6.6 (10J567)
         | 
| 64 | 
            +
                CPU:                 Intel Core 2 Duo 1.6 GHz
         | 
| 65 | 
            +
                Processor Count:     2
         | 
| 66 | 
            +
                Memory:              4 GB
         | 
| 67 | 
            +
                ruby 1.8.7 (2010-04-19 patchlevel 253) [i686-darwin10.4.3], MBARI 0x6770, Ruby Enterprise Edition 2010.02
         | 
| 68 | 
            +
             | 
| 69 | 
            +
            "TinyTDS (row caching)" is up to 79% faster over 1,000 repetitions
         | 
| 70 | 
            +
            ------------------------------------------------------------------
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                TinyTDS (row caching)    4.90862512588501 secs    Fastest
         | 
| 73 | 
            +
                TinyTDS (no caching)     4.91626906394958 secs    0% Slower
         | 
| 74 | 
            +
                ODBC (ascii-8bit)        23.959536075592  secs    79% Slower
         | 
| 75 | 
            +
             | 
| 76 | 
            +
            =end
         | 
| 77 | 
            +
             | 
| @@ -0,0 +1,106 @@ | |
| 1 | 
            +
            require 'rubygems'
         | 
| 2 | 
            +
            require 'bench_press'
         | 
| 3 | 
            +
            begin gem 'odbc', '0.99992' ; rescue Gem::LoadError ; end
         | 
| 4 | 
            +
            require 'odbc'
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            extend BenchPress
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            author 'Ken Collins'
         | 
| 9 | 
            +
            summary 'Benchmarking ODBC Querys'
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            reps 1_000
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            @client = ODBC.connect ENV['TINYTDS_UNIT_DATASERVER'], 'tinytds', ''
         | 
| 14 | 
            +
            @client.use_time = true
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            @query_nothing  = "SELECT NULL AS [null]"
         | 
| 17 | 
            +
            @query_ints     = "SELECT [int], [bigint], [smallint], [tinyint] FROM [datatypes]"
         | 
| 18 | 
            +
            @query_binaries = "SELECT [binary_50], [image], [varbinary_50] FROM [datatypes]"
         | 
| 19 | 
            +
            @query_bits     = "SELECT [bit] FROM [datatypes]"
         | 
| 20 | 
            +
            @query_chars    = "SELECT [char_10], [nchar_10], [ntext], [nvarchar_50], [text], [varchar_50] FROM [datatypes]"
         | 
| 21 | 
            +
            @query_dates    = "SELECT [datetime], [smalldatetime] FROM [datatypes]"
         | 
| 22 | 
            +
            @query_decimals = "SELECT [decimal_9_2], [decimal_16_4], [numeric_18_0], [numeric_36_2] FROM [datatypes]"
         | 
| 23 | 
            +
            @query_floats   = "SELECT [float], [real] FROM [datatypes]"
         | 
| 24 | 
            +
            @query_moneys   = "SELECT [money], [smallmoney] FROM [datatypes]"
         | 
| 25 | 
            +
            @query_guids    = "SELECT [uniqueidentifier] FROM [datatypes]"
         | 
| 26 | 
            +
            @query_all      = "SELECT * FROM [datatypes]"
         | 
| 27 | 
            +
             | 
| 28 | 
            +
            def select_all(query)
         | 
| 29 | 
            +
              h = @client.run(query)
         | 
| 30 | 
            +
              h.fetch_all
         | 
| 31 | 
            +
              h.drop
         | 
| 32 | 
            +
            end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
             | 
| 35 | 
            +
            measure "Nothing" do
         | 
| 36 | 
            +
              select_all @query_nothing
         | 
| 37 | 
            +
            end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
            measure "Integers" do
         | 
| 40 | 
            +
              select_all @query_ints
         | 
| 41 | 
            +
            end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
            measure "Binaries" do
         | 
| 44 | 
            +
              select_all @query_binaries
         | 
| 45 | 
            +
            end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
            measure "Bits" do
         | 
| 48 | 
            +
              select_all @query_bits
         | 
| 49 | 
            +
            end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
            measure "Chars" do
         | 
| 52 | 
            +
              select_all @query_chars
         | 
| 53 | 
            +
            end
         | 
| 54 | 
            +
             | 
| 55 | 
            +
            measure "Dates" do
         | 
| 56 | 
            +
              select_all @query_dates
         | 
| 57 | 
            +
            end
         | 
| 58 | 
            +
             | 
| 59 | 
            +
            measure "Decimals" do
         | 
| 60 | 
            +
              select_all @query_decimals
         | 
| 61 | 
            +
            end
         | 
| 62 | 
            +
             | 
| 63 | 
            +
            measure "Floats" do
         | 
| 64 | 
            +
              select_all @query_floats
         | 
| 65 | 
            +
            end
         | 
| 66 | 
            +
             | 
| 67 | 
            +
            measure "Moneys" do
         | 
| 68 | 
            +
              select_all @query_moneys
         | 
| 69 | 
            +
            end
         | 
| 70 | 
            +
             | 
| 71 | 
            +
            measure "Guids" do
         | 
| 72 | 
            +
              select_all @query_guids
         | 
| 73 | 
            +
            end
         | 
| 74 | 
            +
             | 
| 75 | 
            +
            measure "All" do
         | 
| 76 | 
            +
              select_all @query_all
         | 
| 77 | 
            +
            end
         | 
| 78 | 
            +
             | 
| 79 | 
            +
             | 
| 80 | 
            +
            =begin
         | 
| 81 | 
            +
             | 
| 82 | 
            +
            System Information
         | 
| 83 | 
            +
            ------------------
         | 
| 84 | 
            +
                Operating System:    Mac OS X 10.6.4 (10F569)
         | 
| 85 | 
            +
                CPU:                 Intel Core 2 Duo 2.4 GHz
         | 
| 86 | 
            +
                Processor Count:     2
         | 
| 87 | 
            +
                Memory:              4 GB
         | 
| 88 | 
            +
                ruby 1.8.7 (2010-08-16 patchlevel 302) [i686-darwin10.4.0]
         | 
| 89 | 
            +
             | 
| 90 | 
            +
            "Nothing" is up to 98% faster over 1,000 repetitions
         | 
| 91 | 
            +
            ----------------------------------------------------
         | 
| 92 | 
            +
             | 
| 93 | 
            +
                Nothing     0.297961950302124 secs    Fastest
         | 
| 94 | 
            +
                Bits        0.377611875534058 secs    21% Slower
         | 
| 95 | 
            +
                Guids       0.381000995635986 secs    21% Slower
         | 
| 96 | 
            +
                Moneys      0.405518054962158 secs    26% Slower
         | 
| 97 | 
            +
                Floats      0.409428119659424 secs    27% Slower
         | 
| 98 | 
            +
                Integers    0.448167085647583 secs    33% Slower
         | 
| 99 | 
            +
                Decimals    0.471596956253052 secs    36% Slower
         | 
| 100 | 
            +
                Dates       0.52501106262207  secs    43% Slower
         | 
| 101 | 
            +
                Binaries    3.66349482536316  secs    91% Slower
         | 
| 102 | 
            +
                Chars       6.82928085327148  secs    95% Slower
         | 
| 103 | 
            +
                All         28.4982612133026  secs    98% Slower
         | 
| 104 | 
            +
             | 
| 105 | 
            +
            =end
         | 
| 106 | 
            +
             |