tiny_tds_vagas 1.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +20 -0
  3. data/CHANGELOG +198 -0
  4. data/CODE_OF_CONDUCT.md +31 -0
  5. data/Gemfile +6 -0
  6. data/ISSUE_TEMPLATE.md +5 -0
  7. data/MIT-LICENSE +23 -0
  8. data/README.md +427 -0
  9. data/Rakefile +110 -0
  10. data/VERSION +1 -0
  11. data/appveyor.yml +52 -0
  12. data/bin/defncopy +3 -0
  13. data/bin/tsql +3 -0
  14. data/ext/tiny_tds/client.c +410 -0
  15. data/ext/tiny_tds/client.h +49 -0
  16. data/ext/tiny_tds/extconf.rb +329 -0
  17. data/ext/tiny_tds/extconsts.rb +15 -0
  18. data/ext/tiny_tds/result.c +608 -0
  19. data/ext/tiny_tds/result.h +32 -0
  20. data/ext/tiny_tds/tiny_tds_ext.c +12 -0
  21. data/ext/tiny_tds/tiny_tds_ext.h +17 -0
  22. data/lib/tiny_tds.rb +37 -0
  23. data/lib/tiny_tds/bin.rb +86 -0
  24. data/lib/tiny_tds/client.rb +124 -0
  25. data/lib/tiny_tds/error.rb +15 -0
  26. data/lib/tiny_tds/result.rb +8 -0
  27. data/lib/tiny_tds/version.rb +3 -0
  28. data/ports/patches/freetds/1.00/0001-mingw_missing_inet_pton.diff +34 -0
  29. data/test/appveyor/dbsetup.ps1 +27 -0
  30. data/test/appveyor/dbsetup.sql +9 -0
  31. data/test/benchmark/query.rb +77 -0
  32. data/test/benchmark/query_odbc.rb +106 -0
  33. data/test/benchmark/query_tinytds.rb +126 -0
  34. data/test/client_test.rb +217 -0
  35. data/test/result_test.rb +728 -0
  36. data/test/schema/1px.gif +0 -0
  37. data/test/schema/sqlserver_2000.sql +140 -0
  38. data/test/schema/sqlserver_2005.sql +140 -0
  39. data/test/schema/sqlserver_2008.sql +140 -0
  40. data/test/schema/sqlserver_2014.sql +140 -0
  41. data/test/schema/sqlserver_azure.sql +140 -0
  42. data/test/schema/sybase_ase.sql +138 -0
  43. data/test/schema_test.rb +443 -0
  44. data/test/test_helper.rb +213 -0
  45. data/test/thread_test.rb +98 -0
  46. data/tiny_tds.gemspec +28 -0
  47. metadata +201 -0
@@ -0,0 +1,32 @@
1
+
2
+ #ifndef TINYTDS_RESULT_H
3
+ #define TINYTDS_RESULT_H
4
+
5
+ void init_tinytds_result();
6
+ VALUE rb_tinytds_new_result_obj(tinytds_client_wrapper *cwrap);
7
+
8
+ typedef struct {
9
+ tinytds_client_wrapper *cwrap;
10
+ DBPROCESS *client;
11
+ VALUE local_offset;
12
+ VALUE fields;
13
+ VALUE fields_processed;
14
+ VALUE results;
15
+ rb_encoding *encoding;
16
+ VALUE dbresults_retcodes;
17
+ unsigned int number_of_results;
18
+ unsigned int number_of_fields;
19
+ unsigned long number_of_rows;
20
+ } tinytds_result_wrapper;
21
+
22
+
23
+ // Lib Macros
24
+
25
+ #define GET_RESULT_WRAPPER(self) \
26
+ tinytds_result_wrapper *rwrap; \
27
+ Data_Get_Struct(self, tinytds_result_wrapper, rwrap)
28
+
29
+
30
+
31
+
32
+ #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,17 @@
1
+ #ifndef TINYTDS_EXT
2
+ #define TINYTDS_EXT
3
+
4
+ #undef SYBDBLIB
5
+ #define MSDBLIB 1
6
+
7
+ #include <ruby.h>
8
+ #include <ruby/encoding.h>
9
+ #include <ruby/version.h>
10
+ #include <ruby/thread.h>
11
+ #include <sybfront.h>
12
+ #include <sybdb.h>
13
+
14
+ #include <client.h>
15
+ #include <result.h>
16
+
17
+ #endif
data/lib/tiny_tds.rb ADDED
@@ -0,0 +1,37 @@
1
+ # encoding: UTF-8
2
+ require 'date'
3
+ require 'bigdecimal'
4
+ require 'rational'
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
+ if RUBY_PLATFORM =~ /mingw|mswin/ && RUBY_VERSION =~ /(\d+.\d+)/
13
+ ver = $1
14
+ # Set the PATH environment variable, so that the DLLs can be found.
15
+ old_path = ENV['PATH']
16
+ begin
17
+ # Do the same host consolidation as in extconf.rb
18
+ ports_dir = RbConfig::CONFIG["host"].gsub('i686-pc-mingw32', 'i686-w64-mingw32')
19
+ ENV['PATH'] = "#{File.expand_path("../../ports/#{ports_dir}/bin", __FILE__)};#{old_path}"
20
+ require "tiny_tds/#{ver}/tiny_tds"
21
+ rescue LoadError
22
+ require 'tiny_tds/tiny_tds'
23
+ ensure
24
+ ENV['PATH'] = old_path
25
+ end
26
+ else
27
+ # Load dependent shared libraries into the process, so that they are already present,
28
+ # when tiny_tds.so is loaded. This ensures, that shared libraries are loaded even when
29
+ # the path is different between build and run time (e.g. Heroku).
30
+ ports_libs = File.expand_path("../../ports/#{RbConfig::CONFIG["host"]}/lib/*.so", __FILE__)
31
+ Dir[ports_libs].each do |lib|
32
+ require "fiddle"
33
+ Fiddle.dlopen(lib)
34
+ end
35
+
36
+ require 'tiny_tds/tiny_tds'
37
+ end
@@ -0,0 +1,86 @@
1
+ require_relative './version'
2
+ require 'shellwords'
3
+
4
+ module TinyTds
5
+ class Bin
6
+
7
+ ROOT = File.expand_path '../../..', __FILE__
8
+ PATHS = ENV['PATH'].split File::PATH_SEPARATOR
9
+ EXTS = (ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']) | ['.exe']
10
+
11
+ attr_reader :name
12
+
13
+ class << self
14
+
15
+ def exe(name, *args)
16
+ bin = new(name)
17
+ puts bin.info
18
+ bin.run(*args)
19
+ end
20
+
21
+ end
22
+
23
+ def initialize(name)
24
+ @name = name
25
+ @binstub = find_bin
26
+ @exefile = find_exe
27
+ end
28
+
29
+ def run(*args)
30
+ return nil unless path
31
+ Kernel.system Shellwords.join(args.unshift(path))
32
+ $?.to_i
33
+ end
34
+
35
+ def path
36
+ return @path if defined?(@path)
37
+ @path = @exefile && File.exists?(@exefile) ? @exefile : which
38
+ end
39
+
40
+ def info
41
+ "[TinyTds][v#{TinyTds::VERSION}][#{name}]: #{path}"
42
+ end
43
+
44
+
45
+ private
46
+
47
+ def find_bin
48
+ File.join ROOT, 'bin', name
49
+ end
50
+
51
+ def find_exe
52
+ EXTS.each do |ext|
53
+ f = File.join ROOT, 'exe', "#{name}#{ext}"
54
+ return f if File.exists?(f)
55
+ end
56
+ nil
57
+ end
58
+
59
+ def which
60
+ PATHS.each do |path|
61
+ EXTS.each do |ext|
62
+ exe = File.expand_path File.join(path, "#{name}#{ext}"), ROOT
63
+ next if exe == @binstub
64
+ next if !File.executable?(exe)
65
+ next if !binary?(exe)
66
+ return exe
67
+ end
68
+ end
69
+ return nil
70
+ end
71
+
72
+ # Implementation directly copied from ptools.
73
+ # https://github.com/djberg96/ptools
74
+ # https://opensource.org/licenses/Artistic-2.0
75
+ #
76
+ def binary?(file)
77
+ bytes = File.stat(file).blksize
78
+ return false unless bytes
79
+ bytes = 4096 if bytes > 4096
80
+ s = (File.read(file, bytes) || "")
81
+ s = s.encode('US-ASCII', :undef => :replace).split(//)
82
+ ((s.size - s.grep(" ".."~").size) / s.size.to_f) > 0.30
83
+ end
84
+
85
+ end
86
+ end
@@ -0,0 +1,124 @@
1
+ module TinyTds
2
+ class Client
3
+
4
+ @@default_query_options = {
5
+ :as => :hash,
6
+ :symbolize_keys => false,
7
+ :cache_rows => true,
8
+ :timezone => :local,
9
+ :empty_sets => true
10
+ }
11
+
12
+ attr_reader :query_options
13
+
14
+ class << self
15
+
16
+ def default_query_options
17
+ @@default_query_options
18
+ end
19
+
20
+ # Most, if not all, iconv encoding names can be found by ruby. Just in case, you can
21
+ # overide this method to return a string name that Encoding.find would work with. Default
22
+ # is to return the passed encoding.
23
+ #
24
+ def transpose_iconv_encoding(encoding)
25
+ encoding
26
+ end
27
+
28
+ end
29
+
30
+
31
+ def initialize(opts={})
32
+ raise ArgumentError, 'missing :host option if no :dataserver given' if opts[:dataserver].to_s.empty? && opts[:host].to_s.empty?
33
+ opts[:username] = parse_username(opts)
34
+ @query_options = @@default_query_options.dup
35
+ opts[:password] = opts[:password].to_s if opts[:password] && opts[:password].to_s.strip != ''
36
+ opts[:appname] ||= 'TinyTds'
37
+ opts[:tds_version] = tds_versions_setter(opts)
38
+ opts[:login_timeout] ||= 60
39
+ opts[:timeout] ||= 5
40
+ opts[:encoding] = (opts[:encoding].nil? || opts[:encoding].downcase == 'utf8') ? 'UTF-8' : opts[:encoding].upcase
41
+ opts[:port] ||= 1433
42
+ opts[:dataserver] = "#{opts[:host]}:#{opts[:port]}" if opts[:dataserver].to_s.empty?
43
+ connect(opts)
44
+ end
45
+
46
+ def tds_73?
47
+ tds_version >= 11
48
+ end
49
+
50
+ def tds_version_info
51
+ info = TDS_VERSIONS_GETTERS[tds_version]
52
+ "#{info[:name]} - #{info[:description]}" if info
53
+ end
54
+
55
+ def active?
56
+ !closed? && !dead?
57
+ end
58
+
59
+
60
+ private
61
+
62
+ def self.local_offset
63
+ ::Time.local(2010).utc_offset.to_r / 86400
64
+ end
65
+
66
+ def parse_username(opts)
67
+ host = opts[:host]
68
+ username = opts[:username]
69
+ return username if username.nil? || !opts[:azure]
70
+ return username if username.include?("@") && !username.include?("database.windows.net")
71
+ user, domain = username.split("@")
72
+ domain ||= host
73
+ "#{user}@#{domain.split('.').first}"
74
+ end
75
+
76
+ def tds_versions_setter(opts={})
77
+ v = opts[:tds_version] || ENV['TDSVER'] || '7.3'
78
+ TDS_VERSIONS_SETTERS[v.to_s]
79
+ end
80
+
81
+ # From sybdb.h comments:
82
+ # DBVERSION_xxx are used with dbsetversion()
83
+ #
84
+ TDS_VERSIONS_SETTERS = {
85
+ 'unknown' => 0,
86
+ '46' => 1,
87
+ '100' => 2,
88
+ '42' => 3,
89
+ '70' => 4,
90
+ '7.0' => 4,
91
+ '71' => 5,
92
+ '7.1' => 5,
93
+ '80' => 5,
94
+ '8.0' => 5,
95
+ '72' => 6,
96
+ '7.2' => 6,
97
+ '90' => 6,
98
+ '9.0' => 6,
99
+ '73' => 7,
100
+ '7.3' => 7
101
+ }.freeze
102
+
103
+ # From sybdb.h comments:
104
+ # DBTDS_xxx are returned by DBTDS()
105
+ # The integer values of the constants are poorly chosen.
106
+ #
107
+ TDS_VERSIONS_GETTERS = {
108
+ 0 => {:name => 'DBTDS_UNKNOWN', :description => 'Unknown'},
109
+ 1 => {:name => 'DBTDS_2_0', :description => 'Pre 4.0 SQL Server'},
110
+ 2 => {:name => 'DBTDS_3_4', :description => 'Microsoft SQL Server (3.0)'},
111
+ 3 => {:name => 'DBTDS_4_0', :description => '4.0 SQL Server'},
112
+ 4 => {:name => 'DBTDS_4_2', :description => '4.2 SQL Server'},
113
+ 5 => {:name => 'DBTDS_4_6', :description => '2.0 OpenServer and 4.6 SQL Server.'},
114
+ 6 => {:name => 'DBTDS_4_9_5', :description => '4.9.5 (NCR) SQL Server'},
115
+ 7 => {:name => 'DBTDS_5_0', :description => '5.0 SQL Server'},
116
+ 8 => {:name => 'DBTDS_7_0', :description => 'Microsoft SQL Server 7.0'},
117
+ 9 => {:name => 'DBTDS_7_1/DBTDS_8_0', :description => 'Microsoft SQL Server 2000'},
118
+ 10 => {:name => 'DBTDS_7_2/DBTDS_9_0', :description => 'Microsoft SQL Server 2005'},
119
+ 11 => {:name => 'DBTDS_7_3', :description => 'Microsoft SQL Server 2008'},
120
+ 12 => {:name => 'DBTDS_7_4', :description => 'Microsoft SQL Server 2012/2014'}
121
+ }.freeze
122
+
123
+ end
124
+ end
@@ -0,0 +1,15 @@
1
+ module TinyTds
2
+ class Error < StandardError
3
+
4
+ attr_accessor :source, :severity, :db_error_number, :os_error_number
5
+
6
+ def initialize(message)
7
+ super
8
+ @severity = nil
9
+ @db_error_number = nil
10
+ @os_error_number = nil
11
+ end
12
+
13
+
14
+ end
15
+ 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 = File.read(File.expand_path("../../../VERSION", __FILE__)).chomp
3
+ end
@@ -0,0 +1,34 @@
1
+ diff --git a/src/tds/tls.c b/src/tds/tls.c
2
+ index 0d11a33..b8ab2ba 100644
3
+ --- a/src/tds/tls.c
4
+ +++ b/src/tds/tls.c
5
+ @@ -72,6 +72,29 @@
6
+ #define SSL_PTR bio->ptr
7
+ #endif
8
+
9
+ +/*
10
+ + * Add a workaround for older Mingw versions without inet_pton().
11
+ + * This means RubyInstallers DevKit-4.7.2 in particular.
12
+ + */
13
+ +#if defined(__MINGW64_VERSION_MAJOR) && !defined(InetPtonA)
14
+ + #include <windows.h>
15
+ +
16
+ + static HMODULE ws2_32 = NULL;
17
+ + typedef INT (WINAPI * __inet_pton)(INT Family, LPCWSTR pStringBuf, PVOID pAddr);
18
+ + static __inet_pton _inet_pton = NULL;
19
+ +
20
+ + INT WINAPI inet_pton(INT Family, LPCWSTR pStringBuf, PVOID pAddr)
21
+ + {
22
+ + if (_inet_pton == NULL) {
23
+ + ws2_32 = LoadLibraryEx("Ws2_32.dll", NULL, 0);
24
+ +
25
+ + _inet_pton = (__inet_pton)GetProcAddress(ws2_32, "inet_pton");
26
+ + }
27
+ +
28
+ + return (_inet_pton)(Family, pStringBuf, pAddr);
29
+ + }
30
+ +#endif
31
+ +
32
+ static SSL_RET
33
+ tds_pull_func_login(SSL_PULL_ARGS)
34
+ {
@@ -0,0 +1,27 @@
1
+
2
+ Write-Output "Setting up..."
3
+ [reflection.assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo") | Out-Null
4
+ [reflection.assembly]::LoadWithPartialName("Microsoft.SqlServer.SqlWmiManagement") | Out-Null
5
+
6
+ Write-Output "Setting variables..."
7
+ $serverName = $env:COMPUTERNAME
8
+ $instances = @('SQL2008R2SP2', 'SQL2012SP1', 'SQL2014')
9
+ $smo = 'Microsoft.SqlServer.Management.Smo.'
10
+ $wmi = new-object ($smo + 'Wmi.ManagedComputer')
11
+
12
+ Write-Output "Configure Instances..."
13
+ foreach ($instance in $instances) {
14
+ Write-Output "Instance $instance ..."
15
+ Write-Output "Enable TCP/IP and port 1433..."
16
+ $uri = "ManagedComputer[@Name='$serverName']/ServerInstance[@Name='$instance']/ServerProtocol[@Name='Tcp']"
17
+ $tcp = $wmi.GetSmoObject($uri)
18
+ $tcp.IsEnabled = $true
19
+ foreach ($ipAddress in $Tcp.IPAddresses) {
20
+ $ipAddress.IPAddressProperties["TcpDynamicPorts"].Value = ""
21
+ $ipAddress.IPAddressProperties["TcpPort"].Value = "1433"
22
+ }
23
+ $tcp.Alter()
24
+ }
25
+
26
+ Set-Service SQLBrowser -StartupType Manual
27
+ Start-Service SQLBrowser
@@ -0,0 +1,9 @@
1
+ CREATE DATABASE [tinytdstest];
2
+ GO
3
+ CREATE LOGIN [tinytds] WITH PASSWORD = '', CHECK_POLICY = OFF, DEFAULT_DATABASE = [tinytdstest];
4
+ GO
5
+ USE [tinytdstest];
6
+ CREATE USER [tinytds] FOR LOGIN [tinytds];
7
+ GO
8
+ EXEC sp_addrolemember N'db_owner', N'tinytds';
9
+ GO
@@ -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
+