tiny_tds 0.6.2-x64-mingw32

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -0,0 +1,12 @@
1
+
2
+ #include <tiny_tds_ext.h>
3
+
4
+ VALUE mTinyTds, cTinyTdsError;
5
+
6
+ void Init_tiny_tds() {
7
+ mTinyTds = rb_define_module("TinyTds");
8
+ cTinyTdsError = rb_const_get(mTinyTds, rb_intern("Error"));
9
+ init_tinytds_client();
10
+ init_tinytds_result();
11
+ }
12
+
@@ -0,0 +1,15 @@
1
+ #ifndef TINYTDS_EXT
2
+ #define TINYTDS_EXT
3
+
4
+ #undef MSDBLIB
5
+ #define SYBDBLIB
6
+
7
+ #include <ruby.h>
8
+ #include <ruby/encoding.h>
9
+ #include <sybfront.h>
10
+ #include <sybdb.h>
11
+
12
+ #include <client.h>
13
+ #include <result.h>
14
+
15
+ #endif
@@ -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
@@ -0,0 +1,8 @@
1
+ module TinyTds
2
+ class Result
3
+
4
+ include Enumerable
5
+
6
+
7
+ end
8
+ end
@@ -0,0 +1,3 @@
1
+ module TinyTds
2
+ VERSION = '0.6.2'
3
+ end
@@ -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
+