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.
@@ -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
+