tiny_tds 0.5.1.rc1-x86-mingw32 → 0.5.1-x86-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.
- data/CHANGELOG +1 -1
- data/Gemfile +2 -2
- data/README.md +6 -2
- data/Rakefile +1 -0
- data/ext/tiny_tds/extconf.rb +70 -60
- data/lib/tiny_tds/client.rb +1 -0
- data/lib/tiny_tds/version.rb +1 -1
- data/test/client_test.rb +3 -3
- data/test/result_test.rb +43 -19
- data/test/schema/sybase_ase.sql +138 -0
- data/test/schema_test.rb +3 -3
- data/test/test_helper.rb +32 -4
- metadata +11 -15
data/CHANGELOG
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -288,15 +288,19 @@ $ rake native gem
|
|
288
288
|
$ gem install pkg/tiny_tds-X.X.X-#{platform}.gem
|
289
289
|
```
|
290
290
|
|
291
|
+
**Important:** You must use rubygems version 1.7.2 or higher. You will almost certainly hit a *Don't know how to build task...* error when running the `rake native gem` command if you do not. Please update rubygems! Here is a link on [how to upgrade or downgrade rubygems](http://rubygems.rubyforge.org/rubygems-update/UPGRADING_rdoc.html).
|
292
|
+
|
291
293
|
|
292
294
|
## Development & Testing
|
293
295
|
|
294
|
-
We use bundler for development. Simply run `bundle install` then `rake` to build the gem and run the unit tests. The tests assume you have created a database named `tinytdstest` accessible by a database owner named `tinytds`. Before running the test rake task, you may need to define a pair of environment variables that help the client connect to your specific FreeTDS database server name and which schema (2000, 2005, 2008 or
|
296
|
+
We use bundler for development. Simply run `bundle install` then `rake` to build the gem and run the unit tests. The tests assume you have created a database named `tinytdstest` accessible by a database owner named `tinytds`. Before running the test rake task, you may need to define a pair of environment variables that help the client connect to your specific FreeTDS database server name and which schema (2000, 2005, 2008, Azure or Sybase ASE) to use. For example:
|
295
297
|
|
296
298
|
```
|
297
299
|
$ rake TINYTDS_UNIT_DATASERVER=mydbserver TINYTDS_SCHEMA=sqlserver_2008
|
298
300
|
or
|
299
301
|
$ rake TINYTDS_UNIT_HOST=mydb.host.net TINYTDS_SCHEMA=sqlserver_azure
|
302
|
+
or
|
303
|
+
$ rake TINYTDS_UNIT_HOST=mydb.host.net TINYTDS_UNIT_PORT=5000 TINYTDS_SCHEMA=sybase_ase
|
300
304
|
```
|
301
305
|
|
302
306
|
If you do not want to use MiniPortile to compile a local project version of FreeTDS and instead use your local system version, use the `TINYTDS_SKIP_PORTS` environment variable. This will ignore any port tasks and will instead build and link to your system's FreeTDS installation as a normal gem install would.
|
@@ -323,7 +327,7 @@ $ rake TINYTDS_SKIP_PORTS=true
|
|
323
327
|
|
324
328
|
## About Me
|
325
329
|
|
326
|
-
My name is Ken Collins and I currently maintain the SQL Server adapter for ActiveRecord and wrote this library as my first cut into learning ruby C extensions. Hopefully it will help promote the power of ruby and the
|
330
|
+
My name is Ken Collins and I currently maintain the SQL Server adapter for ActiveRecord and wrote this library as my first cut into learning ruby C extensions. Hopefully it will help promote the power of ruby and the Rails framework to those that have not yet discovered it. My blog is http://metaskills.net and I can be found on twitter as @metaskills. Enjoy!
|
327
331
|
|
328
332
|
|
329
333
|
## Special Thanks
|
data/Rakefile
CHANGED
data/ext/tiny_tds/extconf.rb
CHANGED
@@ -1,12 +1,19 @@
|
|
1
|
+
ENV['RC_ARCHS'] = '' if RUBY_PLATFORM =~ /darwin/
|
2
|
+
|
3
|
+
# :stopdoc:
|
4
|
+
|
1
5
|
require 'mkmf'
|
2
6
|
|
3
|
-
|
4
|
-
|
7
|
+
# Shamelessly copied from nokogiri
|
8
|
+
#
|
9
|
+
LIBDIR = RbConfig::CONFIG['libdir']
|
10
|
+
INCLUDEDIR = RbConfig::CONFIG['includedir']
|
5
11
|
|
6
|
-
|
7
|
-
|
12
|
+
$CFLAGS << " #{ENV["CFLAGS"]}"
|
13
|
+
$LDFLAGS << " #{ENV["LDFLAGS"]}"
|
14
|
+
$LIBS << " #{ENV["LIBS"]}"
|
8
15
|
|
9
|
-
|
16
|
+
SEARCHABLE_PATHS = begin
|
10
17
|
eop_regexp = /#{File::SEPARATOR}bin$/
|
11
18
|
paths = ENV['PATH']
|
12
19
|
paths = paths.gsub(File::ALT_SEPARATOR, File::SEPARATOR) if File::ALT_SEPARATOR
|
@@ -15,69 +22,72 @@ def root_paths
|
|
15
22
|
bin_paths.map{ |p| p.sub(eop_regexp,'') }.compact.reject{ |p| p.empty? }.uniq
|
16
23
|
end
|
17
24
|
|
18
|
-
def
|
19
|
-
|
25
|
+
def searchable_paths_with_directories(*directories)
|
26
|
+
SEARCHABLE_PATHS.map do |path|
|
27
|
+
directories.map do |paths|
|
28
|
+
dir = File.join path, *paths
|
29
|
+
File.directory?(dir) ? dir : nil
|
30
|
+
end.flatten.compact
|
31
|
+
end.flatten.compact
|
20
32
|
end
|
21
33
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
34
|
+
if RbConfig::CONFIG['target_os'] =~ /mswin32|mingw32/
|
35
|
+
lib_prefix = 'lib' unless RbConfig::CONFIG['target_os'] =~ /mingw32/
|
36
|
+
# There's no default include/lib dir on Windows. Let's just add the Ruby ones
|
37
|
+
# and resort on the search path specified by INCLUDE and LIB environment
|
38
|
+
# variables
|
39
|
+
HEADER_DIRS = [INCLUDEDIR]
|
40
|
+
LIB_DIRS = [LIBDIR]
|
41
|
+
else
|
42
|
+
lib_prefix = ''
|
43
|
+
HEADER_DIRS = [
|
44
|
+
# First search /opt/local for macports
|
45
|
+
'/opt/local/include',
|
46
|
+
# Then search /usr/local for people that installed from source
|
47
|
+
'/usr/local/include',
|
48
|
+
# Check the ruby install locations
|
49
|
+
INCLUDEDIR,
|
50
|
+
# Finally fall back to /usr
|
51
|
+
'/usr/include'
|
52
|
+
].reject{ |dir| !File.directory?(dir) }
|
53
|
+
LIB_DIRS = [
|
54
|
+
# First search /opt/local for macports
|
55
|
+
'/opt/local/lib',
|
56
|
+
# Then search /usr/local for people that installed from source
|
57
|
+
'/usr/local/lib',
|
58
|
+
# Check the ruby install locations
|
59
|
+
LIBDIR,
|
60
|
+
# Finally fall back to /usr
|
61
|
+
'/usr/lib',
|
62
|
+
].reject{ |dir| !File.directory?(dir) }
|
41
63
|
end
|
42
64
|
|
43
|
-
|
44
|
-
|
45
|
-
end
|
65
|
+
FREETDS_HEADER_DIRS = (searchable_paths_with_directories(['include'],['include','freetds']) + HEADER_DIRS).uniq
|
66
|
+
FREETDS_LIB_DIRS = (searchable_paths_with_directories(['lib'],['lib','freetds']) + LIB_DIRS).uniq
|
46
67
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
$CPPFLAGS = "-I#{dir} #{$CPPFLAGS}".strip
|
56
|
-
true
|
57
|
-
else
|
58
|
-
false
|
59
|
-
end
|
60
|
-
else
|
61
|
-
puts "#{message} no"
|
62
|
-
false
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
68
|
+
# lookup over searchable paths is great for native compilation, however, when
|
69
|
+
# cross compiling we need to specify our own paths.
|
70
|
+
if enable_config("lookup", true)
|
71
|
+
dir_config('iconv', FREETDS_HEADER_DIRS, FREETDS_LIB_DIRS)
|
72
|
+
dir_config('freetds', FREETDS_HEADER_DIRS, FREETDS_LIB_DIRS)
|
73
|
+
else
|
74
|
+
dir_config('iconv')
|
75
|
+
dir_config('freetds')
|
67
76
|
|
68
|
-
|
69
|
-
|
77
|
+
# remove LDFLAGS
|
78
|
+
$LDFLAGS = ENV.fetch("LDFLAGS", "")
|
70
79
|
end
|
71
80
|
|
72
|
-
|
73
|
-
|
74
|
-
abort "-----\nCan not find FreeTDS's db-lib or include directory.\n-----"
|
75
|
-
end
|
76
|
-
else
|
77
|
-
$LDFLAGS = ENV.fetch("LDFLAGS")
|
78
|
-
unless have_freetds_libraries?(*FREETDS_LIBRARIES) && have_freetds_headers?(*FREETDS_HEADERS)
|
79
|
-
abort "-----\nCan not find FreeTDS's db-lib or include directory.\n-----"
|
80
|
-
end
|
81
|
+
def asplode(lib)
|
82
|
+
abort "-----\n#{lib} is missing.\n-----"
|
81
83
|
end
|
82
84
|
|
85
|
+
asplode 'libiconv' unless have_func('iconv_open', 'iconv.h') || have_library('iconv', 'iconv_open', 'iconv.h')
|
86
|
+
asplode 'freetds' unless have_header('sybfront.h') && have_header('sybdb.h')
|
87
|
+
|
88
|
+
asplode 'freetds' unless find_library("#{lib_prefix}sybdb", 'tdsdbopen')
|
89
|
+
asplode 'freetds' unless find_library("#{lib_prefix}ct", 'ct_bind')
|
90
|
+
|
83
91
|
create_makefile('tiny_tds/tiny_tds')
|
92
|
+
|
93
|
+
# :startdoc:
|
data/lib/tiny_tds/client.rb
CHANGED
@@ -54,6 +54,7 @@ module TinyTds
|
|
54
54
|
|
55
55
|
|
56
56
|
def initialize(opts={})
|
57
|
+
warn 'FreeTDS may have issues with passwords longer than 30 characters!' if opts[:password].to_s.length > 30
|
57
58
|
raise ArgumentError, 'missing :username option' if opts[:username].to_s.empty?
|
58
59
|
raise ArgumentError, 'missing :host option if no :dataserver given' if opts[:dataserver].to_s.empty? && opts[:host].to_s.empty?
|
59
60
|
@query_options = @@default_query_options.dup
|
data/lib/tiny_tds/version.rb
CHANGED
data/test/client_test.rb
CHANGED
@@ -7,7 +7,7 @@ class ClientTest < TinyTds::TestCase
|
|
7
7
|
setup do
|
8
8
|
@client = new_connection
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
should 'not be closed' do
|
12
12
|
assert !@client.closed?
|
13
13
|
assert @client.active?
|
@@ -46,7 +46,7 @@ class ClientTest < TinyTds::TestCase
|
|
46
46
|
end
|
47
47
|
|
48
48
|
should 'be able to use :host/:port connection' do
|
49
|
-
client = new_connection :dataserver => nil, :host => ENV['TINYTDS_UNIT_HOST'], :port => 1433
|
49
|
+
client = new_connection :dataserver => nil, :host => ENV['TINYTDS_UNIT_HOST'], :port => ENV['TINYTDS_UNIT_PORT'] || 1433
|
50
50
|
end unless sqlserver_azure?
|
51
51
|
|
52
52
|
end
|
@@ -136,7 +136,7 @@ class ClientTest < TinyTds::TestCase
|
|
136
136
|
if sqlserver_azure?
|
137
137
|
assert_match %r{server name cannot be determined}i, e.message, 'ignore if non-english test run'
|
138
138
|
else
|
139
|
-
assert_equal 18456, e.db_error_number
|
139
|
+
assert_equal sybase_ase? ? 4002 : 18456, e.db_error_number
|
140
140
|
assert_equal 14, e.severity
|
141
141
|
assert_match %r{login failed}i, e.message, 'ignore if non-english test run'
|
142
142
|
end
|
data/test/result_test.rb
CHANGED
@@ -369,14 +369,22 @@ class ResultTest < TinyTds::TestCase
|
|
369
369
|
end
|
370
370
|
|
371
371
|
should 'from a stored procedure' do
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
372
|
+
if sqlserver?
|
373
|
+
results1, results2 = @client.execute("EXEC sp_helpconstraint '[datatypes]'").each
|
374
|
+
assert_equal [{"Object Name"=>"[datatypes]"}], results1
|
375
|
+
constraint_info = results2.first
|
376
|
+
assert constraint_info.key?("constraint_keys")
|
377
|
+
assert constraint_info.key?("constraint_type")
|
378
|
+
assert constraint_info.key?("constraint_name")
|
379
|
+
elsif sybase_ase?
|
380
|
+
results1, results2 = @client.execute("EXEC sp_helpconstraint 'datatypes'").each
|
381
|
+
assert results1['name'] =~ /^datatypes_bit/
|
382
|
+
assert results1['defintion'] == 'DEFAULT 0'
|
383
|
+
assert results2['name'] =~ /^datatypes_id/
|
384
|
+
assert results2['defintion'] =~ /^PRIMARY KEY/
|
385
|
+
end
|
378
386
|
end
|
379
|
-
|
387
|
+
|
380
388
|
context 'using :empty_sets TRUE' do
|
381
389
|
|
382
390
|
setup do
|
@@ -565,7 +573,7 @@ class ResultTest < TinyTds::TestCase
|
|
565
573
|
insert_and_select_datatype :nvarchar_max
|
566
574
|
end
|
567
575
|
|
568
|
-
end unless sqlserver_2000?
|
576
|
+
end unless sqlserver_2000? || sybase_ase?
|
569
577
|
|
570
578
|
end
|
571
579
|
|
@@ -576,20 +584,36 @@ class ResultTest < TinyTds::TestCase
|
|
576
584
|
assert_equal [], @client.execute('').each
|
577
585
|
end
|
578
586
|
|
579
|
-
|
580
|
-
|
581
|
-
|
587
|
+
if sybase_ase?
|
588
|
+
|
589
|
+
should 'not raise an error when severity is 10 or less' do
|
590
|
+
(1..10).to_a.each do |severity|
|
591
|
+
@client.execute("RAISERROR(N'Test #{severity} severity', #{severity}, 1)").do
|
592
|
+
end
|
582
593
|
end
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
594
|
+
|
595
|
+
should 'raise an error when severity is greater than 10' do
|
596
|
+
action = lambda { @client.execute("RAISERROR(N'Test 11 severity', 11, 1)").do }
|
597
|
+
assert_raise_tinytds_error(action) do |e|
|
598
|
+
assert_equal "Test 11 severity", e.message
|
599
|
+
assert_equal 11, e.severity
|
600
|
+
assert_equal 50000, e.db_error_number
|
601
|
+
end
|
591
602
|
end
|
603
|
+
|
604
|
+
else
|
605
|
+
|
606
|
+
should 'raise an error' do
|
607
|
+
action = lambda { @client.execute("RAISERROR 99999 'Hello World'").do }
|
608
|
+
assert_raise_tinytds_error(action) do |e|
|
609
|
+
assert_equal "Hello World", e.message
|
610
|
+
assert_equal 16, e.severity # predefined on ASE
|
611
|
+
assert_equal 99999, e.db_error_number
|
612
|
+
end
|
613
|
+
end
|
614
|
+
|
592
615
|
end
|
616
|
+
|
593
617
|
|
594
618
|
should 'throw an error when you execute another query with other results pending' do
|
595
619
|
result1 = @client.execute(@query1)
|
@@ -0,0 +1,138 @@
|
|
1
|
+
|
2
|
+
/*
|
3
|
+
|
4
|
+
* Binary Data - Our test binary data is a 1 pixel gif. The basic (raw) data is below. Quoting this data
|
5
|
+
would involve this (encode) method and be (encoded) with the 0x prefix for raw SQL. In other clients the
|
6
|
+
(raw_db) value without the 0x prefix would need to be (packed) again yield the original (raw) value.
|
7
|
+
|
8
|
+
(raw) - "GIF89a\001\000\001\000\221\000\000\377\377\377\377\377\377\376\001\002\000\000\000!\371\004\004\024\000\377\000,\000\000\000\000\001\000\001\000\000\002\002D\001\000;"
|
9
|
+
(encode) - "0x#{raw.unpack("H*")[0]}"
|
10
|
+
(encoded) - "0x47494638396101000100910000fffffffffffffe010200000021f904041400ff002c00000000010001000002024401003b"
|
11
|
+
(raw_db) - "47494638396101000100910000fffffffffffffe010200000021f904041400ff002c00000000010001000002024401003b"
|
12
|
+
(packed) - [raw_db].pack('H*')
|
13
|
+
|
14
|
+
*/
|
15
|
+
|
16
|
+
CREATE TABLE [datatypes] (
|
17
|
+
[id] [int] IDENTITY NOT NULL PRIMARY KEY,
|
18
|
+
[bigint] [bigint] NULL,
|
19
|
+
[binary_50] [binary](50) NULL,
|
20
|
+
[bit] [bit] DEFAULT 0,
|
21
|
+
[char_10] [char](10) NULL,
|
22
|
+
[date] [date] NULL,
|
23
|
+
[datetime] [datetime] NULL,
|
24
|
+
-- [datetime2_7] [datetime2](7) NULL,
|
25
|
+
-- [datetimeoffset_2] [datetimeoffset](2) NULL,
|
26
|
+
-- [datetimeoffset_7] [datetimeoffset](7) NULL,
|
27
|
+
[decimal_9_2] [decimal](9, 2) NULL,
|
28
|
+
[decimal_16_4] [decimal](16, 4) NULL,
|
29
|
+
[float] [float] NULL,
|
30
|
+
-- [geography] [geography] NULL,
|
31
|
+
-- [geometry] [geometry] NULL,
|
32
|
+
-- [hierarchyid] [hierarchyid] NULL,
|
33
|
+
[image] [image] NULL,
|
34
|
+
[int] [int] NULL,
|
35
|
+
[money] [money] NULL,
|
36
|
+
[nchar_10] [nchar](10) NULL,
|
37
|
+
-- [ntext] [ntext] NULL,
|
38
|
+
[numeric_18_0] [numeric](18, 0) NULL,
|
39
|
+
[numeric_36_2] [numeric](36, 2) NULL,
|
40
|
+
[nvarchar_50] [nvarchar](50) NULL,
|
41
|
+
-- [nvarchar_max] [nvarchar](max) NULL,
|
42
|
+
[real] [real] NULL,
|
43
|
+
[smalldatetime] [smalldatetime] NULL,
|
44
|
+
[smallint] [smallint] NULL,
|
45
|
+
[smallmoney] [smallmoney] NULL,
|
46
|
+
[text] [text] NULL,
|
47
|
+
-- [time_2] [time](2) NULL,
|
48
|
+
-- [time_7] [time](7) NULL,
|
49
|
+
[timestamp] [timestamp] NULL,
|
50
|
+
[tinyint] [tinyint] NULL,
|
51
|
+
-- [uniqueidentifier] [uniqueidentifier] NULL,
|
52
|
+
[varbinary_50] [varbinary](50) NULL,
|
53
|
+
-- [varbinary_max] [varbinary](max) NULL,
|
54
|
+
[varchar_50] [varchar](50) NULL
|
55
|
+
-- [varchar_max] [varchar](max) NULL,
|
56
|
+
-- [xml] [xml] NULL
|
57
|
+
)
|
58
|
+
|
59
|
+
SET IDENTITY_INSERT [dbo].[datatypes] ON
|
60
|
+
|
61
|
+
INSERT INTO [datatypes] ([id], [bigint]) VALUES ( 11, -9223372036854775807 )
|
62
|
+
INSERT INTO [datatypes] ([id], [bigint]) VALUES ( 12, 9223372036854775806 )
|
63
|
+
INSERT INTO [datatypes] ([id], [binary_50]) VALUES ( 21, 0x47494638396101000100910000fffffffffffffe010200000021f904041400ff002c00000000010001000002024401003b )
|
64
|
+
INSERT INTO [datatypes] ([id], [bit]) VALUES ( 31, 1 )
|
65
|
+
INSERT INTO [datatypes] ([id], [bit]) VALUES ( 32, 0 )
|
66
|
+
INSERT INTO [datatypes] ([id], [char_10]) VALUES ( 41, '1234567890' )
|
67
|
+
INSERT INTO [datatypes] ([id], [char_10]) VALUES ( 42, '12345678' )
|
68
|
+
INSERT INTO [datatypes] ([id], [date]) VALUES ( 51, '0001-01-01' )
|
69
|
+
INSERT INTO [datatypes] ([id], [date]) VALUES ( 52, '9999-12-31' )
|
70
|
+
INSERT INTO [datatypes] ([id], [datetime]) VALUES ( 61, '1753-01-01T00:00:00.000' )
|
71
|
+
INSERT INTO [datatypes] ([id], [datetime]) VALUES ( 62, '9999-12-31T23:59:59.997' )
|
72
|
+
INSERT INTO [datatypes] ([id], [datetime]) VALUES ( 63, '2010-01-01T12:34:56.123' )
|
73
|
+
-- INSERT INTO [datatypes] ([id], [datetime2_7]) VALUES ( 71, '0001-01-01T00:00:00.0000000Z' )
|
74
|
+
-- INSERT INTO [datatypes] ([id], [datetime2_7]) VALUES ( 72, '1984-01-24T04:20:00.0000000-08:00' )
|
75
|
+
-- INSERT INTO [datatypes] ([id], [datetime2_7]) VALUES ( 73, '9999-12-31T23:59:59.9999999Z' )
|
76
|
+
-- INSERT INTO [datatypes] ([id], [datetimeoffset_2]) VALUES ( 81, '1984-01-24T04:20:00.0000000-08:00' ) -- 1984-01-24 04:20:00.00 -08:00
|
77
|
+
-- INSERT INTO [datatypes] ([id], [datetimeoffset_2]) VALUES ( 82, '1984-01-24T04:20:00.0000000Z' ) -- 1984-01-24 04:20:00.00 +00:00
|
78
|
+
-- INSERT INTO [datatypes] ([id], [datetimeoffset_2]) VALUES ( 83, '9999-12-31T23:59:59.9999999Z' ) -- 9999-12-31 23:59:59.99 +00:00
|
79
|
+
-- INSERT INTO [datatypes] ([id], [datetimeoffset_7]) VALUES ( 84, '1984-01-24T04:20:00.0000000-08:00' ) -- 1984-01-24 04:20:00.0000000 -08:00
|
80
|
+
-- INSERT INTO [datatypes] ([id], [datetimeoffset_7]) VALUES ( 85, '1984-01-24T04:20:00.0000000Z' ) -- 1984-01-24 04:20:00.0000000 +00:00
|
81
|
+
-- INSERT INTO [datatypes] ([id], [datetimeoffset_7]) VALUES ( 86, '9999-12-31T23:59:59.9999999Z' ) -- 9999-12-31 23:59:59.9999999 +00:00
|
82
|
+
INSERT INTO [datatypes] ([id], [decimal_9_2]) VALUES ( 91, 12345.01 )
|
83
|
+
INSERT INTO [datatypes] ([id], [decimal_9_2]) VALUES ( 92, 1234567.89 )
|
84
|
+
INSERT INTO [datatypes] ([id], [decimal_16_4]) VALUES ( 93, 0.0 )
|
85
|
+
INSERT INTO [datatypes] ([id], [decimal_16_4]) VALUES ( 94, 123456789012.3456 )
|
86
|
+
INSERT INTO [datatypes] ([id], [float]) VALUES ( 101, 123.00000001 )
|
87
|
+
INSERT INTO [datatypes] ([id], [float]) VALUES ( 102, 0.0 )
|
88
|
+
INSERT INTO [datatypes] ([id], [float]) VALUES ( 103, 123.45 )
|
89
|
+
-- INSERT INTO [datatypes] ([id], [geography]) VALUES ( 111, geography::STGeomFromText('LINESTRING(-122.360 47.656, -122.343 47.656)', 4326) ) -- 0xE610000001148716D9CEF7D34740D7A3703D0A975EC08716D9CEF7D34740CBA145B6F3955EC0
|
90
|
+
-- INSERT INTO [datatypes] ([id], [geometry]) VALUES ( 121, geometry::STGeomFromText('LINESTRING (100 100, 20 180, 180 180)', 0) ) -- 0x0000000001040300000000000000000059400000000000005940000000000000344000000000008066400000000000806640000000000080664001000000010000000001000000FFFFFFFF0000000002
|
91
|
+
-- INSERT INTO [datatypes] ([id], [hierarchyid]) VALUES ( 131, CAST('/1/' AS hierarchyid) ) -- 0x58
|
92
|
+
-- INSERT INTO [datatypes] ([id], [hierarchyid]) VALUES ( 132, CAST('/2/' AS hierarchyid) ) -- 0x68
|
93
|
+
INSERT INTO [datatypes] ([id], [image]) VALUES ( 141, 0x47494638396101000100910000fffffffffffffe010200000021f904041400ff002c00000000010001000002024401003b )
|
94
|
+
INSERT INTO [datatypes] ([id], [int]) VALUES ( 151, -2147483647 )
|
95
|
+
INSERT INTO [datatypes] ([id], [int]) VALUES ( 152, 2147483646 )
|
96
|
+
INSERT INTO [datatypes] ([id], [money]) VALUES ( 161, 4.20 )
|
97
|
+
INSERT INTO [datatypes] ([id], [money]) VALUES ( 162, -922337203685477.5807 )
|
98
|
+
INSERT INTO [datatypes] ([id], [money]) VALUES ( 163, 922337203685477.5806 )
|
99
|
+
INSERT INTO [datatypes] ([id], [nchar_10]) VALUES ( 171, N'1234567890' )
|
100
|
+
INSERT INTO [datatypes] ([id], [nchar_10]) VALUES ( 172, N'123456åå' )
|
101
|
+
INSERT INTO [datatypes] ([id], [nchar_10]) VALUES ( 173, N'abc123' )
|
102
|
+
-- INSERT INTO [datatypes] ([id], [ntext]) VALUES ( 181, N'test ntext' )
|
103
|
+
-- INSERT INTO [datatypes] ([id], [ntext]) VALUES ( 182, N'test ntext åå' )
|
104
|
+
INSERT INTO [datatypes] ([id], [numeric_18_0]) VALUES ( 191, 191 )
|
105
|
+
INSERT INTO [datatypes] ([id], [numeric_18_0]) VALUES ( 192, 123456789012345678 )
|
106
|
+
INSERT INTO [datatypes] ([id], [numeric_36_2]) VALUES ( 193, 12345678901234567890.01 )
|
107
|
+
INSERT INTO [datatypes] ([id], [numeric_36_2]) VALUES ( 194, 123.46 )
|
108
|
+
INSERT INTO [datatypes] ([id], [nvarchar_50]) VALUES ( 201, N'test nvarchar_50' )
|
109
|
+
INSERT INTO [datatypes] ([id], [nvarchar_50]) VALUES ( 202, N'test nvarchar_50 åå' )
|
110
|
+
-- INSERT INTO [datatypes] ([id], [nvarchar_max]) VALUES ( 211, N'test nvarchar_max' )
|
111
|
+
-- INSERT INTO [datatypes] ([id], [nvarchar_max]) VALUES ( 212, N'test nvarchar_max åå' )
|
112
|
+
INSERT INTO [datatypes] ([id], [real]) VALUES ( 221, 123.45 )
|
113
|
+
INSERT INTO [datatypes] ([id], [real]) VALUES ( 222, 0.0 )
|
114
|
+
INSERT INTO [datatypes] ([id], [real]) VALUES ( 223, 0.00001 )
|
115
|
+
INSERT INTO [datatypes] ([id], [smalldatetime]) VALUES ( 231, '1901-01-01T15:45:00.000' ) -- 1901-01-01 15:45:00
|
116
|
+
INSERT INTO [datatypes] ([id], [smalldatetime]) VALUES ( 232, '2078-06-05T04:20:00.000' ) -- 2078-06-05 04:20:00
|
117
|
+
INSERT INTO [datatypes] ([id], [smallint]) VALUES ( 241, -32767 )
|
118
|
+
INSERT INTO [datatypes] ([id], [smallint]) VALUES ( 242, 32766 )
|
119
|
+
INSERT INTO [datatypes] ([id], [smallmoney]) VALUES ( 251, 4.20 )
|
120
|
+
INSERT INTO [datatypes] ([id], [smallmoney]) VALUES ( 252, -214748.3647 )
|
121
|
+
INSERT INTO [datatypes] ([id], [smallmoney]) VALUES ( 253, 214748.3646 )
|
122
|
+
INSERT INTO [datatypes] ([id], [text]) VALUES ( 271, 'test text' )
|
123
|
+
-- INSERT INTO [datatypes] ([id], [time_2]) VALUES ( 281, '1901-01-01T15:45:00.0100001Z' ) -- 15:45:00.01
|
124
|
+
-- INSERT INTO [datatypes] ([id], [time_2]) VALUES ( 282, '1984-01-24T04:20:00.0000001-08:00' ) -- 04:20:00.00
|
125
|
+
-- INSERT INTO [datatypes] ([id], [time_7]) VALUES ( 283, '1901-01-01T15:45:00.0100001Z' ) -- 15:45:00.0100001
|
126
|
+
-- INSERT INTO [datatypes] ([id], [time_7]) VALUES ( 284, '1984-01-24T04:20:00.0000001-08:00' ) -- 04:20:00.0000001
|
127
|
+
INSERT INTO [datatypes] ([id], [tinyint]) VALUES ( 301, 0 )
|
128
|
+
INSERT INTO [datatypes] ([id], [tinyint]) VALUES ( 302, 255 )
|
129
|
+
-- INSERT INTO [datatypes] ([id], [uniqueidentifier]) VALUES ( 311, NEWID() )
|
130
|
+
INSERT INTO [datatypes] ([id], [varbinary_50]) VALUES ( 321, 0x47494638396101000100910000fffffffffffffe010200000021f904041400ff002c00000000010001000002024401003b )
|
131
|
+
-- INSERT INTO [datatypes] ([id], [varbinary_max]) VALUES ( 331, 0x47494638396101000100910000fffffffffffffe010200000021f904041400ff002c00000000010001000002024401003b )
|
132
|
+
INSERT INTO [datatypes] ([id], [varchar_50]) VALUES ( 341, 'test varchar_50' )
|
133
|
+
-- INSERT INTO [datatypes] ([id], [varchar_max]) VALUES ( 351, 'test varchar_max' )
|
134
|
+
-- INSERT INTO [datatypes] ([id], [xml]) VALUES ( 361, '<foo><bar>batz</bar></foo>' )
|
135
|
+
|
136
|
+
SET IDENTITY_INSERT [datatypes] OFF
|
137
|
+
|
138
|
+
|
data/test/schema_test.rb
CHANGED
@@ -7,7 +7,7 @@ class SchemaTest < TinyTds::TestCase
|
|
7
7
|
|
8
8
|
setup do
|
9
9
|
@@current_schema_loaded ||= load_current_schema
|
10
|
-
@client
|
10
|
+
@client = new_connection
|
11
11
|
@gif1px = ruby19? ? File.read('test/schema/1px.gif',:mode=>"rb:BINARY") : File.read('test/schema/1px.gif')
|
12
12
|
end
|
13
13
|
|
@@ -159,7 +159,7 @@ class SchemaTest < TinyTds::TestCase
|
|
159
159
|
large_value = "x" * 5000
|
160
160
|
large_value_id = @client.execute("INSERT INTO [datatypes] ([ntext]) VALUES (N'#{large_value}')").insert
|
161
161
|
assert_equal large_value, find_value(large_value_id, :ntext)
|
162
|
-
end
|
162
|
+
end unless sybase_ase?
|
163
163
|
|
164
164
|
should 'cast numeric' do
|
165
165
|
assert_instance_of BigDecimal, find_value(191, :numeric_18_0)
|
@@ -257,7 +257,7 @@ class SchemaTest < TinyTds::TestCase
|
|
257
257
|
should 'cast uniqueidentifier' do
|
258
258
|
assert_match %r|\w{8}-\w{4}-\w{4}-\w{4}-\w{12}|, find_value(311, :uniqueidentifier)
|
259
259
|
assert_utf8_encoding find_value(311, :uniqueidentifier)
|
260
|
-
end
|
260
|
+
end unless sybase_ase?
|
261
261
|
|
262
262
|
should 'cast varbinary' do
|
263
263
|
value = find_value(321, :varbinary_50)
|
data/test/test_helper.rb
CHANGED
@@ -16,7 +16,7 @@ class DateTime
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
TINYTDS_SCHEMAS = ['sqlserver_2000', 'sqlserver_2005', 'sqlserver_2008', 'sqlserver_azure'].freeze
|
19
|
+
TINYTDS_SCHEMAS = ['sqlserver_2000', 'sqlserver_2005', 'sqlserver_2008', 'sqlserver_azure', 'sybase_ase'].freeze
|
20
20
|
|
21
21
|
module TinyTds
|
22
22
|
class TestCase < MiniTest::Spec
|
@@ -33,8 +33,15 @@ module TinyTds
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
+
def sqlserver?
|
37
|
+
current_schema =~ /sqlserver/
|
38
|
+
end
|
39
|
+
|
36
40
|
end
|
37
41
|
|
42
|
+
teardown do
|
43
|
+
@client.close if @client.is_a?(TinyTds::Client)
|
44
|
+
end
|
38
45
|
|
39
46
|
protected
|
40
47
|
|
@@ -48,9 +55,15 @@ module TinyTds
|
|
48
55
|
self.class.current_schema
|
49
56
|
end
|
50
57
|
|
58
|
+
def sqlserver?
|
59
|
+
self.class.sqlserver?
|
60
|
+
end
|
61
|
+
|
51
62
|
def new_connection(options={})
|
52
63
|
client = TinyTds::Client.new(connection_options(options))
|
53
|
-
|
64
|
+
if sybase_ase?
|
65
|
+
client.execute("SET ANSINULL ON").do
|
66
|
+
elsif !sqlserver_azure?
|
54
67
|
client.execute("SET ANSI_DEFAULTS ON").do
|
55
68
|
client.execute("SET IMPLICIT_TRANSACTIONS OFF").do
|
56
69
|
client.execute("SET CURSOR_CLOSE_ON_COMMIT OFF").do
|
@@ -59,10 +72,11 @@ module TinyTds
|
|
59
72
|
end
|
60
73
|
|
61
74
|
def connection_options(options={})
|
62
|
-
username = sqlserver_azure? ? ENV['TINYTDS_UNIT_AZURE_USER'] : 'tinytds'
|
63
|
-
password = sqlserver_azure? ? ENV['TINYTDS_UNIT_AZURE_PASS'] : ''
|
75
|
+
username = sqlserver_azure? ? ENV['TINYTDS_UNIT_AZURE_USER'] : ENV['TINYTDS_UNIT_USER'] || 'tinytds'
|
76
|
+
password = sqlserver_azure? ? ENV['TINYTDS_UNIT_AZURE_PASS'] : ENV['TINYTDS_UNIT_PASS'] || ''
|
64
77
|
{ :dataserver => ENV['TINYTDS_UNIT_DATASERVER'],
|
65
78
|
:host => ENV['TINYTDS_UNIT_HOST'],
|
79
|
+
:port => ENV['TINYTDS_UNIT_PORT'],
|
66
80
|
:username => username,
|
67
81
|
:password => password,
|
68
82
|
:database => 'tinytdstest',
|
@@ -139,6 +153,7 @@ module TinyTds
|
|
139
153
|
loader = new_connection
|
140
154
|
schema_file = File.expand_path File.join(File.dirname(__FILE__), 'schema', "#{current_schema}.sql")
|
141
155
|
schema_sql = ruby18? ? File.read(schema_file) : File.open(schema_file,"rb:UTF-8") { |f|f.read }
|
156
|
+
|
142
157
|
loader.execute(drop_sql).each
|
143
158
|
loader.execute(schema_sql).cancel
|
144
159
|
loader.execute(sp_sql).cancel
|
@@ -147,6 +162,19 @@ module TinyTds
|
|
147
162
|
end
|
148
163
|
|
149
164
|
def drop_sql
|
165
|
+
sybase_ase? ? drop_sql_sybase : drop_sql_microsoft
|
166
|
+
end
|
167
|
+
|
168
|
+
def drop_sql_sybase
|
169
|
+
%|IF EXISTS(
|
170
|
+
SELECT 1 FROM sysobjects WHERE type = 'U' AND name = 'datatypes'
|
171
|
+
) DROP TABLE datatypes
|
172
|
+
IF EXISTS(
|
173
|
+
SELECT 1 FROM sysobjects WHERE type = 'P' AND name = 'tinytds_TestReturnCodes'
|
174
|
+
) DROP PROCEDURE tinytds_TestReturnCodes|
|
175
|
+
end
|
176
|
+
|
177
|
+
def drop_sql_microsoft
|
150
178
|
%|IF EXISTS (
|
151
179
|
SELECT TABLE_NAME
|
152
180
|
FROM INFORMATION_SCHEMA.TABLES
|
metadata
CHANGED
@@ -1,15 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tiny_tds
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
5
|
-
prerelease:
|
4
|
+
hash: 9
|
5
|
+
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 5
|
9
9
|
- 1
|
10
|
-
|
11
|
-
- 1
|
12
|
-
version: 0.5.1.rc1
|
10
|
+
version: 0.5.1
|
13
11
|
platform: x86-mingw32
|
14
12
|
authors:
|
15
13
|
- Ken Collins
|
@@ -18,8 +16,7 @@ autorequire:
|
|
18
16
|
bindir: bin
|
19
17
|
cert_chain: []
|
20
18
|
|
21
|
-
date:
|
22
|
-
default_executable:
|
19
|
+
date: 2012-01-23 00:00:00 Z
|
23
20
|
dependencies: []
|
24
21
|
|
25
22
|
description: TinyTDS - A modern, simple and fast FreeTDS library for Ruby using DB-Library. Developed for the ActiveRecord SQL Server adapter.
|
@@ -62,11 +59,11 @@ files:
|
|
62
59
|
- test/schema/sqlserver_2005.sql
|
63
60
|
- test/schema/sqlserver_2008.sql
|
64
61
|
- test/schema/sqlserver_azure.sql
|
62
|
+
- test/schema/sybase_ase.sql
|
65
63
|
- test/schema_test.rb
|
66
64
|
- test/test_helper.rb
|
67
65
|
- lib/tiny_tds/1.8/tiny_tds.so
|
68
66
|
- lib/tiny_tds/1.9/tiny_tds.so
|
69
|
-
has_rdoc: true
|
70
67
|
homepage: http://github.com/rails-sqlserver/tiny_tds
|
71
68
|
licenses: []
|
72
69
|
|
@@ -87,18 +84,16 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
87
84
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
88
85
|
none: false
|
89
86
|
requirements:
|
90
|
-
- - "
|
87
|
+
- - ">="
|
91
88
|
- !ruby/object:Gem::Version
|
92
|
-
hash:
|
89
|
+
hash: 3
|
93
90
|
segments:
|
94
|
-
-
|
95
|
-
|
96
|
-
- 1
|
97
|
-
version: 1.3.1
|
91
|
+
- 0
|
92
|
+
version: "0"
|
98
93
|
requirements: []
|
99
94
|
|
100
95
|
rubyforge_project:
|
101
|
-
rubygems_version: 1.
|
96
|
+
rubygems_version: 1.8.15
|
102
97
|
signing_key:
|
103
98
|
specification_version: 3
|
104
99
|
summary: TinyTDS - A modern, simple and fast FreeTDS library for Ruby using DB-Library.
|
@@ -113,5 +108,6 @@ test_files:
|
|
113
108
|
- test/schema/sqlserver_2005.sql
|
114
109
|
- test/schema/sqlserver_2008.sql
|
115
110
|
- test/schema/sqlserver_azure.sql
|
111
|
+
- test/schema/sybase_ase.sql
|
116
112
|
- test/schema_test.rb
|
117
113
|
- test/test_helper.rb
|