sequel 3.21.0 → 3.31.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 (225) hide show
  1. data/CHANGELOG +485 -3
  2. data/README.rdoc +20 -6
  3. data/Rakefile +37 -19
  4. data/bin/sequel +1 -5
  5. data/doc/association_basics.rdoc +249 -43
  6. data/doc/dataset_basics.rdoc +4 -4
  7. data/doc/dataset_filtering.rdoc +8 -0
  8. data/doc/mass_assignment.rdoc +54 -0
  9. data/doc/migration.rdoc +15 -538
  10. data/doc/model_hooks.rdoc +72 -27
  11. data/doc/opening_databases.rdoc +89 -50
  12. data/doc/prepared_statements.rdoc +40 -13
  13. data/doc/reflection.rdoc +8 -2
  14. data/doc/release_notes/3.22.0.txt +39 -0
  15. data/doc/release_notes/3.23.0.txt +172 -0
  16. data/doc/release_notes/3.24.0.txt +420 -0
  17. data/doc/release_notes/3.25.0.txt +88 -0
  18. data/doc/release_notes/3.26.0.txt +88 -0
  19. data/doc/release_notes/3.27.0.txt +82 -0
  20. data/doc/release_notes/3.28.0.txt +304 -0
  21. data/doc/release_notes/3.29.0.txt +459 -0
  22. data/doc/release_notes/3.30.0.txt +135 -0
  23. data/doc/release_notes/3.31.0.txt +146 -0
  24. data/doc/schema_modification.rdoc +547 -0
  25. data/doc/sharding.rdoc +7 -1
  26. data/doc/testing.rdoc +129 -0
  27. data/doc/transactions.rdoc +137 -0
  28. data/doc/virtual_rows.rdoc +2 -2
  29. data/lib/sequel/adapters/ado/mssql.rb +18 -6
  30. data/lib/sequel/adapters/ado.rb +40 -18
  31. data/lib/sequel/adapters/amalgalite.rb +17 -9
  32. data/lib/sequel/adapters/db2.rb +175 -86
  33. data/lib/sequel/adapters/dbi.rb +15 -15
  34. data/lib/sequel/adapters/do/mysql.rb +5 -7
  35. data/lib/sequel/adapters/do/postgres.rb +0 -5
  36. data/lib/sequel/adapters/do/sqlite.rb +0 -5
  37. data/lib/sequel/adapters/do.rb +17 -36
  38. data/lib/sequel/adapters/firebird.rb +27 -208
  39. data/lib/sequel/adapters/ibmdb.rb +448 -0
  40. data/lib/sequel/adapters/informix.rb +6 -23
  41. data/lib/sequel/adapters/jdbc/as400.rb +16 -34
  42. data/lib/sequel/adapters/jdbc/db2.rb +45 -0
  43. data/lib/sequel/adapters/jdbc/derby.rb +247 -0
  44. data/lib/sequel/adapters/jdbc/firebird.rb +29 -0
  45. data/lib/sequel/adapters/jdbc/h2.rb +56 -29
  46. data/lib/sequel/adapters/jdbc/hsqldb.rb +170 -0
  47. data/lib/sequel/adapters/jdbc/informix.rb +26 -0
  48. data/lib/sequel/adapters/jdbc/jtds.rb +34 -0
  49. data/lib/sequel/adapters/jdbc/mssql.rb +3 -33
  50. data/lib/sequel/adapters/jdbc/mysql.rb +11 -11
  51. data/lib/sequel/adapters/jdbc/oracle.rb +81 -25
  52. data/lib/sequel/adapters/jdbc/postgresql.rb +9 -13
  53. data/lib/sequel/adapters/jdbc/sqlite.rb +2 -6
  54. data/lib/sequel/adapters/jdbc/sqlserver.rb +71 -0
  55. data/lib/sequel/adapters/jdbc/transactions.rb +83 -0
  56. data/lib/sequel/adapters/jdbc.rb +231 -78
  57. data/lib/sequel/adapters/mock.rb +335 -0
  58. data/lib/sequel/adapters/mysql.rb +82 -184
  59. data/lib/sequel/adapters/mysql2.rb +26 -25
  60. data/lib/sequel/adapters/odbc/db2.rb +17 -0
  61. data/lib/sequel/adapters/odbc/mssql.rb +1 -6
  62. data/lib/sequel/adapters/odbc.rb +28 -9
  63. data/lib/sequel/adapters/openbase.rb +3 -5
  64. data/lib/sequel/adapters/oracle.rb +351 -53
  65. data/lib/sequel/adapters/postgres.rb +194 -33
  66. data/lib/sequel/adapters/shared/access.rb +32 -9
  67. data/lib/sequel/adapters/shared/db2.rb +321 -0
  68. data/lib/sequel/adapters/shared/firebird.rb +221 -0
  69. data/lib/sequel/adapters/shared/informix.rb +53 -0
  70. data/lib/sequel/adapters/shared/mssql.rb +231 -106
  71. data/lib/sequel/adapters/shared/mysql.rb +181 -63
  72. data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +149 -0
  73. data/lib/sequel/adapters/shared/oracle.rb +231 -41
  74. data/lib/sequel/adapters/shared/postgres.rb +214 -82
  75. data/lib/sequel/adapters/shared/progress.rb +4 -7
  76. data/lib/sequel/adapters/shared/sqlite.rb +201 -57
  77. data/lib/sequel/adapters/sqlite.rb +29 -21
  78. data/lib/sequel/adapters/swift/mysql.rb +12 -7
  79. data/lib/sequel/adapters/swift/postgres.rb +0 -5
  80. data/lib/sequel/adapters/swift/sqlite.rb +8 -6
  81. data/lib/sequel/adapters/swift.rb +5 -5
  82. data/lib/sequel/adapters/tinytds.rb +160 -19
  83. data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +66 -0
  84. data/lib/sequel/adapters/utils/stored_procedures.rb +1 -11
  85. data/lib/sequel/ast_transformer.rb +190 -0
  86. data/lib/sequel/connection_pool/threaded.rb +3 -2
  87. data/lib/sequel/connection_pool.rb +1 -1
  88. data/lib/sequel/core.rb +46 -5
  89. data/lib/sequel/database/connecting.rb +5 -6
  90. data/lib/sequel/database/dataset.rb +4 -4
  91. data/lib/sequel/database/dataset_defaults.rb +59 -1
  92. data/lib/sequel/database/logging.rb +1 -1
  93. data/lib/sequel/database/misc.rb +104 -19
  94. data/lib/sequel/database/query.rb +153 -58
  95. data/lib/sequel/database/schema_generator.rb +17 -7
  96. data/lib/sequel/database/schema_methods.rb +59 -29
  97. data/lib/sequel/dataset/actions.rb +231 -76
  98. data/lib/sequel/dataset/features.rb +91 -8
  99. data/lib/sequel/dataset/graph.rb +38 -11
  100. data/lib/sequel/dataset/misc.rb +50 -23
  101. data/lib/sequel/dataset/mutation.rb +5 -6
  102. data/lib/sequel/dataset/prepared_statements.rb +48 -27
  103. data/lib/sequel/dataset/query.rb +236 -43
  104. data/lib/sequel/dataset/sql.rb +665 -253
  105. data/lib/sequel/dataset.rb +8 -0
  106. data/lib/sequel/exceptions.rb +4 -0
  107. data/lib/sequel/extensions/columns_introspection.rb +61 -0
  108. data/lib/sequel/extensions/migration.rb +6 -4
  109. data/lib/sequel/extensions/named_timezones.rb +5 -0
  110. data/lib/sequel/extensions/thread_local_timezones.rb +1 -1
  111. data/lib/sequel/extensions/to_dot.rb +95 -83
  112. data/lib/sequel/model/associations.rb +1020 -337
  113. data/lib/sequel/model/base.rb +414 -132
  114. data/lib/sequel/model/errors.rb +1 -1
  115. data/lib/sequel/model/exceptions.rb +5 -1
  116. data/lib/sequel/model.rb +15 -8
  117. data/lib/sequel/plugins/association_pks.rb +22 -4
  118. data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
  119. data/lib/sequel/plugins/dataset_associations.rb +100 -0
  120. data/lib/sequel/plugins/defaults_setter.rb +58 -0
  121. data/lib/sequel/plugins/force_encoding.rb +6 -6
  122. data/lib/sequel/plugins/identity_map.rb +114 -7
  123. data/lib/sequel/plugins/many_through_many.rb +65 -7
  124. data/lib/sequel/plugins/prepared_statements.rb +151 -0
  125. data/lib/sequel/plugins/prepared_statements_associations.rb +84 -0
  126. data/lib/sequel/plugins/prepared_statements_safe.rb +82 -0
  127. data/lib/sequel/plugins/prepared_statements_with_pk.rb +59 -0
  128. data/lib/sequel/plugins/rcte_tree.rb +29 -15
  129. data/lib/sequel/plugins/serialization.rb +88 -44
  130. data/lib/sequel/plugins/serialization_modification_detection.rb +51 -0
  131. data/lib/sequel/plugins/sharding.rb +21 -54
  132. data/lib/sequel/plugins/single_table_inheritance.rb +3 -1
  133. data/lib/sequel/plugins/typecast_on_load.rb +9 -12
  134. data/lib/sequel/plugins/update_primary_key.rb +2 -2
  135. data/lib/sequel/plugins/xml_serializer.rb +3 -3
  136. data/lib/sequel/sql.rb +109 -52
  137. data/lib/sequel/timezones.rb +57 -38
  138. data/lib/sequel/version.rb +1 -1
  139. data/spec/adapters/db2_spec.rb +146 -0
  140. data/spec/adapters/mssql_spec.rb +111 -29
  141. data/spec/adapters/mysql_spec.rb +135 -123
  142. data/spec/adapters/oracle_spec.rb +49 -77
  143. data/spec/adapters/postgres_spec.rb +267 -78
  144. data/spec/adapters/spec_helper.rb +6 -5
  145. data/spec/adapters/sqlite_spec.rb +35 -21
  146. data/spec/core/connection_pool_spec.rb +71 -92
  147. data/spec/core/core_sql_spec.rb +21 -30
  148. data/spec/core/database_spec.rb +788 -512
  149. data/spec/core/dataset_spec.rb +1073 -1053
  150. data/spec/core/expression_filters_spec.rb +159 -42
  151. data/spec/core/mock_adapter_spec.rb +419 -0
  152. data/spec/core/object_graph_spec.rb +86 -114
  153. data/spec/core/schema_generator_spec.rb +3 -3
  154. data/spec/core/schema_spec.rb +298 -38
  155. data/spec/core/spec_helper.rb +6 -48
  156. data/spec/extensions/association_autoreloading_spec.rb +1 -10
  157. data/spec/extensions/association_dependencies_spec.rb +2 -12
  158. data/spec/extensions/association_pks_spec.rb +66 -32
  159. data/spec/extensions/caching_spec.rb +23 -50
  160. data/spec/extensions/class_table_inheritance_spec.rb +31 -83
  161. data/spec/extensions/columns_introspection_spec.rb +91 -0
  162. data/spec/extensions/composition_spec.rb +18 -13
  163. data/spec/extensions/dataset_associations_spec.rb +199 -0
  164. data/spec/extensions/defaults_setter_spec.rb +64 -0
  165. data/spec/extensions/hook_class_methods_spec.rb +65 -91
  166. data/spec/extensions/identity_map_spec.rb +114 -22
  167. data/spec/extensions/instance_filters_spec.rb +11 -21
  168. data/spec/extensions/instance_hooks_spec.rb +53 -0
  169. data/spec/extensions/json_serializer_spec.rb +4 -5
  170. data/spec/extensions/lazy_attributes_spec.rb +16 -20
  171. data/spec/extensions/list_spec.rb +17 -39
  172. data/spec/extensions/many_through_many_spec.rb +283 -250
  173. data/spec/extensions/migration_spec.rb +35 -32
  174. data/spec/extensions/named_timezones_spec.rb +23 -3
  175. data/spec/extensions/nested_attributes_spec.rb +97 -88
  176. data/spec/extensions/optimistic_locking_spec.rb +9 -20
  177. data/spec/extensions/prepared_statements_associations_spec.rb +111 -0
  178. data/spec/extensions/prepared_statements_safe_spec.rb +61 -0
  179. data/spec/extensions/prepared_statements_spec.rb +53 -0
  180. data/spec/extensions/prepared_statements_with_pk_spec.rb +31 -0
  181. data/spec/extensions/pretty_table_spec.rb +1 -6
  182. data/spec/extensions/rcte_tree_spec.rb +41 -43
  183. data/spec/extensions/schema_dumper_spec.rb +5 -8
  184. data/spec/extensions/schema_spec.rb +13 -21
  185. data/spec/extensions/serialization_modification_detection_spec.rb +37 -0
  186. data/spec/extensions/serialization_spec.rb +72 -43
  187. data/spec/extensions/sharding_spec.rb +66 -140
  188. data/spec/extensions/single_table_inheritance_spec.rb +18 -29
  189. data/spec/extensions/spec_helper.rb +13 -61
  190. data/spec/extensions/sql_expr_spec.rb +20 -60
  191. data/spec/extensions/tactical_eager_loading_spec.rb +9 -19
  192. data/spec/extensions/thread_local_timezones_spec.rb +22 -2
  193. data/spec/extensions/timestamps_spec.rb +6 -6
  194. data/spec/extensions/to_dot_spec.rb +4 -7
  195. data/spec/extensions/touch_spec.rb +13 -14
  196. data/spec/extensions/tree_spec.rb +11 -26
  197. data/spec/extensions/typecast_on_load_spec.rb +1 -6
  198. data/spec/extensions/update_primary_key_spec.rb +30 -24
  199. data/spec/extensions/validation_class_methods_spec.rb +30 -51
  200. data/spec/extensions/validation_helpers_spec.rb +16 -35
  201. data/spec/extensions/xml_serializer_spec.rb +16 -4
  202. data/spec/integration/associations_test.rb +537 -21
  203. data/spec/integration/database_test.rb +4 -2
  204. data/spec/integration/dataset_test.rb +461 -65
  205. data/spec/integration/eager_loader_test.rb +19 -21
  206. data/spec/integration/model_test.rb +80 -1
  207. data/spec/integration/plugin_test.rb +304 -116
  208. data/spec/integration/prepared_statement_test.rb +212 -122
  209. data/spec/integration/schema_test.rb +161 -30
  210. data/spec/integration/spec_helper.rb +39 -30
  211. data/spec/integration/timezone_test.rb +38 -12
  212. data/spec/integration/transaction_test.rb +172 -5
  213. data/spec/integration/type_test.rb +17 -3
  214. data/spec/model/association_reflection_spec.rb +201 -7
  215. data/spec/model/associations_spec.rb +865 -662
  216. data/spec/model/base_spec.rb +275 -95
  217. data/spec/model/dataset_methods_spec.rb +7 -27
  218. data/spec/model/eager_loading_spec.rb +677 -676
  219. data/spec/model/hooks_spec.rb +309 -67
  220. data/spec/model/model_spec.rb +222 -168
  221. data/spec/model/plugins_spec.rb +24 -13
  222. data/spec/model/record_spec.rb +381 -218
  223. data/spec/model/spec_helper.rb +13 -71
  224. data/spec/model/validations_spec.rb +11 -0
  225. metadata +115 -73
@@ -2,7 +2,7 @@ require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper')
2
2
 
3
3
  describe "DB#create_table" do
4
4
  before do
5
- @db = SchemaDummyDatabase.new
5
+ @db = Sequel.mock
6
6
  end
7
7
 
8
8
  specify "should accept the table name" do
@@ -88,13 +88,11 @@ describe "DB#create_table" do
88
88
  end
89
89
  @db.sqls.should == ['CREATE TABLE cats (id integer PRIMARY KEY AUTOINCREMENT)']
90
90
 
91
- @db.sqls.clear
92
91
  @db.create_table(:cats) do
93
92
  primary_key :id, :serial, :auto_increment => false
94
93
  end
95
94
  @db.sqls.should == ['CREATE TABLE cats (id serial PRIMARY KEY)']
96
95
 
97
- @db.sqls.clear
98
96
  @db.create_table(:cats) do
99
97
  primary_key :id, :type => :serial, :auto_increment => false
100
98
  end
@@ -154,7 +152,6 @@ describe "DB#create_table" do
154
152
  varchar :name
155
153
  end
156
154
  @db.sqls.should == ["CREATE TABLE cats (name varchar(255))"]
157
- @db.sqls.clear
158
155
  @db.create_table(:cats) do
159
156
  varchar :name, :size => 51
160
157
  end
@@ -199,7 +196,6 @@ describe "DB#create_table" do
199
196
  end
200
197
  @db.sqls.should == ["CREATE TABLE cats (project_id integer REFERENCES projects(id))"]
201
198
 
202
- @db.sqls.clear
203
199
  @db.create_table(:cats) do
204
200
  foreign_key :project_id, :table => :projects, :key => :zzz
205
201
  end
@@ -212,32 +208,25 @@ describe "DB#create_table" do
212
208
  end
213
209
  @db.sqls.should == ["CREATE TABLE cats (project_id integer REFERENCES projects ON DELETE RESTRICT)"]
214
210
 
215
- @db.sqls.clear
216
211
  @db.create_table(:cats) do
217
212
  foreign_key :project_id, :table => :projects, :on_delete => :cascade
218
213
  end
219
214
  @db.sqls.should == ["CREATE TABLE cats (project_id integer REFERENCES projects ON DELETE CASCADE)"]
220
215
 
221
- @db.sqls.clear
222
216
  @db.create_table(:cats) do
223
217
  foreign_key :project_id, :table => :projects, :on_delete => :no_action
224
218
  end
225
219
  @db.sqls.should == ["CREATE TABLE cats (project_id integer REFERENCES projects ON DELETE NO ACTION)"]
226
- @db.sqls.clear
227
220
 
228
- @db.sqls.clear
229
221
  @db.create_table(:cats) do
230
222
  foreign_key :project_id, :table => :projects, :on_delete => :set_null
231
223
  end
232
224
  @db.sqls.should == ["CREATE TABLE cats (project_id integer REFERENCES projects ON DELETE SET NULL)"]
233
- @db.sqls.clear
234
225
 
235
- @db.sqls.clear
236
226
  @db.create_table(:cats) do
237
227
  foreign_key :project_id, :table => :projects, :on_delete => :set_default
238
228
  end
239
229
  @db.sqls.should == ["CREATE TABLE cats (project_id integer REFERENCES projects ON DELETE SET DEFAULT)"]
240
- @db.sqls.clear
241
230
  end
242
231
 
243
232
  specify "should accept foreign keys with ON UPDATE clause" do
@@ -246,32 +235,25 @@ describe "DB#create_table" do
246
235
  end
247
236
  @db.sqls.should == ["CREATE TABLE cats (project_id integer REFERENCES projects ON UPDATE RESTRICT)"]
248
237
 
249
- @db.sqls.clear
250
238
  @db.create_table(:cats) do
251
239
  foreign_key :project_id, :table => :projects, :on_update => :cascade
252
240
  end
253
241
  @db.sqls.should == ["CREATE TABLE cats (project_id integer REFERENCES projects ON UPDATE CASCADE)"]
254
242
 
255
- @db.sqls.clear
256
243
  @db.create_table(:cats) do
257
244
  foreign_key :project_id, :table => :projects, :on_update => :no_action
258
245
  end
259
246
  @db.sqls.should == ["CREATE TABLE cats (project_id integer REFERENCES projects ON UPDATE NO ACTION)"]
260
- @db.sqls.clear
261
247
 
262
- @db.sqls.clear
263
248
  @db.create_table(:cats) do
264
249
  foreign_key :project_id, :table => :projects, :on_update => :set_null
265
250
  end
266
251
  @db.sqls.should == ["CREATE TABLE cats (project_id integer REFERENCES projects ON UPDATE SET NULL)"]
267
- @db.sqls.clear
268
252
 
269
- @db.sqls.clear
270
253
  @db.create_table(:cats) do
271
254
  foreign_key :project_id, :table => :projects, :on_update => :set_default
272
255
  end
273
256
  @db.sqls.should == ["CREATE TABLE cats (project_id integer REFERENCES projects ON UPDATE SET DEFAULT)"]
274
- @db.sqls.clear
275
257
  end
276
258
 
277
259
  specify "should accept foreign keys with deferrable option" do
@@ -281,6 +263,13 @@ describe "DB#create_table" do
281
263
  @db.sqls.should == ["CREATE TABLE cats (project_id integer REFERENCES projects DEFERRABLE INITIALLY DEFERRED)"]
282
264
  end
283
265
 
266
+ specify "should accept collation" do
267
+ @db.create_table(:cats) do
268
+ varchar :name, :collate => :utf8_bin
269
+ end
270
+ @db.sqls.should == ["CREATE TABLE cats (name varchar(255) COLLATE utf8_bin)"]
271
+ end
272
+
284
273
  specify "should accept inline index definition" do
285
274
  @db.create_table(:cats) do
286
275
  integer :id, :index => true
@@ -361,7 +350,6 @@ describe "DB#create_table" do
361
350
  @db.meta_def(:execute_ddl){|*a| raise Sequel::DatabaseError if /blah/.match(a.first); super(*a)}
362
351
  lambda{@db.create_table(:cats){Integer :id; index :blah; index :id}}.should raise_error(Sequel::DatabaseError)
363
352
  @db.sqls.should == ['CREATE TABLE cats (id integer)']
364
- @db.sqls.clear
365
353
  lambda{@db.create_table(:cats, :ignore_index_errors=>true){Integer :id; index :blah; index :id}}.should_not raise_error(Sequel::DatabaseError)
366
354
  @db.sqls.should == ['CREATE TABLE cats (id integer)', 'CREATE INDEX cats_id_index ON cats (id)']
367
355
  end
@@ -499,7 +487,6 @@ describe "DB#create_table" do
499
487
  foreign_key [:a, :b], :abc, :key => [:real_a, :real_b]
500
488
  end
501
489
  @db.sqls.should == ["CREATE TABLE cats (a integer, b integer, FOREIGN KEY (a, b) REFERENCES abc(real_a, real_b))"]
502
- @db.sqls.clear
503
490
 
504
491
  @db.create_table(:cats) do
505
492
  integer :a
@@ -517,7 +504,6 @@ describe "DB#create_table" do
517
504
  end
518
505
  @db.sqls.should == ["CREATE TABLE cats (a integer, b integer, FOREIGN KEY (a, b) REFERENCES abc ON DELETE CASCADE)"]
519
506
 
520
- @db.sqls.clear
521
507
  @db.create_table(:cats) do
522
508
  integer :a
523
509
  integer :b
@@ -525,7 +511,6 @@ describe "DB#create_table" do
525
511
  end
526
512
  @db.sqls.should == ["CREATE TABLE cats (a integer, b integer, FOREIGN KEY (a, b) REFERENCES abc ON UPDATE NO ACTION)"]
527
513
 
528
- @db.sqls.clear
529
514
  @db.create_table(:cats) do
530
515
  integer :a
531
516
  integer :b
@@ -533,7 +518,6 @@ describe "DB#create_table" do
533
518
  end
534
519
  @db.sqls.should == ["CREATE TABLE cats (a integer, b integer, FOREIGN KEY (a, b) REFERENCES abc ON DELETE RESTRICT ON UPDATE SET DEFAULT)"]
535
520
 
536
- @db.sqls.clear
537
521
  @db.create_table(:cats) do
538
522
  integer :a
539
523
  integer :b
@@ -545,24 +529,31 @@ end
545
529
 
546
530
  describe "DB#create_table!" do
547
531
  before do
548
- @db = SchemaDummyDatabase.new
532
+ @db = Sequel.mock
549
533
  end
550
534
 
551
- specify "should drop the table and then create it" do
552
- @db.create_table!(:cats) {}
535
+ specify "should create the table if it does not exist" do
536
+ @db.meta_def(:table_exists?){|a| false}
537
+ @db.create_table!(:cats){|*a|}
538
+ @db.sqls.should == ['CREATE TABLE cats ()']
539
+ end
540
+
541
+ specify "should drop the table before creating it if it already exists" do
542
+ @db.meta_def(:table_exists?){|a| true}
543
+ @db.create_table!(:cats){|*a|}
553
544
  @db.sqls.should == ['DROP TABLE cats', 'CREATE TABLE cats ()']
554
545
  end
555
546
  end
556
547
 
557
548
  describe "DB#create_table?" do
558
549
  before do
559
- @db = SchemaDummyDatabase.new
550
+ @db = Sequel.mock
560
551
  end
561
552
 
562
553
  specify "should not create the table if the table already exists" do
563
554
  @db.meta_def(:table_exists?){|a| true}
564
555
  @db.create_table?(:cats){|*a|}
565
- @db.sqls.should == nil
556
+ @db.sqls.should == []
566
557
  end
567
558
 
568
559
  specify "should create the table if the table doesn't already exist" do
@@ -570,22 +561,38 @@ describe "DB#create_table?" do
570
561
  @db.create_table?(:cats){|*a|}
571
562
  @db.sqls.should == ['CREATE TABLE cats ()']
572
563
  end
564
+
565
+ specify "should use IF NOT EXISTS if the database supports that" do
566
+ @db.meta_def(:supports_create_table_if_not_exists?){true}
567
+ @db.create_table?(:cats){|*a|}
568
+ @db.sqls.should == ['CREATE TABLE IF NOT EXISTS cats ()']
569
+ end
573
570
  end
574
571
 
575
572
  describe "DB#drop_table" do
576
573
  before do
577
- @db = SchemaDummyDatabase.new
574
+ @db = Sequel.mock
578
575
  end
579
576
 
580
577
  specify "should generate a DROP TABLE statement" do
581
578
  @db.drop_table :cats
582
579
  @db.sqls.should == ['DROP TABLE cats']
583
580
  end
581
+
582
+ specify "should drop multiple tables at once" do
583
+ @db.drop_table :cats, :dogs
584
+ @db.sqls.should == ['DROP TABLE cats', 'DROP TABLE dogs']
585
+ end
586
+
587
+ specify "should take an options hash and support the :cascade option" do
588
+ @db.drop_table :cats, :dogs, :cascade=>true
589
+ @db.sqls.should == ['DROP TABLE cats CASCADE', 'DROP TABLE dogs CASCADE']
590
+ end
584
591
  end
585
592
 
586
593
  describe "DB#alter_table" do
587
594
  before do
588
- @db = SchemaDummyDatabase.new
595
+ @db = Sequel.mock
589
596
  end
590
597
 
591
598
  specify "should allow adding not null constraint" do
@@ -629,7 +636,6 @@ describe "DB#alter_table" do
629
636
  end
630
637
  @db.sqls.should == ["ALTER TABLE cats ADD UNIQUE (a, b)"]
631
638
 
632
- @db.sqls.clear
633
639
  @db.alter_table(:cats) do
634
640
  add_unique_constraint [:a, :b], :name => :ab_uniq
635
641
  end
@@ -649,19 +655,16 @@ describe "DB#alter_table" do
649
655
  end
650
656
  @db.sqls.should == ["ALTER TABLE cats ADD FOREIGN KEY (node_id, prop_id) REFERENCES nodes_props"]
651
657
 
652
- @db.sqls.clear
653
658
  @db.alter_table(:cats) do
654
659
  add_foreign_key [:node_id, :prop_id], :nodes_props, :name => :cfk
655
660
  end
656
661
  @db.sqls.should == ["ALTER TABLE cats ADD CONSTRAINT cfk FOREIGN KEY (node_id, prop_id) REFERENCES nodes_props"]
657
662
 
658
- @db.sqls.clear
659
663
  @db.alter_table(:cats) do
660
664
  add_foreign_key [:node_id, :prop_id], :nodes_props, :key => [:nid, :pid]
661
665
  end
662
666
  @db.sqls.should == ["ALTER TABLE cats ADD FOREIGN KEY (node_id, prop_id) REFERENCES nodes_props(nid, pid)"]
663
667
 
664
- @db.sqls.clear
665
668
  @db.alter_table(:cats) do
666
669
  add_foreign_key [:node_id, :prop_id], :nodes_props, :on_delete => :restrict, :on_update => :cascade
667
670
  end
@@ -679,7 +682,7 @@ describe "DB#alter_table" do
679
682
  @db.meta_def(:execute_ddl){|*a| raise Sequel::DatabaseError}
680
683
  lambda{@db.add_index(:cats, :id)}.should raise_error(Sequel::DatabaseError)
681
684
  lambda{@db.add_index(:cats, :id, :ignore_errors=>true)}.should_not raise_error(Sequel::DatabaseError)
682
- @db.sqls.should == nil
685
+ @db.sqls.should == []
683
686
  end
684
687
 
685
688
  specify "should support add_primary_key" do
@@ -695,7 +698,6 @@ describe "DB#alter_table" do
695
698
  end
696
699
  @db.sqls.should == ["ALTER TABLE cats ADD PRIMARY KEY (id, type)"]
697
700
 
698
- @db.sqls.clear
699
701
  @db.alter_table(:cats) do
700
702
  add_primary_key [:id, :type], :name => :cpk
701
703
  end
@@ -709,6 +711,13 @@ describe "DB#alter_table" do
709
711
  @db.sqls.should == ["ALTER TABLE cats DROP COLUMN score"]
710
712
  end
711
713
 
714
+ specify "should support drop_column with :cascade=>true option" do
715
+ @db.alter_table(:cats) do
716
+ drop_column :score, :cascade=>true
717
+ end
718
+ @db.sqls.should == ["ALTER TABLE cats DROP COLUMN score CASCADE"]
719
+ end
720
+
712
721
  specify "should support drop_constraint" do
713
722
  @db.alter_table(:cats) do
714
723
  drop_constraint :valid_score
@@ -716,6 +725,13 @@ describe "DB#alter_table" do
716
725
  @db.sqls.should == ["ALTER TABLE cats DROP CONSTRAINT valid_score"]
717
726
  end
718
727
 
728
+ specify "should support drop_constraint with :cascade=>true option" do
729
+ @db.alter_table(:cats) do
730
+ drop_constraint :valid_score, :cascade=>true
731
+ end
732
+ @db.sqls.should == ["ALTER TABLE cats DROP CONSTRAINT valid_score CASCADE"]
733
+ end
734
+
719
735
  specify "should support drop_index" do
720
736
  @db.alter_table(:cats) do
721
737
  drop_index :name
@@ -763,6 +779,236 @@ describe "DB#alter_table" do
763
779
  end
764
780
  end
765
781
 
782
+ describe "Database#create_table" do
783
+ before do
784
+ @db = Sequel.mock
785
+ end
786
+
787
+ specify "should construct proper SQL" do
788
+ @db.create_table :test do
789
+ primary_key :id, :integer, :null => false
790
+ column :name, :text
791
+ index :name, :unique => true
792
+ end
793
+ @db.sqls.should == ['CREATE TABLE test (id integer NOT NULL PRIMARY KEY AUTOINCREMENT, name text)',
794
+ 'CREATE UNIQUE INDEX test_name_index ON test (name)']
795
+ end
796
+
797
+ specify "should create a temporary table" do
798
+ @db.create_table :test_tmp, :temp => true do
799
+ primary_key :id, :integer, :null => false
800
+ column :name, :text
801
+ index :name, :unique => true
802
+ end
803
+
804
+ @db.sqls.should == ['CREATE TEMPORARY TABLE test_tmp (id integer NOT NULL PRIMARY KEY AUTOINCREMENT, name text)',
805
+ 'CREATE UNIQUE INDEX test_tmp_name_index ON test_tmp (name)']
806
+ end
807
+
808
+ specify "should not use default schema when creating a temporary table" do
809
+ @db.default_schema = :foo
810
+ @db.create_table :test_tmp, :temp => true do
811
+ column :name, :text
812
+ end
813
+ @db.sqls.should == ['CREATE TEMPORARY TABLE test_tmp (name text)']
814
+ end
815
+ end
816
+
817
+ describe "Database#alter_table" do
818
+ before do
819
+ @db = Sequel.mock
820
+ end
821
+
822
+ specify "should construct proper SQL" do
823
+ @db.alter_table :xyz do
824
+ add_column :aaa, :text, :null => false, :unique => true
825
+ drop_column :bbb
826
+ rename_column :ccc, :ddd
827
+ set_column_type :eee, :integer
828
+ set_column_default :hhh, 'abcd'
829
+ add_index :fff, :unique => true
830
+ drop_index :ggg
831
+ end
832
+
833
+ @db.sqls.should == ['ALTER TABLE xyz ADD COLUMN aaa text NOT NULL UNIQUE',
834
+ 'ALTER TABLE xyz DROP COLUMN bbb',
835
+ 'ALTER TABLE xyz RENAME COLUMN ccc TO ddd',
836
+ 'ALTER TABLE xyz ALTER COLUMN eee TYPE integer',
837
+ "ALTER TABLE xyz ALTER COLUMN hhh SET DEFAULT 'abcd'",
838
+ 'CREATE UNIQUE INDEX xyz_fff_index ON xyz (fff)',
839
+ 'DROP INDEX xyz_ggg_index']
840
+ end
841
+ end
842
+
843
+ describe "Database#add_column" do
844
+ specify "should construct proper SQL" do
845
+ db = Sequel.mock
846
+ db.add_column :test, :name, :text, :unique => true
847
+ db.sqls.should == ['ALTER TABLE test ADD COLUMN name text UNIQUE']
848
+ end
849
+ end
850
+
851
+ describe "Database#drop_column" do
852
+ before do
853
+ @db = Sequel.mock
854
+ end
855
+
856
+ specify "should construct proper SQL" do
857
+ @db.drop_column :test, :name
858
+ @db.sqls.should == ['ALTER TABLE test DROP COLUMN name']
859
+ end
860
+
861
+ specify "should use CASCADE for :cascade=>true option" do
862
+ @db.drop_column :test, :name, :cascade=>true
863
+ @db.sqls.should == ['ALTER TABLE test DROP COLUMN name CASCADE']
864
+ end
865
+ end
866
+
867
+ describe "Database#rename_column" do
868
+ before do
869
+ @db = Sequel.mock
870
+ end
871
+
872
+ specify "should construct proper SQL" do
873
+ @db.rename_column :test, :abc, :def
874
+ @db.sqls.should == ['ALTER TABLE test RENAME COLUMN abc TO def']
875
+ end
876
+ end
877
+
878
+ describe "Database#set_column_type" do
879
+ before do
880
+ @db = Sequel.mock
881
+ end
882
+
883
+ specify "should construct proper SQL" do
884
+ @db.set_column_type :test, :name, :integer
885
+ @db.sqls.should == ['ALTER TABLE test ALTER COLUMN name TYPE integer']
886
+ end
887
+ end
888
+
889
+ describe "Database#set_column_default" do
890
+ before do
891
+ @db = Sequel.mock
892
+ end
893
+
894
+ specify "should construct proper SQL" do
895
+ @db.set_column_default :test, :name, 'zyx'
896
+ @db.sqls.should == ["ALTER TABLE test ALTER COLUMN name SET DEFAULT 'zyx'"]
897
+ end
898
+ end
899
+
900
+ describe "Database#add_index" do
901
+ before do
902
+ @db = Sequel.mock
903
+ end
904
+
905
+ specify "should construct proper SQL" do
906
+ @db.add_index :test, :name, :unique => true
907
+ @db.sqls.should == ['CREATE UNIQUE INDEX test_name_index ON test (name)']
908
+ end
909
+
910
+ specify "should accept multiple columns" do
911
+ @db.add_index :test, [:one, :two]
912
+ @db.sqls.should == ['CREATE INDEX test_one_two_index ON test (one, two)']
913
+ end
914
+ end
915
+
916
+ describe "Database#drop_index" do
917
+ before do
918
+ @db = Sequel.mock
919
+ end
920
+
921
+ specify "should construct proper SQL" do
922
+ @db.drop_index :test, :name
923
+ @db.sqls.should == ['DROP INDEX test_name_index']
924
+ end
925
+
926
+ end
927
+
928
+ describe "Database#drop_table" do
929
+ before do
930
+ @db = Sequel.mock
931
+ end
932
+
933
+ specify "should construct proper SQL" do
934
+ @db.drop_table :test
935
+ @db.sqls.should == ['DROP TABLE test']
936
+ end
937
+
938
+ specify "should accept multiple table names" do
939
+ @db.drop_table :a, :bb, :ccc
940
+ @db.sqls.should == ['DROP TABLE a', 'DROP TABLE bb', 'DROP TABLE ccc']
941
+ end
942
+ end
943
+
944
+ describe "Database#rename_table" do
945
+ before do
946
+ @db = Sequel.mock
947
+ end
948
+
949
+ specify "should construct proper SQL" do
950
+ @db.rename_table :abc, :xyz
951
+ @db.sqls.should == ['ALTER TABLE abc RENAME TO xyz']
952
+ end
953
+ end
954
+
955
+ describe "Database#create_view" do
956
+ before do
957
+ @db = Sequel.mock
958
+ end
959
+
960
+ specify "should construct proper SQL with raw SQL" do
961
+ @db.create_view :test, "SELECT * FROM xyz"
962
+ @db.sqls.should == ['CREATE VIEW test AS SELECT * FROM xyz']
963
+ @db.create_view :test.identifier, "SELECT * FROM xyz"
964
+ @db.sqls.should == ['CREATE VIEW test AS SELECT * FROM xyz']
965
+ end
966
+
967
+ specify "should construct proper SQL with dataset" do
968
+ @db.create_view :test, @db[:items].select(:a, :b).order(:c)
969
+ @db.sqls.should == ['CREATE VIEW test AS SELECT a, b FROM items ORDER BY c']
970
+ @db.create_or_replace_view :sch__test, "SELECT * FROM xyz"
971
+ @db.sqls.should == ['CREATE OR REPLACE VIEW sch.test AS SELECT * FROM xyz']
972
+ end
973
+
974
+ specify "should construct proper SQL with dataset" do
975
+ @db.create_or_replace_view :test, @db[:items].select(:a, :b).order(:c)
976
+ @db.sqls.should == ['CREATE OR REPLACE VIEW test AS SELECT a, b FROM items ORDER BY c']
977
+ @db.create_or_replace_view :test.identifier, @db[:items].select(:a, :b).order(:c)
978
+ @db.sqls.should == ['CREATE OR REPLACE VIEW test AS SELECT a, b FROM items ORDER BY c']
979
+ end
980
+ end
981
+
982
+ describe "Database#drop_view" do
983
+ before do
984
+ @db = Sequel.mock
985
+ end
986
+
987
+ specify "should construct proper SQL" do
988
+ @db.drop_view :test
989
+ @db.drop_view :test.identifier
990
+ @db.drop_view :sch__test
991
+ @db.drop_view :test.qualify(:sch)
992
+ @db.sqls.should == ['DROP VIEW test', 'DROP VIEW test', 'DROP VIEW sch.test', 'DROP VIEW sch.test']
993
+ end
994
+
995
+ specify "should drop multiple views at once" do
996
+ @db.drop_view :cats, :dogs
997
+ @db.sqls.should == ['DROP VIEW cats', 'DROP VIEW dogs']
998
+ end
999
+
1000
+ specify "should take an options hash and support the :cascade option" do
1001
+ @db.drop_view :cats, :dogs, :cascade=>true
1002
+ @db.sqls.should == ['DROP VIEW cats CASCADE', 'DROP VIEW dogs CASCADE']
1003
+ end
1004
+ end
1005
+
1006
+ describe "Database#alter_table_sql" do
1007
+ specify "should raise error for an invalid op" do
1008
+ proc {Sequel.mock.send(:alter_table_sql, :mau, :op => :blah)}.should raise_error(Sequel::Error)
1009
+ end
1010
+ end
1011
+
766
1012
  describe "Schema Parser" do
767
1013
  before do
768
1014
  @sqls = []
@@ -776,6 +1022,21 @@ describe "Schema Parser" do
776
1022
  proc{@db.schema(:x)}.should raise_error(Sequel::Error)
777
1023
  end
778
1024
 
1025
+ specify "should provide options if given a table name" do
1026
+ c = nil
1027
+ @db.meta_def(:schema_parse_table) do |t, opts|
1028
+ c = [t, opts]
1029
+ [[:a, {:db_type=>t.to_s}]]
1030
+ end
1031
+ @db.schema(:x)
1032
+ c.should == ["x", {}]
1033
+ @db.schema(:s__x)
1034
+ c.should == ["x", {:schema=>"s"}]
1035
+ ds = @db[:s__y]
1036
+ @db.schema(ds)
1037
+ c.should == ["y", {:schema=>"s", :dataset=>ds}]
1038
+ end
1039
+
779
1040
  specify "should parse the schema correctly for a single table" do
780
1041
  sqls = @sqls
781
1042
  proc{@db.schema(:x)}.should raise_error(Sequel::Error)
@@ -829,7 +1090,6 @@ describe "Schema Parser" do
829
1090
  @db.schema(:"time with time zone").first.last[:type].should == :time
830
1091
  @db.schema(:"time without time zone").first.last[:type].should == :time
831
1092
  @db.schema(:boolean).first.last[:type].should == :boolean
832
- @db.schema(:bit).first.last[:type].should == :boolean
833
1093
  @db.schema(:real).first.last[:type].should == :float
834
1094
  @db.schema(:float).first.last[:type].should == :float
835
1095
  @db.schema(:double).first.last[:type].should == :float
@@ -5,53 +5,11 @@ unless Object.const_defined?('Sequel')
5
5
  require 'sequel/core'
6
6
  end
7
7
 
8
- class MockDataset < Sequel::Dataset
9
- def insert(*args)
10
- @db.execute insert_sql(*args)
11
- end
12
-
13
- def update(*args)
14
- @db.execute update_sql(*args)
15
- end
16
-
17
- def fetch_rows(sql)
18
- @db.execute(sql)
19
- yield({:id => 1, :x => 1})
20
- end
21
-
22
- def quoted_identifier(c)
23
- "\"#{c}\""
24
- end
25
- end
26
-
27
- class MockDatabase < Sequel::Database
28
- set_adapter_scheme :mock
29
- @@quote_identifiers = false
30
- self.identifier_input_method = nil
31
- self.identifier_output_method = nil
32
- attr_reader :sqls
33
-
34
- def execute(sql, opts={})
35
- @sqls ||= []
36
- @sqls << sql
37
- end
38
-
39
- def reset
40
- @sqls = []
41
- end
42
-
43
- def transaction(opts={}); yield; end
44
-
45
- def dataset; MockDataset.new(self); end
8
+ if ENV['SEQUEL_COLUMNS_INTROSPECTION']
9
+ Sequel.extension :columns_introspection
10
+ Sequel::Dataset.introspect_all_columns
46
11
  end
47
12
 
48
- class SchemaDummyDatabase < Sequel::Database
49
- attr_reader :sqls
50
- self.identifier_input_method = nil
51
- self.identifier_output_method = nil
52
-
53
- def execute(sql, opts={})
54
- @sqls ||= []
55
- @sqls << sql
56
- end
57
- end
13
+ Sequel.quote_identifiers = false
14
+ Sequel.identifier_input_method = nil
15
+ Sequel.identifier_output_method = nil
@@ -5,11 +5,7 @@ describe "AssociationAutoreloading plugin" do
5
5
  @c = Class.new(Sequel::Model)
6
6
  @c.plugin :association_autoreloading
7
7
  @Artist = Class.new(@c).set_dataset(:artists)
8
- ds1 = @Artist.dataset
9
- def ds1.fetch_rows(s)
10
- (MODEL_DB.sqls ||= []) << s
11
- yield({:id=>2, :name=>'Ar'})
12
- end
8
+ @Artist.dataset._fetch = {:id=>2, :name=>'Ar'}
13
9
  @Album = Class.new(@c).set_dataset(:albums)
14
10
  @Artist.columns :id, :name
15
11
  @Album.columns :id, :name, :artist_id
@@ -22,7 +18,6 @@ describe "AssociationAutoreloading plugin" do
22
18
  album = @Album.load(:id => 1, :name=>'Al', :artist_id=>2)
23
19
  album.artist
24
20
  MODEL_DB.sqls.should == ['SELECT * FROM artists WHERE (artists.id = 2) LIMIT 1']
25
- MODEL_DB.reset
26
21
 
27
22
  album.artist_id = 1
28
23
  album.artist
@@ -33,7 +28,6 @@ describe "AssociationAutoreloading plugin" do
33
28
  album = @Album.load(:id => 1, :name=>'Al', :artist_id=>2)
34
29
  album.artist
35
30
  MODEL_DB.sqls.should == ['SELECT * FROM artists WHERE (artists.id = 2) LIMIT 1']
36
- MODEL_DB.reset
37
31
 
38
32
  album.artist_id = 2
39
33
  album.artist
@@ -54,7 +48,6 @@ describe "AssociationAutoreloading plugin" do
54
48
  album.artist_id = 1
55
49
  album.artist
56
50
  MODEL_DB.sqls.should == ['SELECT * FROM artists WHERE (artists.id = 1) LIMIT 1']
57
- MODEL_DB.reset
58
51
 
59
52
  album.other_artist
60
53
  MODEL_DB.sqls.should == ['SELECT * FROM artists WHERE (artists.id = 1) LIMIT 1']
@@ -69,7 +62,6 @@ describe "AssociationAutoreloading plugin" do
69
62
  album.artist_id = 1
70
63
  album.composite_artist
71
64
  MODEL_DB.sqls.should == ["SELECT * FROM artists WHERE ((artists.id = 1) AND (artists.name = 'Al')) LIMIT 1"]
72
- MODEL_DB.reset
73
65
 
74
66
  album.name = 'Al2'
75
67
  album.composite_artist
@@ -84,7 +76,6 @@ describe "AssociationAutoreloading plugin" do
84
76
  album = salbum.load(:id => 1, :name=>'Al', :artist_id=>2)
85
77
  album.artist
86
78
  MODEL_DB.sqls.should == ['SELECT * FROM artists WHERE (artists.id = 2) LIMIT 1']
87
- MODEL_DB.reset
88
79
 
89
80
  album.artist_id = 1
90
81
  album.artist