sequel 3.40.0 → 3.41.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.
Files changed (89) hide show
  1. data/CHANGELOG +40 -0
  2. data/README.rdoc +2 -2
  3. data/doc/advanced_associations.rdoc +12 -0
  4. data/doc/bin_sequel.rdoc +144 -0
  5. data/doc/migration.rdoc +1 -1
  6. data/doc/object_model.rdoc +29 -0
  7. data/doc/release_notes/3.41.0.txt +155 -0
  8. data/lib/sequel/adapters/ado.rb +4 -4
  9. data/lib/sequel/adapters/amalgalite.rb +0 -5
  10. data/lib/sequel/adapters/cubrid.rb +2 -2
  11. data/lib/sequel/adapters/db2.rb +9 -5
  12. data/lib/sequel/adapters/dbi.rb +4 -6
  13. data/lib/sequel/adapters/do.rb +4 -5
  14. data/lib/sequel/adapters/firebird.rb +8 -4
  15. data/lib/sequel/adapters/ibmdb.rb +2 -3
  16. data/lib/sequel/adapters/informix.rb +0 -6
  17. data/lib/sequel/adapters/jdbc.rb +11 -7
  18. data/lib/sequel/adapters/jdbc/db2.rb +22 -0
  19. data/lib/sequel/adapters/jdbc/derby.rb +5 -5
  20. data/lib/sequel/adapters/jdbc/h2.rb +0 -5
  21. data/lib/sequel/adapters/jdbc/jtds.rb +1 -1
  22. data/lib/sequel/adapters/jdbc/sqlserver.rb +6 -0
  23. data/lib/sequel/adapters/mock.rb +3 -3
  24. data/lib/sequel/adapters/mysql.rb +7 -7
  25. data/lib/sequel/adapters/mysql2.rb +0 -5
  26. data/lib/sequel/adapters/odbc.rb +4 -4
  27. data/lib/sequel/adapters/openbase.rb +4 -6
  28. data/lib/sequel/adapters/oracle.rb +14 -6
  29. data/lib/sequel/adapters/postgres.rb +12 -8
  30. data/lib/sequel/adapters/shared/db2.rb +5 -0
  31. data/lib/sequel/adapters/shared/firebird.rb +10 -0
  32. data/lib/sequel/adapters/shared/mssql.rb +43 -1
  33. data/lib/sequel/adapters/shared/mysql.rb +1 -0
  34. data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +1 -1
  35. data/lib/sequel/adapters/shared/postgres.rb +12 -0
  36. data/lib/sequel/adapters/shared/sqlite.rb +32 -0
  37. data/lib/sequel/adapters/sqlite.rb +9 -8
  38. data/lib/sequel/adapters/swift.rb +3 -8
  39. data/lib/sequel/adapters/tinytds.rb +5 -5
  40. data/lib/sequel/connection_pool.rb +13 -19
  41. data/lib/sequel/connection_pool/sharded_single.rb +12 -12
  42. data/lib/sequel/connection_pool/sharded_threaded.rb +37 -17
  43. data/lib/sequel/connection_pool/single.rb +6 -3
  44. data/lib/sequel/connection_pool/threaded.rb +33 -13
  45. data/lib/sequel/database/connecting.rb +28 -1
  46. data/lib/sequel/database/logging.rb +1 -1
  47. data/lib/sequel/database/misc.rb +2 -5
  48. data/lib/sequel/database/query.rb +2 -2
  49. data/lib/sequel/database/schema_generator.rb +1 -1
  50. data/lib/sequel/database/schema_methods.rb +3 -0
  51. data/lib/sequel/dataset/query.rb +8 -4
  52. data/lib/sequel/dataset/sql.rb +7 -0
  53. data/lib/sequel/extensions/arbitrary_servers.rb +1 -1
  54. data/lib/sequel/extensions/connection_validator.rb +109 -0
  55. data/lib/sequel/extensions/pg_array.rb +2 -0
  56. data/lib/sequel/extensions/pg_hstore.rb +2 -0
  57. data/lib/sequel/extensions/pg_json.rb +4 -0
  58. data/lib/sequel/extensions/pg_range.rb +1 -0
  59. data/lib/sequel/extensions/pg_row.rb +4 -0
  60. data/lib/sequel/plugins/prepared_statements.rb +2 -1
  61. data/lib/sequel/plugins/single_table_inheritance.rb +53 -10
  62. data/lib/sequel/plugins/touch.rb +18 -6
  63. data/lib/sequel/plugins/validation_class_methods.rb +1 -0
  64. data/lib/sequel/plugins/validation_helpers.rb +3 -1
  65. data/lib/sequel/sql.rb +61 -19
  66. data/lib/sequel/version.rb +1 -1
  67. data/spec/adapters/firebird_spec.rb +52 -38
  68. data/spec/adapters/mssql_spec.rb +67 -0
  69. data/spec/adapters/mysql_spec.rb +192 -116
  70. data/spec/adapters/postgres_spec.rb +133 -70
  71. data/spec/adapters/spec_helper.rb +7 -0
  72. data/spec/adapters/sqlite_spec.rb +34 -1
  73. data/spec/core/connection_pool_spec.rb +79 -75
  74. data/spec/core/database_spec.rb +9 -4
  75. data/spec/core/dataset_spec.rb +15 -0
  76. data/spec/core/expression_filters_spec.rb +40 -2
  77. data/spec/extensions/connection_validator_spec.rb +118 -0
  78. data/spec/extensions/pg_array_spec.rb +4 -0
  79. data/spec/extensions/single_table_inheritance_spec.rb +42 -0
  80. data/spec/extensions/touch_spec.rb +40 -0
  81. data/spec/extensions/validation_class_methods_spec.rb +19 -1
  82. data/spec/extensions/validation_helpers_spec.rb +17 -0
  83. data/spec/integration/database_test.rb +14 -0
  84. data/spec/integration/dataset_test.rb +3 -3
  85. data/spec/integration/plugin_test.rb +41 -12
  86. data/spec/integration/schema_test.rb +14 -0
  87. data/spec/integration/spec_helper.rb +7 -0
  88. data/spec/integration/type_test.rb +3 -0
  89. metadata +9 -3
@@ -568,3 +568,70 @@ describe "MSSQL::Database#drop_column with a schema" do
568
568
  MSSQL_DB[:test__items].columns.should == [:id]
569
569
  end
570
570
  end
571
+
572
+ describe "Database#foreign_key_list" do
573
+ before(:all) do
574
+ MSSQL_DB.create_table! :items do
575
+ primary_key :id
576
+ integer :sku
577
+ end
578
+ MSSQL_DB.create_table! :prices do
579
+ integer :item_id
580
+ datetime :valid_from
581
+ float :price
582
+ primary_key [:item_id, :valid_from]
583
+ foreign_key [:item_id], :items, :key => :id, :name => :fk_prices_items
584
+ end
585
+ MSSQL_DB.create_table! :sales do
586
+ integer :id
587
+ integer :price_item_id
588
+ datetime :price_valid_from
589
+ foreign_key [:price_item_id, :price_valid_from], :prices, :key => [:item_id, :valid_from], :name => :fk_sales_prices, :on_delete => :cascade
590
+ end
591
+ end
592
+ after(:all) do
593
+ MSSQL_DB.drop_table :sales
594
+ MSSQL_DB.drop_table :prices
595
+ MSSQL_DB.drop_table :items
596
+ end
597
+ it "should support typical foreign keys" do
598
+ MSSQL_DB.foreign_key_list(:prices).should == [{:name => :fk_prices_items,
599
+ :table => :items,
600
+ :columns => [:item_id],
601
+ :key => [:id],
602
+ :on_update => :no_action,
603
+ :on_delete => :no_action }]
604
+ end
605
+ it "should support a foreign key with multiple columns" do
606
+ MSSQL_DB.foreign_key_list(:sales).should == [{:name => :fk_sales_prices,
607
+ :table => :prices,
608
+ :columns => [:price_item_id, :price_valid_from],
609
+ :key => [:item_id, :valid_from],
610
+ :on_update => :no_action,
611
+ :on_delete => :cascade }]
612
+ end
613
+
614
+ context "with multiple schemas" do
615
+ before(:all) do
616
+ MSSQL_DB.execute_ddl "create schema vendor"
617
+ MSSQL_DB.create_table! :vendor__vendors do
618
+ primary_key :id
619
+ varchar :name
620
+ end
621
+ MSSQL_DB.create_table! :vendor__mapping do
622
+ integer :vendor_id
623
+ integer :item_id
624
+ foreign_key [:vendor_id], :vendor__vendors, :name => :fk_mapping_vendor
625
+ foreign_key [:item_id], :items, :name => :fk_mapping_item
626
+ end
627
+ end
628
+ after(:all) do
629
+ MSSQL_DB.drop_table :vendor__mapping
630
+ MSSQL_DB.drop_table :vendor__vendors
631
+ MSSQL_DB.execute_ddl "drop schema vendor"
632
+ end
633
+ it "should support mixed schema bound tables" do
634
+ MSSQL_DB.foreign_key_list(:vendor__mapping).sort_by{|h| h[:name].to_s}.should == [{:name => :fk_mapping_item, :table => :items, :columns => [:item_id], :key => [:id], :on_update => :no_action, :on_delete => :no_action }, {:name => :fk_mapping_vendor, :table => :vendor__vendors, :columns => [:vendor_id], :key => [:id], :on_update => :no_action, :on_delete => :no_action }]
635
+ end
636
+ end
637
+ end
@@ -39,22 +39,30 @@ describe "MySQL", '#create_table' do
39
39
 
40
40
  specify "should allow to specify options for MySQL" do
41
41
  @db.create_table(:dolls, :engine => 'MyISAM', :charset => 'latin2'){text :name}
42
- @db.sqls.should == ["CREATE TABLE `dolls` (`name` text) ENGINE=MyISAM DEFAULT CHARSET=latin2"]
42
+ check_sqls do
43
+ @db.sqls.should == ["CREATE TABLE `dolls` (`name` text) ENGINE=MyISAM DEFAULT CHARSET=latin2"]
44
+ end
43
45
  end
44
46
 
45
47
  specify "should create a temporary table" do
46
48
  @db.create_table(:tmp_dolls, :temp => true, :engine => 'MyISAM', :charset => 'latin2'){text :name}
47
- @db.sqls.should == ["CREATE TEMPORARY TABLE `tmp_dolls` (`name` text) ENGINE=MyISAM DEFAULT CHARSET=latin2"]
49
+ check_sqls do
50
+ @db.sqls.should == ["CREATE TEMPORARY TABLE `tmp_dolls` (`name` text) ENGINE=MyISAM DEFAULT CHARSET=latin2"]
51
+ end
48
52
  end
49
53
 
50
54
  specify "should not use a default for a String :text=>true type" do
51
55
  @db.create_table(:dolls){String :name, :text=>true, :default=>'blah'}
52
- @db.sqls.should == ["CREATE TABLE `dolls` (`name` text)"]
56
+ check_sqls do
57
+ @db.sqls.should == ["CREATE TABLE `dolls` (`name` text)"]
58
+ end
53
59
  end
54
60
 
55
61
  specify "should not use a default for a File type" do
56
62
  @db.create_table(:dolls){File :name, :default=>'blah'}
57
- @db.sqls.should == ["CREATE TABLE `dolls` (`name` blob)"]
63
+ check_sqls do
64
+ @db.sqls.should == ["CREATE TABLE `dolls` (`name` blob)"]
65
+ end
58
66
  end
59
67
 
60
68
  specify "should respect the size option for File type" do
@@ -464,17 +472,23 @@ describe "A MySQL database with table options" do
464
472
 
465
473
  specify "should allow to pass custom options (engine, charset, collate) for table creation" do
466
474
  @db.create_table(:items, @options){Integer :size; text :name}
467
- @db.sqls.should == ["CREATE TABLE `items` (`size` integer, `name` text) ENGINE=MyISAM DEFAULT CHARSET=latin1 DEFAULT COLLATE=latin1_swedish_ci"]
475
+ check_sqls do
476
+ @db.sqls.should == ["CREATE TABLE `items` (`size` integer, `name` text) ENGINE=MyISAM DEFAULT CHARSET=latin1 DEFAULT COLLATE=latin1_swedish_ci"]
477
+ end
468
478
  end
469
479
 
470
480
  specify "should use default options if specified (engine, charset, collate) for table creation" do
471
481
  @db.create_table(:items){Integer :size; text :name}
472
- @db.sqls.should == ["CREATE TABLE `items` (`size` integer, `name` text) ENGINE=InnoDB DEFAULT CHARSET=utf8 DEFAULT COLLATE=utf8_general_ci"]
482
+ check_sqls do
483
+ @db.sqls.should == ["CREATE TABLE `items` (`size` integer, `name` text) ENGINE=InnoDB DEFAULT CHARSET=utf8 DEFAULT COLLATE=utf8_general_ci"]
484
+ end
473
485
  end
474
486
 
475
487
  specify "should not use default if option has a nil value" do
476
488
  @db.create_table(:items, :engine=>nil, :charset=>nil, :collate=>nil){Integer :size; text :name}
477
- @db.sqls.should == ["CREATE TABLE `items` (`size` integer, `name` text)"]
489
+ check_sqls do
490
+ @db.sqls.should == ["CREATE TABLE `items` (`size` integer, `name` text)"]
491
+ end
478
492
  end
479
493
  end
480
494
 
@@ -490,27 +504,35 @@ describe "A MySQL database" do
490
504
 
491
505
  specify "should support defaults for boolean columns" do
492
506
  @db.create_table(:items){TrueClass :active1, :default=>true; FalseClass :active2, :default => false}
493
- @db.sqls.should == ["CREATE TABLE `items` (`active1` tinyint(1) DEFAULT 1, `active2` tinyint(1) DEFAULT 0)"]
507
+ check_sqls do
508
+ @db.sqls.should == ["CREATE TABLE `items` (`active1` tinyint(1) DEFAULT 1, `active2` tinyint(1) DEFAULT 0)"]
509
+ end
494
510
  end
495
511
 
496
512
  specify "should correctly format CREATE TABLE statements with foreign keys" do
497
513
  @db.create_table(:items){primary_key :id; foreign_key :p_id, :items, :key => :id, :null => false, :on_delete => :cascade}
498
- @db.sqls.should == ["CREATE TABLE `items` (`id` integer PRIMARY KEY AUTO_INCREMENT, `p_id` integer NOT NULL, UNIQUE (`id`), FOREIGN KEY (`p_id`) REFERENCES `items`(`id`) ON DELETE CASCADE)"]
514
+ check_sqls do
515
+ @db.sqls.should == ["CREATE TABLE `items` (`id` integer PRIMARY KEY AUTO_INCREMENT, `p_id` integer NOT NULL, UNIQUE (`id`), FOREIGN KEY (`p_id`) REFERENCES `items`(`id`) ON DELETE CASCADE)"]
516
+ end
499
517
  end
500
518
 
501
519
  specify "should correctly format ALTER TABLE statements with foreign keys" do
502
520
  @db.create_table(:items){Integer :id}
503
521
  @db.create_table(:users){primary_key :id}
504
522
  @db.alter_table(:items){add_foreign_key :p_id, :users, :key => :id, :null => false, :on_delete => :cascade}
505
- @db.sqls.should == ["CREATE TABLE `items` (`id` integer)",
506
- "CREATE TABLE `users` (`id` integer PRIMARY KEY AUTO_INCREMENT)",
507
- "ALTER TABLE `items` ADD COLUMN `p_id` integer NOT NULL, ADD FOREIGN KEY (`p_id`) REFERENCES `users`(`id`) ON DELETE CASCADE"]
523
+ check_sqls do
524
+ @db.sqls.should == ["CREATE TABLE `items` (`id` integer)",
525
+ "CREATE TABLE `users` (`id` integer PRIMARY KEY AUTO_INCREMENT)",
526
+ "ALTER TABLE `items` ADD COLUMN `p_id` integer NOT NULL, ADD FOREIGN KEY (`p_id`) REFERENCES `users`(`id`) ON DELETE CASCADE"]
527
+ end
508
528
  end
509
529
 
510
530
  specify "should have rename_column support keep existing options" do
511
531
  @db.create_table(:items){String :id, :null=>false, :default=>'blah'}
512
532
  @db.alter_table(:items){rename_column :id, :nid}
513
- @db.sqls.should == ["CREATE TABLE `items` (`id` varchar(255) NOT NULL DEFAULT 'blah')", "DESCRIBE `items`", "ALTER TABLE `items` CHANGE COLUMN `id` `nid` varchar(255) NOT NULL DEFAULT 'blah'"]
533
+ check_sqls do
534
+ @db.sqls.should == ["CREATE TABLE `items` (`id` varchar(255) NOT NULL DEFAULT 'blah')", "DESCRIBE `items`", "ALTER TABLE `items` CHANGE COLUMN `id` `nid` varchar(255) NOT NULL DEFAULT 'blah'"]
535
+ end
514
536
  @db[:items].insert
515
537
  @db[:items].all.should == [{:nid=>'blah'}]
516
538
  proc{@db[:items].insert(:nid=>nil)}.should raise_error(Sequel::DatabaseError)
@@ -519,7 +541,9 @@ describe "A MySQL database" do
519
541
  specify "should have set_column_type support keep existing options" do
520
542
  @db.create_table(:items){Integer :id, :null=>false, :default=>5}
521
543
  @db.alter_table(:items){set_column_type :id, Bignum}
522
- @db.sqls.should == ["CREATE TABLE `items` (`id` integer NOT NULL DEFAULT 5)", "DESCRIBE `items`", "ALTER TABLE `items` CHANGE COLUMN `id` `id` bigint NOT NULL DEFAULT 5"]
544
+ check_sqls do
545
+ @db.sqls.should == ["CREATE TABLE `items` (`id` integer NOT NULL DEFAULT 5)", "DESCRIBE `items`", "ALTER TABLE `items` CHANGE COLUMN `id` `id` bigint NOT NULL DEFAULT 5"]
546
+ end
523
547
  @db[:items].insert
524
548
  @db[:items].all.should == [{:id=>5}]
525
549
  proc{@db[:items].insert(:id=>nil)}.should raise_error(Sequel::DatabaseError)
@@ -531,13 +555,17 @@ describe "A MySQL database" do
531
555
  specify "should have set_column_type pass through options" do
532
556
  @db.create_table(:items){integer :id; enum :list, :elements=>%w[one]}
533
557
  @db.alter_table(:items){set_column_type :id, :int, :unsigned=>true, :size=>8; set_column_type :list, :enum, :elements=>%w[two]}
534
- @db.sqls.should == ["CREATE TABLE `items` (`id` integer, `list` enum('one'))", "DESCRIBE `items`", "ALTER TABLE `items` CHANGE COLUMN `id` `id` int(8) UNSIGNED NULL, CHANGE COLUMN `list` `list` enum('two') NULL"]
558
+ check_sqls do
559
+ @db.sqls.should == ["CREATE TABLE `items` (`id` integer, `list` enum('one'))", "DESCRIBE `items`", "ALTER TABLE `items` CHANGE COLUMN `id` `id` int(8) UNSIGNED NULL, CHANGE COLUMN `list` `list` enum('two') NULL"]
560
+ end
535
561
  end
536
562
 
537
563
  specify "should have set_column_default support keep existing options" do
538
564
  @db.create_table(:items){Integer :id, :null=>false, :default=>5}
539
565
  @db.alter_table(:items){set_column_default :id, 6}
540
- @db.sqls.should == ["CREATE TABLE `items` (`id` integer NOT NULL DEFAULT 5)", "DESCRIBE `items`", "ALTER TABLE `items` CHANGE COLUMN `id` `id` int(11) NOT NULL DEFAULT 6"]
566
+ check_sqls do
567
+ @db.sqls.should == ["CREATE TABLE `items` (`id` integer NOT NULL DEFAULT 5)", "DESCRIBE `items`", "ALTER TABLE `items` CHANGE COLUMN `id` `id` int(11) NOT NULL DEFAULT 6"]
568
+ end
541
569
  @db[:items].insert
542
570
  @db[:items].all.should == [{:id=>6}]
543
571
  proc{@db[:items].insert(:id=>nil)}.should raise_error(Sequel::DatabaseError)
@@ -546,7 +574,9 @@ describe "A MySQL database" do
546
574
  specify "should have set_column_allow_null support keep existing options" do
547
575
  @db.create_table(:items){Integer :id, :null=>false, :default=>5}
548
576
  @db.alter_table(:items){set_column_allow_null :id, true}
549
- @db.sqls.should == ["CREATE TABLE `items` (`id` integer NOT NULL DEFAULT 5)", "DESCRIBE `items`", "ALTER TABLE `items` CHANGE COLUMN `id` `id` int(11) NULL DEFAULT 5"]
577
+ check_sqls do
578
+ @db.sqls.should == ["CREATE TABLE `items` (`id` integer NOT NULL DEFAULT 5)", "DESCRIBE `items`", "ALTER TABLE `items` CHANGE COLUMN `id` `id` int(11) NULL DEFAULT 5"]
579
+ end
550
580
  @db[:items].insert
551
581
  @db[:items].all.should == [{:id=>5}]
552
582
  proc{@db[:items].insert(:id=>nil)}.should_not
@@ -683,11 +713,13 @@ describe "A MySQL database" do
683
713
 
684
714
  specify "should support fulltext indexes and full_text_search" do
685
715
  @db.create_table(:posts, :engine=>:MyISAM){text :title; text :body; full_text_index :title; full_text_index [:title, :body]}
686
- @db.sqls.should == [
687
- "CREATE TABLE `posts` (`title` text, `body` text) ENGINE=MyISAM",
688
- "CREATE FULLTEXT INDEX `posts_title_index` ON `posts` (`title`)",
689
- "CREATE FULLTEXT INDEX `posts_title_body_index` ON `posts` (`title`, `body`)"
690
- ]
716
+ check_sqls do
717
+ @db.sqls.should == [
718
+ "CREATE TABLE `posts` (`title` text, `body` text) ENGINE=MyISAM",
719
+ "CREATE FULLTEXT INDEX `posts_title_index` ON `posts` (`title`)",
720
+ "CREATE FULLTEXT INDEX `posts_title_body_index` ON `posts` (`title`, `body`)"
721
+ ]
722
+ end
691
723
 
692
724
  @db[:posts].insert(:title=>'ruby rails', :body=>'y')
693
725
  @db[:posts].insert(:title=>'sequel', :body=>'ruby')
@@ -697,10 +729,12 @@ describe "A MySQL database" do
697
729
  @db[:posts].full_text_search(:title, 'rails').all.should == [{:title=>'ruby rails', :body=>'y'}]
698
730
  @db[:posts].full_text_search([:title, :body], ['sequel', 'ruby']).all.should == [{:title=>'sequel', :body=>'ruby'}]
699
731
  @db[:posts].full_text_search(:title, '+ruby -rails', :boolean => true).all.should == [{:title=>'ruby scooby', :body=>'x'}]
700
- @db.sqls.should == [
701
- "SELECT * FROM `posts` WHERE (MATCH (`title`) AGAINST ('rails'))",
702
- "SELECT * FROM `posts` WHERE (MATCH (`title`, `body`) AGAINST ('sequel ruby'))",
703
- "SELECT * FROM `posts` WHERE (MATCH (`title`) AGAINST ('+ruby -rails' IN BOOLEAN MODE))"]
732
+ check_sqls do
733
+ @db.sqls.should == [
734
+ "SELECT * FROM `posts` WHERE (MATCH (`title`) AGAINST ('rails'))",
735
+ "SELECT * FROM `posts` WHERE (MATCH (`title`, `body`) AGAINST ('sequel ruby'))",
736
+ "SELECT * FROM `posts` WHERE (MATCH (`title`) AGAINST ('+ruby -rails' IN BOOLEAN MODE))"]
737
+ end
704
738
 
705
739
  @db[:posts].full_text_search(:title, :$n).call(:select, :n=>'rails').should == [{:title=>'ruby rails', :body=>'y'}]
706
740
  @db[:posts].full_text_search(:title, :$n).prepare(:select, :fts_select).call(:n=>'rails').should == [{:title=>'ruby rails', :body=>'y'}]
@@ -708,26 +742,32 @@ describe "A MySQL database" do
708
742
 
709
743
  specify "should support spatial indexes" do
710
744
  @db.create_table(:posts, :engine=>:MyISAM){point :geom, :null=>false; spatial_index [:geom]}
711
- @db.sqls.should == [
712
- "CREATE TABLE `posts` (`geom` point NOT NULL) ENGINE=MyISAM",
713
- "CREATE SPATIAL INDEX `posts_geom_index` ON `posts` (`geom`)"
714
- ]
745
+ check_sqls do
746
+ @db.sqls.should == [
747
+ "CREATE TABLE `posts` (`geom` point NOT NULL) ENGINE=MyISAM",
748
+ "CREATE SPATIAL INDEX `posts_geom_index` ON `posts` (`geom`)"
749
+ ]
750
+ end
715
751
  end
716
752
 
717
753
  specify "should support indexes with index type" do
718
754
  @db.create_table(:posts){Integer :id; index :id, :type => :btree}
719
- @db.sqls.should == [
720
- "CREATE TABLE `posts` (`id` integer)",
721
- "CREATE INDEX `posts_id_index` USING btree ON `posts` (`id`)"
722
- ]
755
+ check_sqls do
756
+ @db.sqls.should == [
757
+ "CREATE TABLE `posts` (`id` integer)",
758
+ "CREATE INDEX `posts_id_index` USING btree ON `posts` (`id`)"
759
+ ]
760
+ end
723
761
  end
724
762
 
725
763
  specify "should support unique indexes with index type" do
726
764
  @db.create_table(:posts){Integer :id; index :id, :type => :btree, :unique => true}
727
- @db.sqls.should == [
728
- "CREATE TABLE `posts` (`id` integer)",
729
- "CREATE UNIQUE INDEX `posts_id_index` USING btree ON `posts` (`id`)"
730
- ]
765
+ check_sqls do
766
+ @db.sqls.should == [
767
+ "CREATE TABLE `posts` (`id` integer)",
768
+ "CREATE UNIQUE INDEX `posts_id_index` USING btree ON `posts` (`id`)"
769
+ ]
770
+ end
731
771
  end
732
772
 
733
773
  specify "should not dump partial indexes" do
@@ -755,19 +795,25 @@ describe "MySQL::Dataset#insert and related methods" do
755
795
 
756
796
  specify "#insert should insert record with default values when no arguments given" do
757
797
  @d.insert
758
- MYSQL_DB.sqls.should == ["INSERT INTO `items` () VALUES ()"]
798
+ check_sqls do
799
+ MYSQL_DB.sqls.should == ["INSERT INTO `items` () VALUES ()"]
800
+ end
759
801
  @d.all.should == [{:name => nil, :value => nil}]
760
802
  end
761
803
 
762
804
  specify "#insert should insert record with default values when empty hash given" do
763
805
  @d.insert({})
764
- MYSQL_DB.sqls.should == ["INSERT INTO `items` () VALUES ()"]
806
+ check_sqls do
807
+ MYSQL_DB.sqls.should == ["INSERT INTO `items` () VALUES ()"]
808
+ end
765
809
  @d.all.should == [{:name => nil, :value => nil}]
766
810
  end
767
811
 
768
812
  specify "#insert should insert record with default values when empty array given" do
769
813
  @d.insert []
770
- MYSQL_DB.sqls.should == ["INSERT INTO `items` () VALUES ()"]
814
+ check_sqls do
815
+ MYSQL_DB.sqls.should == ["INSERT INTO `items` () VALUES ()"]
816
+ end
771
817
  @d.all.should == [{:name => nil, :value => nil}]
772
818
  end
773
819
 
@@ -778,10 +824,12 @@ describe "MySQL::Dataset#insert and related methods" do
778
824
  @d.on_duplicate_key_update(:name, :value => 6).insert(:name => 'abc', :value => 1)
779
825
  @d.on_duplicate_key_update(:name, :value => 6).insert(:name => 'def', :value => 2)
780
826
 
781
- MYSQL_DB.sqls.length.should == 3
782
- MYSQL_DB.sqls[0].should =~ /\AINSERT INTO `items` \(`(name|value)`, `(name|value)`\) VALUES \(('abc'|1), (1|'abc')\)\z/
783
- MYSQL_DB.sqls[1].should =~ /\AINSERT INTO `items` \(`(name|value)`, `(name|value)`\) VALUES \(('abc'|1), (1|'abc')\) ON DUPLICATE KEY UPDATE `name`=VALUES\(`name`\), `value`=6\z/
784
- MYSQL_DB.sqls[2].should =~ /\AINSERT INTO `items` \(`(name|value)`, `(name|value)`\) VALUES \(('def'|2), (2|'def')\) ON DUPLICATE KEY UPDATE `name`=VALUES\(`name`\), `value`=6\z/
827
+ check_sqls do
828
+ MYSQL_DB.sqls.length.should == 3
829
+ MYSQL_DB.sqls[0].should =~ /\AINSERT INTO `items` \(`(name|value)`, `(name|value)`\) VALUES \(('abc'|1), (1|'abc')\)\z/
830
+ MYSQL_DB.sqls[1].should =~ /\AINSERT INTO `items` \(`(name|value)`, `(name|value)`\) VALUES \(('abc'|1), (1|'abc')\) ON DUPLICATE KEY UPDATE `name`=VALUES\(`name`\), `value`=6\z/
831
+ MYSQL_DB.sqls[2].should =~ /\AINSERT INTO `items` \(`(name|value)`, `(name|value)`\) VALUES \(('def'|2), (2|'def')\) ON DUPLICATE KEY UPDATE `name`=VALUES\(`name`\), `value`=6\z/
832
+ end
785
833
 
786
834
  @d.all.should == [{:name => 'abc', :value => 6}, {:name => 'def', :value => 2}]
787
835
  end
@@ -789,11 +837,13 @@ describe "MySQL::Dataset#insert and related methods" do
789
837
  specify "#multi_replace should insert multiple records in a single statement" do
790
838
  @d.multi_replace([{:name => 'abc'}, {:name => 'def'}])
791
839
 
792
- MYSQL_DB.sqls.should == [
793
- SQL_BEGIN,
794
- "REPLACE INTO `items` (`name`) VALUES ('abc'), ('def')",
795
- SQL_COMMIT
796
- ]
840
+ check_sqls do
841
+ MYSQL_DB.sqls.should == [
842
+ SQL_BEGIN,
843
+ "REPLACE INTO `items` (`name`) VALUES ('abc'), ('def')",
844
+ SQL_COMMIT
845
+ ]
846
+ end
797
847
 
798
848
  @d.all.should == [
799
849
  {:name => 'abc', :value => nil}, {:name => 'def', :value => nil}
@@ -804,14 +854,16 @@ describe "MySQL::Dataset#insert and related methods" do
804
854
  @d.multi_replace([{:value => 1}, {:value => 2}, {:value => 3}, {:value => 4}],
805
855
  :commit_every => 2)
806
856
 
807
- MYSQL_DB.sqls.should == [
808
- SQL_BEGIN,
809
- "REPLACE INTO `items` (`value`) VALUES (1), (2)",
810
- SQL_COMMIT,
811
- SQL_BEGIN,
812
- "REPLACE INTO `items` (`value`) VALUES (3), (4)",
813
- SQL_COMMIT
814
- ]
857
+ check_sqls do
858
+ MYSQL_DB.sqls.should == [
859
+ SQL_BEGIN,
860
+ "REPLACE INTO `items` (`value`) VALUES (1), (2)",
861
+ SQL_COMMIT,
862
+ SQL_BEGIN,
863
+ "REPLACE INTO `items` (`value`) VALUES (3), (4)",
864
+ SQL_COMMIT
865
+ ]
866
+ end
815
867
 
816
868
  @d.all.should == [
817
869
  {:name => nil, :value => 1},
@@ -825,14 +877,16 @@ describe "MySQL::Dataset#insert and related methods" do
825
877
  @d.multi_replace([{:value => 1}, {:value => 2}, {:value => 3}, {:value => 4}],
826
878
  :slice => 2)
827
879
 
828
- MYSQL_DB.sqls.should == [
829
- SQL_BEGIN,
830
- "REPLACE INTO `items` (`value`) VALUES (1), (2)",
831
- SQL_COMMIT,
832
- SQL_BEGIN,
833
- "REPLACE INTO `items` (`value`) VALUES (3), (4)",
834
- SQL_COMMIT
835
- ]
880
+ check_sqls do
881
+ MYSQL_DB.sqls.should == [
882
+ SQL_BEGIN,
883
+ "REPLACE INTO `items` (`value`) VALUES (1), (2)",
884
+ SQL_COMMIT,
885
+ SQL_BEGIN,
886
+ "REPLACE INTO `items` (`value`) VALUES (3), (4)",
887
+ SQL_COMMIT
888
+ ]
889
+ end
836
890
 
837
891
  @d.all.should == [
838
892
  {:name => nil, :value => 1},
@@ -845,11 +899,13 @@ describe "MySQL::Dataset#insert and related methods" do
845
899
  specify "#multi_insert should insert multiple records in a single statement" do
846
900
  @d.multi_insert([{:name => 'abc'}, {:name => 'def'}])
847
901
 
848
- MYSQL_DB.sqls.should == [
849
- SQL_BEGIN,
850
- "INSERT INTO `items` (`name`) VALUES ('abc'), ('def')",
851
- SQL_COMMIT
852
- ]
902
+ check_sqls do
903
+ MYSQL_DB.sqls.should == [
904
+ SQL_BEGIN,
905
+ "INSERT INTO `items` (`name`) VALUES ('abc'), ('def')",
906
+ SQL_COMMIT
907
+ ]
908
+ end
853
909
 
854
910
  @d.all.should == [
855
911
  {:name => 'abc', :value => nil}, {:name => 'def', :value => nil}
@@ -860,14 +916,16 @@ describe "MySQL::Dataset#insert and related methods" do
860
916
  @d.multi_insert([{:value => 1}, {:value => 2}, {:value => 3}, {:value => 4}],
861
917
  :commit_every => 2)
862
918
 
863
- MYSQL_DB.sqls.should == [
864
- SQL_BEGIN,
865
- "INSERT INTO `items` (`value`) VALUES (1), (2)",
866
- SQL_COMMIT,
867
- SQL_BEGIN,
868
- "INSERT INTO `items` (`value`) VALUES (3), (4)",
869
- SQL_COMMIT
870
- ]
919
+ check_sqls do
920
+ MYSQL_DB.sqls.should == [
921
+ SQL_BEGIN,
922
+ "INSERT INTO `items` (`value`) VALUES (1), (2)",
923
+ SQL_COMMIT,
924
+ SQL_BEGIN,
925
+ "INSERT INTO `items` (`value`) VALUES (3), (4)",
926
+ SQL_COMMIT
927
+ ]
928
+ end
871
929
 
872
930
  @d.all.should == [
873
931
  {:name => nil, :value => 1},
@@ -881,14 +939,16 @@ describe "MySQL::Dataset#insert and related methods" do
881
939
  @d.multi_insert([{:value => 1}, {:value => 2}, {:value => 3}, {:value => 4}],
882
940
  :slice => 2)
883
941
 
884
- MYSQL_DB.sqls.should == [
885
- SQL_BEGIN,
886
- "INSERT INTO `items` (`value`) VALUES (1), (2)",
887
- SQL_COMMIT,
888
- SQL_BEGIN,
889
- "INSERT INTO `items` (`value`) VALUES (3), (4)",
890
- SQL_COMMIT
891
- ]
942
+ check_sqls do
943
+ MYSQL_DB.sqls.should == [
944
+ SQL_BEGIN,
945
+ "INSERT INTO `items` (`value`) VALUES (1), (2)",
946
+ SQL_COMMIT,
947
+ SQL_BEGIN,
948
+ "INSERT INTO `items` (`value`) VALUES (3), (4)",
949
+ SQL_COMMIT
950
+ ]
951
+ end
892
952
 
893
953
  @d.all.should == [
894
954
  {:name => nil, :value => 1},
@@ -901,11 +961,13 @@ describe "MySQL::Dataset#insert and related methods" do
901
961
  specify "#import should support inserting using columns and values arrays" do
902
962
  @d.import([:name, :value], [['abc', 1], ['def', 2]])
903
963
 
904
- MYSQL_DB.sqls.should == [
905
- SQL_BEGIN,
906
- "INSERT INTO `items` (`name`, `value`) VALUES ('abc', 1), ('def', 2)",
907
- SQL_COMMIT
908
- ]
964
+ check_sqls do
965
+ MYSQL_DB.sqls.should == [
966
+ SQL_BEGIN,
967
+ "INSERT INTO `items` (`name`, `value`) VALUES ('abc', 1), ('def', 2)",
968
+ SQL_COMMIT
969
+ ]
970
+ end
909
971
 
910
972
  @d.all.should == [
911
973
  {:name => 'abc', :value => 1},
@@ -916,11 +978,13 @@ describe "MySQL::Dataset#insert and related methods" do
916
978
  specify "#insert_ignore should add the IGNORE keyword when inserting" do
917
979
  @d.insert_ignore.multi_insert([{:name => 'abc'}, {:name => 'def'}])
918
980
 
919
- MYSQL_DB.sqls.should == [
920
- SQL_BEGIN,
921
- "INSERT IGNORE INTO `items` (`name`) VALUES ('abc'), ('def')",
922
- SQL_COMMIT
923
- ]
981
+ check_sqls do
982
+ MYSQL_DB.sqls.should == [
983
+ SQL_BEGIN,
984
+ "INSERT IGNORE INTO `items` (`name`) VALUES ('abc'), ('def')",
985
+ SQL_COMMIT
986
+ ]
987
+ end
924
988
 
925
989
  @d.all.should == [
926
990
  {:name => 'abc', :value => nil}, {:name => 'def', :value => nil}
@@ -929,19 +993,23 @@ describe "MySQL::Dataset#insert and related methods" do
929
993
 
930
994
  specify "#insert_ignore should add the IGNORE keyword for single inserts" do
931
995
  @d.insert_ignore.insert(:name => 'ghi')
932
- MYSQL_DB.sqls.should == ["INSERT IGNORE INTO `items` (`name`) VALUES ('ghi')"]
996
+ check_sqls do
997
+ MYSQL_DB.sqls.should == ["INSERT IGNORE INTO `items` (`name`) VALUES ('ghi')"]
998
+ end
933
999
  @d.all.should == [{:name => 'ghi', :value => nil}]
934
1000
  end
935
1001
 
936
1002
  specify "#on_duplicate_key_update should add the ON DUPLICATE KEY UPDATE and ALL columns when no args given" do
937
1003
  @d.on_duplicate_key_update.import([:name,:value], [['abc', 1], ['def',2]])
938
1004
 
939
- MYSQL_DB.sqls.should == [
940
- "SELECT * FROM `items` LIMIT 1",
941
- SQL_BEGIN,
942
- "INSERT INTO `items` (`name`, `value`) VALUES ('abc', 1), ('def', 2) ON DUPLICATE KEY UPDATE `name`=VALUES(`name`), `value`=VALUES(`value`)",
943
- SQL_COMMIT
944
- ]
1005
+ check_sqls do
1006
+ MYSQL_DB.sqls.should == [
1007
+ "SELECT * FROM `items` LIMIT 1",
1008
+ SQL_BEGIN,
1009
+ "INSERT INTO `items` (`name`, `value`) VALUES ('abc', 1), ('def', 2) ON DUPLICATE KEY UPDATE `name`=VALUES(`name`), `value`=VALUES(`value`)",
1010
+ SQL_COMMIT
1011
+ ]
1012
+ end
945
1013
 
946
1014
  @d.all.should == [
947
1015
  {:name => 'abc', :value => 1}, {:name => 'def', :value => 2}
@@ -953,11 +1021,13 @@ describe "MySQL::Dataset#insert and related methods" do
953
1021
  [['abc', 1], ['def',2]]
954
1022
  )
955
1023
 
956
- MYSQL_DB.sqls.should == [
957
- SQL_BEGIN,
958
- "INSERT INTO `items` (`name`, `value`) VALUES ('abc', 1), ('def', 2) ON DUPLICATE KEY UPDATE `value`=VALUES(`value`)",
959
- SQL_COMMIT
960
- ]
1024
+ check_sqls do
1025
+ MYSQL_DB.sqls.should == [
1026
+ SQL_BEGIN,
1027
+ "INSERT INTO `items` (`name`, `value`) VALUES ('abc', 1), ('def', 2) ON DUPLICATE KEY UPDATE `value`=VALUES(`value`)",
1028
+ SQL_COMMIT
1029
+ ]
1030
+ end
961
1031
 
962
1032
  @d.all.should == [
963
1033
  {:name => 'abc', :value => 1}, {:name => 'def', :value => 2}
@@ -981,7 +1051,9 @@ describe "MySQL::Dataset#update and related methods" do
981
1051
  proc{@d.where(:value => 1).update(:name => 'cow')}.should raise_error(Sequel::DatabaseError)
982
1052
  MYSQL_DB.sqls.clear
983
1053
  @d.update_ignore.where(:value => 1).update(:name => 'cow')
984
- MYSQL_DB.sqls.should == ["UPDATE IGNORE `items` SET `name` = 'cow' WHERE (`value` = 1)"]
1054
+ check_sqls do
1055
+ MYSQL_DB.sqls.should == ["UPDATE IGNORE `items` SET `name` = 'cow' WHERE (`value` = 1)"]
1056
+ end
985
1057
  @d.order(:name).all.should == [{:name => 'cat', :value => 1}, {:name => 'cow', :value => 0}]
986
1058
  end
987
1059
  end
@@ -1073,13 +1145,17 @@ describe "MySQL::Dataset#calc_found_rows" do
1073
1145
  MYSQL_DB[:items].multi_insert([{:a => 1}, {:a => 1}, {:a => 2}])
1074
1146
  MYSQL_DB.sqls.clear
1075
1147
 
1076
- MYSQL_DB[:items].calc_found_rows.filter(:a => 1).limit(1).all.should == [{:a => 1}]
1077
- MYSQL_DB.dataset.select(Sequel.function(:FOUND_ROWS).as(:rows)).all.should == [{:rows => 2 }]
1148
+ MYSQL_DB.synchronize do
1149
+ MYSQL_DB[:items].calc_found_rows.filter(:a => 1).limit(1).all.should == [{:a => 1}]
1150
+ MYSQL_DB.dataset.select(Sequel.function(:FOUND_ROWS).as(:rows)).all.should == [{:rows => 2 }]
1151
+ end
1078
1152
 
1079
- MYSQL_DB.sqls.should == [
1080
- 'SELECT SQL_CALC_FOUND_ROWS * FROM `items` WHERE (`a` = 1) LIMIT 1',
1081
- 'SELECT FOUND_ROWS() AS `rows`',
1082
- ]
1153
+ check_sqls do
1154
+ MYSQL_DB.sqls.should == [
1155
+ 'SELECT SQL_CALC_FOUND_ROWS * FROM `items` WHERE (`a` = 1) LIMIT 1',
1156
+ 'SELECT FOUND_ROWS() AS `rows`',
1157
+ ]
1158
+ end
1083
1159
  end
1084
1160
  end
1085
1161