tiny_tds 0.5.2.rc3 → 0.5.2.rc4

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,6 +1,8 @@
1
1
 
2
2
  * 0.5.2 *
3
3
 
4
+ * Use proper SQL for returning IDENTITY with Sybase. Fixes #95.
5
+
4
6
  * Compile windows with `--enable-sspi`.
5
7
 
6
8
  * Allow MiniPortile to build any FreeTDS version we need. Fixes #76.
data/Rakefile CHANGED
@@ -8,9 +8,6 @@ require 'rubygems/package_task'
8
8
 
9
9
  # My notes for cross compile native Windows gem.
10
10
  #
11
- # $ rake-compiler cross-ruby VERSION=1.8.7-p352
12
- # $ rake-compiler cross-ruby VERSION=1.9.2-p290
13
- #
14
11
  # $ rbenv shell 1.8.7
15
12
  # $ git clean -x -d -f
16
13
  # $ bundle install
@@ -193,7 +193,7 @@ static VALUE rb_tinytds_execute(VALUE self, VALUE sql) {
193
193
  return Qfalse;
194
194
  }
195
195
  cwrap->userdata->dbsql_sent = 1;
196
- VALUE result = rb_tinytds_new_result_obj(cwrap->client);
196
+ VALUE result = rb_tinytds_new_result_obj(cwrap);
197
197
  rb_iv_set(result, "@query_options", rb_funcall(rb_iv_get(self, "@query_options"), intern_dup, 0));
198
198
  GET_RESULT_WRAPPER(result);
199
199
  rwrap->local_offset = rb_funcall(cTinyTdsClient, intern_local_offset, 0);
@@ -237,6 +237,11 @@ static VALUE rb_tinytds_return_code(VALUE self) {
237
237
  }
238
238
  }
239
239
 
240
+ static VALUE rb_tinytds_identity_sql(VALUE self) {
241
+ GET_CLIENT_WRAPPER(self);
242
+ return rb_str_new2(cwrap->identity_insert_sql);
243
+ }
244
+
240
245
  static VALUE rb_tinytds_freetds_nine_one_or_higher(VALUE self) {
241
246
  #ifdef DBSETLDBNAME
242
247
  return Qtrue;
@@ -304,6 +309,11 @@ static VALUE rb_tinytds_connect(VALUE self, VALUE opts) {
304
309
  VALUE transposed_encoding = rb_funcall(cTinyTdsClient, intern_transpose_iconv_encoding, 1, charset);
305
310
  cwrap->encoding = rb_enc_find(StringValuePtr(transposed_encoding));
306
311
  #endif
312
+ if (dbtds(cwrap->client) <= 7) {
313
+ cwrap->identity_insert_sql = "SELECT CAST(@@IDENTITY AS bigint) AS Ident";
314
+ } else {
315
+ cwrap->identity_insert_sql = "SELECT CAST(SCOPE_IDENTITY() AS bigint) AS Ident";
316
+ }
307
317
  }
308
318
  return self;
309
319
  }
@@ -326,6 +336,7 @@ void init_tinytds_client() {
326
336
  rb_define_method(cTinyTdsClient, "encoding", rb_tinytds_encoding, 0);
327
337
  rb_define_method(cTinyTdsClient, "escape", rb_tinytds_escape, 1);
328
338
  rb_define_method(cTinyTdsClient, "return_code", rb_tinytds_return_code, 0);
339
+ rb_define_method(cTinyTdsClient, "identity_sql", rb_tinytds_identity_sql, 0);
329
340
  rb_define_method(cTinyTdsClient, "freetds_091_or_higer?", rb_tinytds_freetds_nine_one_or_higher, 0);
330
341
  /* Define TinyTds::Client Protected Methods */
331
342
  rb_define_protected_method(cTinyTdsClient, "connect", rb_tinytds_connect, 1);
@@ -20,6 +20,7 @@ typedef struct {
20
20
  short int closed;
21
21
  VALUE charset;
22
22
  tinytds_client_userdata *userdata;
23
+ const char *identity_insert_sql;
23
24
  #ifdef HAVE_RUBY_ENCODING_H
24
25
  rb_encoding *encoding;
25
26
  #endif
@@ -91,11 +91,12 @@ static void rb_tinytds_result_free(void *ptr) {
91
91
  xfree(ptr);
92
92
  }
93
93
 
94
- VALUE rb_tinytds_new_result_obj(DBPROCESS *c) {
94
+ VALUE rb_tinytds_new_result_obj(tinytds_client_wrapper *cwrap) {
95
95
  VALUE obj;
96
96
  tinytds_result_wrapper *rwrap;
97
97
  obj = Data_Make_Struct(cTinyTdsResult, tinytds_result_wrapper, rb_tinytds_result_mark, rb_tinytds_result_free, rwrap);
98
- rwrap->client = c;
98
+ rwrap->cwrap = cwrap;
99
+ rwrap->client = cwrap->client;
99
100
  rwrap->local_offset = Qnil;
100
101
  rwrap->fields = rb_ary_new();
101
102
  rwrap->fields_processed = rb_ary_new();
@@ -467,7 +468,7 @@ static VALUE rb_tinytds_result_insert(VALUE self) {
467
468
  if (rwrap->client) {
468
469
  rb_tinytds_result_cancel_helper(rwrap->client);
469
470
  VALUE identity = Qnil;
470
- dbcmd(rwrap->client, "SELECT CAST(SCOPE_IDENTITY() AS bigint) AS Ident");
471
+ dbcmd(rwrap->client, rwrap->cwrap->identity_insert_sql);
471
472
  if (dbsqlexec(rwrap->client) != FAIL && dbresults(rwrap->client) != FAIL && DBROWS(rwrap->client) != FAIL) {
472
473
  while (dbnextrow(rwrap->client) != NO_MORE_ROWS) {
473
474
  int col = 1;
@@ -7,9 +7,10 @@
7
7
  #endif
8
8
 
9
9
  void init_tinytds_result();
10
- VALUE rb_tinytds_new_result_obj(DBPROCESS *c);
10
+ VALUE rb_tinytds_new_result_obj(tinytds_client_wrapper *cwrap);
11
11
 
12
12
  typedef struct {
13
+ tinytds_client_wrapper *cwrap;
13
14
  DBPROCESS *client;
14
15
  VALUE local_offset;
15
16
  VALUE fields;
@@ -1,3 +1,3 @@
1
1
  module TinyTds
2
- VERSION = '0.5.2.rc3'
2
+ VERSION = '0.5.2.rc4'
3
3
  end
data/test/client_test.rb CHANGED
@@ -25,8 +25,13 @@ class ClientTest < TinyTds::TestCase
25
25
  end
26
26
 
27
27
  it 'has getters for the tds version information (brittle since conf takes precedence)' do
28
- assert_equal 9, @client.tds_version
29
- assert_equal 'DBTDS_7_1 - Microsoft SQL Server 2000', @client.tds_version_info
28
+ if sybase_ase?
29
+ assert_equal 7, @client.tds_version
30
+ assert_equal 'DBTDS_5_0 - 5.0 SQL Server', @client.tds_version_info
31
+ else
32
+ assert_equal 9, @client.tds_version
33
+ assert_equal 'DBTDS_7_1 - Microsoft SQL Server 2000', @client.tds_version_info
34
+ end
30
35
  end
31
36
 
32
37
  it 'uses UTF-8 client charset/encoding by default' do
@@ -155,7 +160,7 @@ class ClientTest < TinyTds::TestCase
155
160
  assert_match %r{connection failed}i, e.message, 'ignore if non-english test run'
156
161
  end
157
162
  assert_new_connections_work
158
- end
163
+ end unless sybase_ase?
159
164
 
160
165
  end
161
166
 
data/test/result_test.rb CHANGED
@@ -128,11 +128,8 @@ class ResultTest < TinyTds::TestCase
128
128
  afrows = @client.execute("SELECT @@ROWCOUNT AS AffectedRows").each.first['AffectedRows']
129
129
  assert_instance_of Fixnum, afrows
130
130
  @client.execute("INSERT INTO [datatypes] ([varchar_50]) VALUES ('#{text}')").do
131
- pk1 = @client.execute("SELECT SCOPE_IDENTITY() AS Ident").each.first['Ident']
132
- assert_instance_of BigDecimal, pk1, 'native is numeric(38,0) for SCOPE_IDENTITY() function'
133
- pk2 = @client.execute("SELECT CAST(SCOPE_IDENTITY() AS bigint) AS Ident").each.first['Ident']
134
- assert_instance_of Fixnum, pk2, 'we it be able to CAST to bigint'
135
- assert_equal pk2, pk1.to_i, 'just making sure the 2 line up'
131
+ pk1 = @client.execute(@client.identity_sql).each.first['Ident']
132
+ assert_instance_of Fixnum, pk1, 'we it be able to CAST to bigint'
136
133
  @client.execute("UPDATE [datatypes] SET [varchar_50] = NULL WHERE [varchar_50] = '#{text}'").do
137
134
  afrows = @client.execute("SELECT @@ROWCOUNT AS AffectedRows").each.first['AffectedRows']
138
135
  assert_equal 1, afrows
@@ -164,12 +161,12 @@ class ResultTest < TinyTds::TestCase
164
161
  end
165
162
  end
166
163
 
167
- it 'has an #insert method that cancels result rows and returns the SCOPE_IDENTITY() natively' do
164
+ it 'has an #insert method that cancels result rows and returns IDENTITY natively' do
168
165
  rollback_transaction(@client) do
169
166
  text = 'test scope identity rows native'
170
167
  @client.execute("DELETE FROM [datatypes] WHERE [varchar_50] = '#{text}'").do
171
168
  @client.execute("INSERT INTO [datatypes] ([varchar_50]) VALUES ('#{text}')").do
172
- sql_identity = @client.execute("SELECT CAST(SCOPE_IDENTITY() AS bigint) AS Ident").each.first['Ident']
169
+ sql_identity = @client.execute(@client.identity_sql).each.first['Ident']
173
170
  native_identity = @client.execute("INSERT INTO [datatypes] ([varchar_50]) VALUES ('#{text}')").insert
174
171
  assert_equal sql_identity+1, native_identity
175
172
  end
@@ -177,6 +174,9 @@ class ResultTest < TinyTds::TestCase
177
174
 
178
175
  it 'returns bigint for #insert when needed' do
179
176
  return if sqlserver_azure? # We can not alter clustered index like this test does.
177
+ return if sybase_ase? # On Sybase, sp_helpindex cannot be used inside a transaction since it does a
178
+ # 'CREATE TABLE' command is not allowed within a multi-statement transaction
179
+ # and and sp_helpindex creates a temporary table #spindtab.
180
180
  rollback_transaction(@client) do
181
181
  seed = 9223372036854775805
182
182
  @client.execute("DELETE FROM [datatypes]").do
@@ -189,7 +189,7 @@ class ResultTest < TinyTds::TestCase
189
189
  assert_equal seed, identity
190
190
  end
191
191
  end
192
-
192
+
193
193
  it 'must be able to begin/commit transactions with raw sql' do
194
194
  rollback_transaction(@client) do
195
195
  @client.execute("BEGIN TRANSACTION").do
@@ -584,7 +584,7 @@ class ResultTest < TinyTds::TestCase
584
584
  assert_equal [], @client.execute('').each
585
585
  end
586
586
 
587
- if sybase_ase?
587
+ if sqlserver?
588
588
 
589
589
  it 'must not raise an error when severity is 10 or less' do
590
590
  (1..10).to_a.each do |severity|
@@ -604,7 +604,7 @@ class ResultTest < TinyTds::TestCase
604
604
  else
605
605
 
606
606
  it 'raises an error' do
607
- action = lambda { @client.execute("RAISERROR (N'Hello World', 16, 1)").do }
607
+ action = lambda { @client.execute("RAISERROR 50000 N'Hello World'").do }
608
608
  assert_raise_tinytds_error(action) do |e|
609
609
  assert_equal "Hello World", e.message
610
610
  assert_equal 16, e.severity # predefined on ASE
@@ -628,7 +628,8 @@ class ResultTest < TinyTds::TestCase
628
628
  it 'must error gracefully with bad table name' do
629
629
  action = lambda { @client.execute('SELECT * FROM [foobar]').each }
630
630
  assert_raise_tinytds_error(action) do |e|
631
- assert_match %r|invalid object name.*foobar|i, e.message
631
+ pattern = sybase_ase? ? /foobar not found/ : %r|invalid object name.*foobar|i
632
+ assert_match pattern, e.message
632
633
  assert_equal 16, e.severity
633
634
  assert_equal 208, e.db_error_number
634
635
  end
@@ -679,7 +680,7 @@ class ResultTest < TinyTds::TestCase
679
680
  else
680
681
  skip 'FreeTDS 0.91 and higher can only pass this test.'
681
682
  end
682
- end
683
+ end unless sybase_ase?
683
684
 
684
685
  end
685
686
 
@@ -56,7 +56,7 @@ CREATE TABLE [datatypes] (
56
56
  -- [xml] [xml] NULL
57
57
  )
58
58
 
59
- SET IDENTITY_INSERT [dbo].[datatypes] ON
59
+ SET IDENTITY_INSERT [datatypes] ON
60
60
 
61
61
  INSERT INTO [datatypes] ([id], [bigint]) VALUES ( 11, -9223372036854775807 )
62
62
  INSERT INTO [datatypes] ([id], [bigint]) VALUES ( 12, 9223372036854775806 )
@@ -100,7 +100,7 @@ INSERT INTO [datatypes] ([id], [nchar_10]) VALUES ( 171, N'1234567890'
100
100
  INSERT INTO [datatypes] ([id], [nchar_10]) VALUES ( 172, N'123456åå' )
101
101
  INSERT INTO [datatypes] ([id], [nchar_10]) VALUES ( 173, N'abc123' )
102
102
  -- INSERT INTO [datatypes] ([id], [ntext]) VALUES ( 181, N'test ntext' )
103
- -- INSERT INTO [datatypes] ([id], [ntext]) VALUES ( 182, N'test ntext åå' )
103
+ -- INSERT INTO [datatypes] ([id], [ntext]) VALUES ( 182, N'test ntext' ) -- Removed UTF-8 chars. They make sybase choke in comments.
104
104
  INSERT INTO [datatypes] ([id], [numeric_18_0]) VALUES ( 191, 191 )
105
105
  INSERT INTO [datatypes] ([id], [numeric_18_0]) VALUES ( 192, 123456789012345678 )
106
106
  INSERT INTO [datatypes] ([id], [numeric_36_2]) VALUES ( 193, 12345678901234567890.01 )
@@ -108,7 +108,7 @@ INSERT INTO [datatypes] ([id], [numeric_36_2]) VALUES ( 194, 123.46 )
108
108
  INSERT INTO [datatypes] ([id], [nvarchar_50]) VALUES ( 201, N'test nvarchar_50' )
109
109
  INSERT INTO [datatypes] ([id], [nvarchar_50]) VALUES ( 202, N'test nvarchar_50 åå' )
110
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 åå' )
111
+ -- INSERT INTO [datatypes] ([id], [nvarchar_max]) VALUES ( 212, N'test nvarchar_max' ) -- Removed UTF-8 chars. They make sybase choke in comments.
112
112
  INSERT INTO [datatypes] ([id], [real]) VALUES ( 221, 123.45 )
113
113
  INSERT INTO [datatypes] ([id], [real]) VALUES ( 222, 0.0 )
114
114
  INSERT INTO [datatypes] ([id], [real]) VALUES ( 223, 0.00001 )
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tiny_tds
3
3
  version: !ruby/object:Gem::Version
4
- hash: 2522453041
4
+ hash: 2270804295
5
5
  prerelease: 6
6
6
  segments:
7
7
  - 0
8
8
  - 5
9
9
  - 2
10
10
  - rc
11
- - 3
12
- version: 0.5.2.rc3
11
+ - 4
12
+ version: 0.5.2.rc4
13
13
  platform: ruby
14
14
  authors:
15
15
  - Ken Collins
@@ -18,7 +18,7 @@ autorequire:
18
18
  bindir: bin
19
19
  cert_chain: []
20
20
 
21
- date: 2012-11-12 00:00:00 -05:00
21
+ date: 2012-11-17 00:00:00 -05:00
22
22
  default_executable:
23
23
  dependencies:
24
24
  - !ruby/object:Gem::Dependency