tiny_tds 2.1.7 → 3.0.0

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/test/result_test.rb CHANGED
@@ -154,7 +154,7 @@ class ResultTest < TinyTds::TestCase
154
154
  inserted_rows = @client.execute("INSERT INTO [datatypes] ([varchar_50]) VALUES ('#{text}')").do
155
155
  assert_equal 1, inserted_rows, 'should have inserted row for one above'
156
156
  updated_rows = @client.execute("UPDATE [datatypes] SET [varchar_50] = NULL WHERE [varchar_50] = '#{text}'").do
157
- assert_equal 1, updated_rows, 'should have updated row for one above' unless sqlserver_2000? # Will report -1
157
+ assert_equal 1, updated_rows, 'should have updated row for one above'
158
158
  end
159
159
  end
160
160
 
@@ -166,7 +166,7 @@ class ResultTest < TinyTds::TestCase
166
166
  inserted_rows = @client.execute("INSERT INTO [datatypes] ([varchar_50]) VALUES ('#{text}')").do
167
167
  assert_equal 1, inserted_rows, 'should have inserted row for one above'
168
168
  updated_rows = @client.execute("UPDATE [datatypes] SET [varchar_50] = NULL WHERE [varchar_50] = '#{text}'").do
169
- assert_equal 1, updated_rows, 'should have updated row for one above' unless sqlserver_2000? # Will report -1
169
+ assert_equal 1, updated_rows, 'should have updated row for one above'
170
170
  end
171
171
  end
172
172
 
@@ -177,19 +177,18 @@ class ResultTest < TinyTds::TestCase
177
177
  @client.execute("INSERT INTO [datatypes] ([varchar_50]) VALUES ('#{text}')").do
178
178
  sql_identity = @client.execute(@client.identity_sql).each.first['Ident']
179
179
  native_identity = @client.execute("INSERT INTO [datatypes] ([varchar_50]) VALUES ('#{text}')").insert
180
- assert_equal sql_identity+1, native_identity
180
+ assert_equal sql_identity + 1, native_identity
181
181
  end
182
182
  end
183
183
 
184
184
  it 'returns bigint for #insert when needed' do
185
185
  return if sqlserver_azure? # We can not alter clustered index like this test does.
186
- return if sybase_ase? # On Sybase, sp_helpindex cannot be used inside a transaction since it does a
187
- # 'CREATE TABLE' command is not allowed within a multi-statement transaction
188
- # and and sp_helpindex creates a temporary table #spindtab.
186
+ # 'CREATE TABLE' command is not allowed within a multi-statement transaction
187
+ # and and sp_helpindex creates a temporary table #spindtab.
189
188
  rollback_transaction(@client) do
190
189
  seed = 9223372036854775805
191
190
  @client.execute("DELETE FROM [datatypes]").do
192
- id_constraint_name = @client.execute("EXEC sp_helpindex [datatypes]").detect{ |row| row['index_keys'] == 'id' }['index_name']
191
+ id_constraint_name = @client.execute("EXEC sp_helpindex [datatypes]").detect { |row| row['index_keys'] == 'id' }['index_name']
193
192
  @client.execute("ALTER TABLE [datatypes] DROP CONSTRAINT [#{id_constraint_name}]").do
194
193
  @client.execute("ALTER TABLE [datatypes] DROP COLUMN [id]").do
195
194
  @client.execute("ALTER TABLE [datatypes] ADD [id] [bigint] NOT NULL IDENTITY(1,1) PRIMARY KEY").do
@@ -236,13 +235,13 @@ class ResultTest < TinyTds::TestCase
236
235
  no_results_query = "SELECT [id], [varchar_50] FROM [datatypes] WHERE [varchar_50] = 'NOTFOUND'"
237
236
  # Fields before each.
238
237
  result = @client.execute(no_results_query)
239
- _(result.fields).must_equal ['id','varchar_50']
238
+ _(result.fields).must_equal ['id', 'varchar_50']
240
239
  result.each
241
- _(result.fields).must_equal ['id','varchar_50']
240
+ _(result.fields).must_equal ['id', 'varchar_50']
242
241
  # Each then fields
243
242
  result = @client.execute(no_results_query)
244
243
  result.each
245
- _(result.fields).must_equal ['id','varchar_50']
244
+ _(result.fields).must_equal ['id', 'varchar_50']
246
245
  end
247
246
 
248
247
  it 'allows the result to be canceled before reading' do
@@ -307,7 +306,7 @@ class ResultTest < TinyTds::TestCase
307
306
 
308
307
  it 'use same string object for hash keys' do
309
308
  data = @client.execute("SELECT [id], [bigint] FROM [datatypes]").each
310
- assert_equal data.first.keys.map{ |r| r.object_id }, data.last.keys.map{ |r| r.object_id }
309
+ assert_equal data.first.keys.map { |r| r.object_id }, data.last.keys.map { |r| r.object_id }
311
310
  end
312
311
 
313
312
  it 'has properly encoded column names with symbol keys' do
@@ -326,7 +325,7 @@ class ResultTest < TinyTds::TestCase
326
325
  it 'allows #return_code to work with stored procedures and reset per sql batch' do
327
326
  assert_nil @client.return_code
328
327
  result = @client.execute("EXEC tinytds_TestReturnCodes")
329
- assert_equal [{"one"=>1}], result.each
328
+ assert_equal [{ "one" => 1 }], result.each
330
329
  assert_equal 420, @client.return_code
331
330
  assert_equal 420, result.return_code
332
331
  result = @client.execute('SELECT 1 as [one]')
@@ -343,7 +342,7 @@ class ResultTest < TinyTds::TestCase
343
342
  describe 'with multiple result sets' do
344
343
 
345
344
  before do
346
- @empty_select = "SELECT 1 AS [rs1] WHERE 1 = 0"
345
+ @empty_select = "SELECT 1 AS [rs1] WHERE 1 = 0"
347
346
  @double_select = "SELECT 1 AS [rs1]
348
347
  SELECT 2 AS [rs2]"
349
348
  @triple_select_1st_empty = "SELECT 1 AS [rs1] WHERE 1 = 0
@@ -361,8 +360,8 @@ class ResultTest < TinyTds::TestCase
361
360
  result = @client.execute(@double_select)
362
361
  result_sets = result.each
363
362
  assert_equal 2, result_sets.size
364
- assert_equal [{'rs1' => 1}], result_sets.first
365
- assert_equal [{'rs2' => 2}], result_sets.last
363
+ assert_equal [{ 'rs1' => 1 }], result_sets.first
364
+ assert_equal [{ 'rs2' => 2 }], result_sets.last
366
365
  assert_equal [['rs1'], ['rs2']], result.fields
367
366
  assert_equal result.each.object_id, result.each.object_id, 'same cached rows'
368
367
  # As array
@@ -383,20 +382,12 @@ class ResultTest < TinyTds::TestCase
383
382
  end
384
383
 
385
384
  it 'works from a stored procedure' do
386
- if sqlserver?
387
- results1, results2 = @client.execute("EXEC sp_helpconstraint '[datatypes]'").each
388
- assert_equal [{"Object Name"=>"[datatypes]"}], results1
389
- constraint_info = results2.first
390
- assert constraint_info.key?("constraint_keys")
391
- assert constraint_info.key?("constraint_type")
392
- assert constraint_info.key?("constraint_name")
393
- elsif sybase_ase?
394
- results1, results2 = @client.execute("EXEC sp_helpconstraint 'datatypes'").each
395
- assert results1['name'] =~ /^datatypes_bit/
396
- assert results1['defintion'] == 'DEFAULT 0'
397
- assert results2['name'] =~ /^datatypes_id/
398
- assert results2['defintion'] =~ /^PRIMARY KEY/
399
- end
385
+ results1, results2 = @client.execute("EXEC sp_helpconstraint '[datatypes]'").each
386
+ assert_equal [{ "Object Name" => "[datatypes]" }], results1
387
+ constraint_info = results2.first
388
+ assert constraint_info.key?("constraint_keys")
389
+ assert constraint_info.key?("constraint_type")
390
+ assert constraint_info.key?("constraint_name")
400
391
  end
401
392
 
402
393
  describe 'using :empty_sets TRUE' do
@@ -423,8 +414,8 @@ class ResultTest < TinyTds::TestCase
423
414
  result_sets = result.each
424
415
  assert_equal 3, result_sets.size
425
416
  assert_equal [], result_sets[0]
426
- assert_equal [{'rs2' => 2}], result_sets[1]
427
- assert_equal [{'rs3' => 3}], result_sets[2]
417
+ assert_equal [{ 'rs2' => 2 }], result_sets[1]
418
+ assert_equal [{ 'rs3' => 3 }], result_sets[2]
428
419
  assert_equal [['rs1'], ['rs2'], ['rs3']], result.fields
429
420
  assert_equal result.each.object_id, result.each.object_id, 'same cached rows'
430
421
  # As array
@@ -442,9 +433,9 @@ class ResultTest < TinyTds::TestCase
442
433
  result = @client.execute(@triple_select_2nd_empty)
443
434
  result_sets = result.each
444
435
  assert_equal 3, result_sets.size
445
- assert_equal [{'rs1' => 1}], result_sets[0]
436
+ assert_equal [{ 'rs1' => 1 }], result_sets[0]
446
437
  assert_equal [], result_sets[1]
447
- assert_equal [{'rs3' => 3}], result_sets[2]
438
+ assert_equal [{ 'rs3' => 3 }], result_sets[2]
448
439
  assert_equal [['rs1'], ['rs2'], ['rs3']], result.fields
449
440
  assert_equal result.each.object_id, result.each.object_id, 'same cached rows'
450
441
  # As array
@@ -462,8 +453,8 @@ class ResultTest < TinyTds::TestCase
462
453
  result = @client.execute(@triple_select_3rd_empty)
463
454
  result_sets = result.each
464
455
  assert_equal 3, result_sets.size
465
- assert_equal [{'rs1' => 1}], result_sets[0]
466
- assert_equal [{'rs2' => 2}], result_sets[1]
456
+ assert_equal [{ 'rs1' => 1 }], result_sets[0]
457
+ assert_equal [{ 'rs2' => 2 }], result_sets[1]
467
458
  assert_equal [], result_sets[2]
468
459
  assert_equal [['rs1'], ['rs2'], ['rs3']], result.fields
469
460
  assert_equal result.each.object_id, result.each.object_id, 'same cached rows'
@@ -503,8 +494,8 @@ class ResultTest < TinyTds::TestCase
503
494
  result = @client.execute(@triple_select_1st_empty)
504
495
  result_sets = result.each
505
496
  assert_equal 2, result_sets.size
506
- assert_equal [{'rs2' => 2}], result_sets[0]
507
- assert_equal [{'rs3' => 3}], result_sets[1]
497
+ assert_equal [{ 'rs2' => 2 }], result_sets[0]
498
+ assert_equal [{ 'rs3' => 3 }], result_sets[1]
508
499
  assert_equal [['rs2'], ['rs3']], result.fields
509
500
  assert_equal result.each.object_id, result.each.object_id, 'same cached rows'
510
501
  # As array
@@ -521,8 +512,8 @@ class ResultTest < TinyTds::TestCase
521
512
  result = @client.execute(@triple_select_2nd_empty)
522
513
  result_sets = result.each
523
514
  assert_equal 2, result_sets.size
524
- assert_equal [{'rs1' => 1}], result_sets[0]
525
- assert_equal [{'rs3' => 3}], result_sets[1]
515
+ assert_equal [{ 'rs1' => 1 }], result_sets[0]
516
+ assert_equal [{ 'rs3' => 3 }], result_sets[1]
526
517
  assert_equal [['rs1'], ['rs3']], result.fields
527
518
  assert_equal result.each.object_id, result.each.object_id, 'same cached rows'
528
519
  # As array
@@ -539,8 +530,8 @@ class ResultTest < TinyTds::TestCase
539
530
  result = @client.execute(@triple_select_3rd_empty)
540
531
  result_sets = result.each
541
532
  assert_equal 2, result_sets.size
542
- assert_equal [{'rs1' => 1}], result_sets[0]
543
- assert_equal [{'rs2' => 2}], result_sets[1]
533
+ assert_equal [{ 'rs1' => 1 }], result_sets[0]
534
+ assert_equal [{ 'rs2' => 2 }], result_sets[1]
544
535
  assert_equal [['rs1'], ['rs2']], result.fields
545
536
  assert_equal result.each.object_id, result.each.object_id, 'same cached rows'
546
537
  # As array
@@ -590,7 +581,7 @@ class ResultTest < TinyTds::TestCase
590
581
  before do
591
582
  @big_text = 'x' * 2_000_000
592
583
  @old_textsize = @client.execute("SELECT @@TEXTSIZE AS [textsize]").each.first['textsize'].inspect
593
- @client.execute("SET TEXTSIZE #{(@big_text.length*2)+1}").do
584
+ @client.execute("SET TEXTSIZE #{(@big_text.length * 2) + 1}").do
594
585
  end
595
586
 
596
587
  it 'must insert and select large varchar_max' do
@@ -601,7 +592,7 @@ class ResultTest < TinyTds::TestCase
601
592
  insert_and_select_datatype :nvarchar_max
602
593
  end
603
594
 
604
- end unless sqlserver_2000? || sybase_ase?
595
+ end
605
596
 
606
597
  end
607
598
 
@@ -612,189 +603,105 @@ class ResultTest < TinyTds::TestCase
612
603
  assert_equal [], @client.execute('').each
613
604
  end
614
605
 
615
- if sqlserver?
606
+ describe 'using :message_handler option' do
607
+ let(:messages) { Array.new }
616
608
 
617
- describe 'using :message_handler option' do
618
- let(:messages) { Array.new }
619
-
620
- before do
621
- close_client
622
- @client = new_connection message_handler: Proc.new { |m| messages << m }
623
- end
624
-
625
- after do
626
- messages.clear
627
- end
609
+ before do
610
+ close_client
611
+ @client = new_connection message_handler: Proc.new { |m| messages << m }
612
+ end
628
613
 
629
- it 'has a message handler that responds to call' do
630
- assert @client.message_handler.respond_to?(:call)
631
- end
614
+ after do
615
+ messages.clear
616
+ end
632
617
 
633
- it 'calls the provided message handler when severity is 10 or less' do
634
- (1..10).to_a.each do |severity|
635
- messages.clear
636
- msg = "Test #{severity} severity"
637
- state = rand(1..255)
638
- @client.execute("RAISERROR(N'#{msg}', #{severity}, #{state})").do
639
- m = messages.first
640
- assert_equal 1, messages.length, 'there should be one message after one raiserror'
641
- assert_equal msg, m.message, 'message text'
642
- assert_equal severity, m.severity, 'message severity' unless severity == 10 && m.severity.to_i == 0
643
- assert_equal state, m.os_error_number, 'message state'
644
- end
645
- end
618
+ it 'has a message handler that responds to call' do
619
+ assert @client.message_handler.respond_to?(:call)
620
+ end
646
621
 
647
- it 'calls the provided message handler for `print` messages' do
622
+ it 'calls the provided message handler when severity is 10 or less' do
623
+ (1..10).to_a.each do |severity|
648
624
  messages.clear
649
- msg = 'hello'
650
- @client.execute("PRINT '#{msg}'").do
625
+ msg = "Test #{severity} severity"
626
+ state = rand(1..255)
627
+ @client.execute("RAISERROR(N'#{msg}', #{severity}, #{state})").do
651
628
  m = messages.first
652
- assert_equal 1, messages.length, 'there should be one message after one print statement'
629
+ assert_equal 1, messages.length, 'there should be one message after one raiserror'
653
630
  assert_equal msg, m.message, 'message text'
654
- end
655
-
656
- it 'must raise an error preceded by a `print` message' do
657
- messages.clear
658
- action = lambda { @client.execute("EXEC tinytds_TestPrintWithError").do }
659
- assert_raise_tinytds_error(action) do |e|
660
- assert_equal 'hello', messages.first.message, 'message text'
661
-
662
- assert_equal "Error following print", e.message
663
- assert_equal 16, e.severity
664
- assert_equal 50000, e.db_error_number
665
- end
666
- end
667
-
668
- it 'calls the provided message handler for each of a series of `print` messages' do
669
- messages.clear
670
- @client.execute("EXEC tinytds_TestSeveralPrints").do
671
- assert_equal ['hello 1', 'hello 2', 'hello 3'], messages.map { |e| e.message }, 'message list'
672
- end
673
-
674
- it 'should flush info messages before raising error in cases of timeout' do
675
- @client = new_connection timeout: 1, message_handler: Proc.new { |m| messages << m }
676
- action = lambda { @client.execute("print 'hello'; waitfor delay '00:00:02'").do }
677
- messages.clear
678
- assert_raise_tinytds_error(action) do |e|
679
- assert_match %r{timed out}i, e.message, 'ignore if non-english test run'
680
- assert_equal 6, e.severity
681
- assert_equal 20003, e.db_error_number
682
- assert_equal 'hello', messages.first&.message, 'message text'
683
- end
684
- end
685
-
686
- it 'should print info messages before raising error in cases of timeout' do
687
- @client = new_connection timeout: 1, message_handler: Proc.new { |m| messages << m }
688
- action = lambda { @client.execute("raiserror('hello', 1, 1) with nowait; waitfor delay '00:00:02'").do }
689
- messages.clear
690
- assert_raise_tinytds_error(action) do |e|
691
- assert_match %r{timed out}i, e.message, 'ignore if non-english test run'
692
- assert_equal 6, e.severity
693
- assert_equal 20003, e.db_error_number
694
- assert_equal 'hello', messages.first&.message, 'message text'
695
- end
631
+ assert_equal severity, m.severity, 'message severity' unless severity == 10 && m.severity.to_i == 0
632
+ assert_equal state, m.os_error_number, 'message state'
696
633
  end
697
634
  end
698
635
 
699
- it 'must not raise an error when severity is 10 or less' do
700
- (1..10).to_a.each do |severity|
701
- @client.execute("RAISERROR(N'Test #{severity} severity', #{severity}, 1)").do
702
- end
636
+ it 'calls the provided message handler for `print` messages' do
637
+ messages.clear
638
+ msg = 'hello'
639
+ @client.execute("PRINT '#{msg}'").do
640
+ m = messages.first
641
+ assert_equal 1, messages.length, 'there should be one message after one print statement'
642
+ assert_equal msg, m.message, 'message text'
703
643
  end
704
644
 
705
- it 'raises an error when severity is greater than 10' do
706
- action = lambda { @client.execute("RAISERROR(N'Test 11 severity', 11, 1)").do }
645
+ it 'must raise an error preceded by a `print` message' do
646
+ messages.clear
647
+ action = lambda { @client.execute("EXEC tinytds_TestPrintWithError").do }
707
648
  assert_raise_tinytds_error(action) do |e|
708
- assert_equal "Test 11 severity", e.message
709
- assert_equal 11, e.severity
649
+ assert_equal 'hello', messages.first.message, 'message text'
650
+
651
+ assert_equal "Error following print", e.message
652
+ assert_equal 16, e.severity
710
653
  assert_equal 50000, e.db_error_number
711
654
  end
712
655
  end
713
656
 
714
- else
657
+ it 'calls the provided message handler for each of a series of `print` messages' do
658
+ messages.clear
659
+ @client.execute("EXEC tinytds_TestSeveralPrints").do
660
+ assert_equal ['hello 1', 'hello 2', 'hello 3'], messages.map { |e| e.message }, 'message list'
661
+ end
715
662
 
716
- it 'raises an error' do
717
- action = lambda { @client.execute("RAISERROR 50000 N'Hello World'").do }
663
+ it 'should flush info messages before raising error in cases of timeout' do
664
+ @client = new_connection timeout: 1, message_handler: Proc.new { |m| messages << m }
665
+ action = lambda { @client.execute("print 'hello'; waitfor delay '00:00:02'").do }
666
+ messages.clear
718
667
  assert_raise_tinytds_error(action) do |e|
719
- assert_equal "Hello World", e.message
720
- assert_equal 16, e.severity # predefined on ASE
721
- assert_equal 50000, e.db_error_number
668
+ assert_match %r{timed out}i, e.message, 'ignore if non-english test run'
669
+ assert_equal 6, e.severity
670
+ assert_equal 20003, e.db_error_number
671
+ assert_equal 'hello', messages.first&.message, 'message text'
722
672
  end
723
- assert_followup_query
724
673
  end
725
674
 
726
- end
727
-
728
- it 'throws an error when you execute another query with other results pending' do
729
- @client.execute(@query1)
730
- action = lambda { @client.execute(@query1) }
731
- assert_raise_tinytds_error(action) do |e|
732
- assert_match %r|with results pending|i, e.message
733
- assert_equal 7, e.severity
734
- assert_equal 20019, e.db_error_number
675
+ it 'should print info messages before raising error in cases of timeout' do
676
+ @client = new_connection timeout: 1, message_handler: Proc.new { |m| messages << m }
677
+ action = lambda { @client.execute("raiserror('hello', 1, 1) with nowait; waitfor delay '00:00:02'").do }
678
+ messages.clear
679
+ assert_raise_tinytds_error(action) do |e|
680
+ assert_match %r{timed out}i, e.message, 'ignore if non-english test run'
681
+ assert_equal 6, e.severity
682
+ assert_equal 20003, e.db_error_number
683
+ assert_equal 'hello', messages.first&.message, 'message text'
684
+ end
735
685
  end
736
686
  end
737
687
 
738
- it 'must error gracefully with bad table name' do
739
- action = lambda { @client.execute('SELECT * FROM [foobar]').each }
740
- assert_raise_tinytds_error(action) do |e|
741
- pattern = sybase_ase? ? /foobar not found/ : %r|invalid object name.*foobar|i
742
- assert_match pattern, e.message
743
- assert_equal 16, e.severity
744
- assert_equal 208, e.db_error_number
688
+ it 'must not raise an error when severity is 10 or less' do
689
+ (1..10).to_a.each do |severity|
690
+ @client.execute("RAISERROR(N'Test #{severity} severity', #{severity}, 1)").do
745
691
  end
746
- assert_followup_query
747
692
  end
748
693
 
749
- it 'must error gracefully with incorrect syntax' do
750
- action = lambda { @client.execute('this will not work').each }
694
+ it 'raises an error when severity is greater than 10' do
695
+ action = lambda { @client.execute("RAISERROR(N'Test 11 severity', 11, 1)").do }
751
696
  assert_raise_tinytds_error(action) do |e|
752
- assert_match %r|incorrect syntax|i, e.message
753
- assert_equal 15, e.severity
754
- assert_equal 156, e.db_error_number
697
+ assert_equal "Test 11 severity", e.message
698
+ assert_equal 11, e.severity
699
+ assert_equal 50000, e.db_error_number
755
700
  end
756
- assert_followup_query
757
701
  end
758
-
759
- it 'must not error at all from reading non-convertable charcters and just use ? marks' do
760
- close_client
761
- @client = new_connection :encoding => 'ASCII'
762
- _(@client.charset).must_equal 'ASCII'
763
- _(find_value(202, :nvarchar_50)).must_equal 'test nvarchar_50 ??'
764
- end
765
-
766
- it 'must error gracefully from writing non-convertable characters' do
767
- close_client
768
- @client = new_connection :encoding => 'ASCII'
769
- _(@client.charset).must_equal 'ASCII'
770
- rollback_transaction(@client) do
771
- text = 'Test ✓'
772
- @client.execute("DELETE FROM [datatypes] WHERE [nvarchar_50] IS NOT NULL").do
773
- action = lambda { @client.execute("INSERT INTO [datatypes] ([nvarchar_50]) VALUES ('#{text}')").do }
774
- assert_raise_tinytds_error(action) do |e|
775
- _(e.message).must_match %r{Unclosed quotation mark}i
776
- _(e.severity).must_equal 15
777
- _(e.db_error_number).must_equal 105
778
- end
779
- assert_followup_query
780
- end
781
- end
782
-
783
- it 'errors gracefully with incorrect syntax in sp_executesql' do
784
- action = lambda { @client.execute("EXEC sp_executesql N'this will not work'").each }
785
- assert_raise_tinytds_error(action) do |e|
786
- assert_match %r|incorrect syntax|i, e.message
787
- assert_equal 15, e.severity
788
- assert_equal 156, e.db_error_number
789
- end
790
- assert_followup_query
791
- end unless sybase_ase?
792
-
793
702
  end
794
-
795
703
  end
796
704
 
797
-
798
705
  protected
799
706
 
800
707
  def assert_followup_query