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
@@ -6,7 +6,6 @@ String.send(:include, Sequel::SQL::StringMethods)
6
6
  describe "Blockless Ruby Filters" do
7
7
  before do
8
8
  db = Sequel::Database.new
9
- db.quote_identifiers = false
10
9
  @d = db[:items]
11
10
  def @d.l(*args, &block)
12
11
  literal(filter_expr(*args, &block))
@@ -186,31 +185,26 @@ describe "Blockless Ruby Filters" do
186
185
  @d.l(~((((:x - :y)/(:x + :y))*:z) <= 100)).should == '((((x - y) / (x + y)) * z) > 100)'
187
186
  end
188
187
 
189
- it "should not allow negation of string expressions" do
190
- proc{~:x.sql_string}.should raise_error
191
- proc{~([:x, :y].sql_string_join)}.should raise_error
188
+ it "should not add ~ method to string expressions" do
189
+ proc{~:x.sql_string}.should raise_error(NoMethodError)
192
190
  end
193
191
 
194
- it "should not allow mathematical or string operations on true, false, or nil" do
195
- proc{:x + 1}.should_not raise_error
196
- proc{:x - true}.should raise_error(Sequel::Error)
197
- proc{:x / false}.should raise_error(Sequel::Error)
198
- proc{:x * nil}.should raise_error(Sequel::Error)
199
- proc{[:x, nil].sql_string_join}.should raise_error(Sequel::Error)
192
+ it "should allow mathematical or string operations on true, false, or nil" do
193
+ @d.lit(:x + 1).should == '(x + 1)'
194
+ @d.lit(:x - true).should == "(x - 't')"
195
+ @d.lit(:x / false).should == "(x / 'f')"
196
+ @d.lit(:x * nil).should == '(x * NULL)'
197
+ @d.lit([:x, nil].sql_string_join).should == '(x || NULL)'
200
198
  end
201
199
 
202
- it "should not allow mathematical or string operations on boolean complex expressions" do
203
- proc{:x + (:y + 1)}.should_not raise_error
204
- proc{:x - (~:y)}.should raise_error(Sequel::Error)
205
- proc{:x / (:y & :z)}.should raise_error(Sequel::Error)
206
- proc{:x * (:y | :z)}.should raise_error(Sequel::Error)
207
- proc{:x + :y.like('a')}.should raise_error(Sequel::Error)
208
- proc{:x - :y.like(/a/)}.should raise_error(Sequel::Error)
209
- proc{:x * :y.like(/a/i)}.should raise_error(Sequel::Error)
210
- proc{:x + ~:y.like('a')}.should raise_error(Sequel::Error)
211
- proc{:x - ~:y.like(/a/)}.should raise_error(Sequel::Error)
212
- proc{:x * ~:y.like(/a/i)}.should raise_error(Sequel::Error)
213
- proc{[:x, ~:y.like(/a/i)].sql_string_join}.should raise_error(Sequel::Error)
200
+ it "should allow mathematical or string operations on boolean complex expressions" do
201
+ @d.lit(:x + (:y + 1)).should == '(x + y + 1)'
202
+ @d.lit(:x - ~:y).should == '(x - NOT y)'
203
+ @d.lit(:x / (:y & :z)).should == '(x / (y AND z))'
204
+ @d.lit(:x * (:y | :z)).should == '(x * (y OR z))'
205
+ @d.lit(:x + :y.like('a')).should == "(x + (y LIKE 'a'))"
206
+ @d.lit(:x - ~:y.like('a')).should == "(x - (y NOT LIKE 'a'))"
207
+ @d.lit([:x, ~:y.like('a')].sql_string_join).should == "(x || (y NOT LIKE 'a'))"
214
208
  end
215
209
 
216
210
  it "should support AND conditions via &" do
@@ -382,12 +376,12 @@ describe "Blockless Ruby Filters" do
382
376
  @d.l((:x + 1) & (:x + 2) > 100).should == '(((x + 1) & (x + 2)) > 100)'
383
377
  end
384
378
 
385
- it "should raise an error if use a Bitwise method on a ComplexExpression that isn't a NumericExpression" do
386
- proc{(:x + 1) & (:x & 2)}.should raise_error(Sequel::Error)
379
+ it "should allow using a Bitwise method on a ComplexExpression that isn't a NumericExpression" do
380
+ @d.lit((:x + 1) & (:x + '2')).should == "((x + 1) & (x || '2'))"
387
381
  end
388
382
 
389
- it "should raise an error if use a Boolean method on a ComplexExpression that isn't a BooleanExpression" do
390
- proc{:x & (:x + 2)}.should raise_error(Sequel::Error)
383
+ it "should allow using a Boolean method on a ComplexExpression that isn't a BooleanExpression" do
384
+ @d.l(:x & (:x + '2')).should == "(x AND (x || '2'))"
391
385
  end
392
386
 
393
387
  it "should raise an error if attempting to invert a ComplexExpression that isn't a BooleanExpression" do
@@ -424,10 +418,94 @@ describe "Blockless Ruby Filters" do
424
418
  @d.l(~{:x => Sequel::SQLFALSE}).should == '(x IS NOT FALSE)'
425
419
  end
426
420
 
421
+ it "should support direct negation of SQL::Constants" do
422
+ @d.l({:x => ~Sequel::NULL}).should == '(x IS NOT NULL)'
423
+ @d.l({:x => ~Sequel::NOTNULL}).should == '(x IS NULL)'
424
+ @d.l({:x => ~Sequel::TRUE}).should == '(x IS FALSE)'
425
+ @d.l({:x => ~Sequel::FALSE}).should == '(x IS TRUE)'
426
+ @d.l({:x => ~Sequel::SQLTRUE}).should == '(x IS FALSE)'
427
+ @d.l({:x => ~Sequel::SQLFALSE}).should == '(x IS TRUE)'
428
+ end
429
+
430
+ it "should raise an error if trying to invert an invalid SQL::Constant" do
431
+ proc{~Sequel::CURRENT_DATE}.should raise_error(Sequel::Error)
432
+ end
433
+
427
434
  it "should raise an error if trying to create an invalid complex expression" do
428
435
  proc{Sequel::SQL::ComplexExpression.new(:BANG, 1, 2)}.should raise_error(Sequel::Error)
429
436
  end
430
437
 
438
+ it "should use a string concatentation for + if given a string" do
439
+ @d.lit(:x + '1').should == "(x || '1')"
440
+ @d.lit(:x + '1' + '1').should == "(x || '1' || '1')"
441
+ end
442
+
443
+ it "should use an addition for + if given a literal string" do
444
+ @d.lit(:x + '1'.lit).should == "(x + 1)"
445
+ @d.lit(:x + '1'.lit + '1'.lit).should == "(x + 1 + 1)"
446
+ end
447
+
448
+ it "should use a bitwise operator for & and | if given an integer" do
449
+ @d.lit(:x & 1).should == "(x & 1)"
450
+ @d.lit(:x | 1).should == "(x | 1)"
451
+ @d.lit(:x & 1 & 1).should == "(x & 1 & 1)"
452
+ @d.lit(:x | 1 | 1).should == "(x | 1 | 1)"
453
+ end
454
+
455
+ it "should allow adding a string to an integer expression" do
456
+ @d.lit(:x + 1 + 'a').should == "(x + 1 + 'a')"
457
+ end
458
+
459
+ it "should allow adding an integer to an string expression" do
460
+ @d.lit(:x + 'a' + 1).should == "(x || 'a' || 1)"
461
+ end
462
+
463
+ it "should allow adding a boolean to an integer expression" do
464
+ @d.lit(:x + 1 + true).should == "(x + 1 + 't')"
465
+ end
466
+
467
+ it "should allow adding a boolean to an string expression" do
468
+ @d.lit(:x + 'a' + true).should == "(x || 'a' || 't')"
469
+ end
470
+
471
+ it "should allow using a boolean operation with an integer on an boolean expression" do
472
+ @d.lit(:x & :a & 1).should == "(x AND a AND 1)"
473
+ end
474
+
475
+ it "should allow using a boolean operation with a string on an boolean expression" do
476
+ @d.lit(:x & :a & 'a').should == "(x AND a AND 'a')"
477
+ end
478
+
479
+ it "should allowing AND of boolean expression and literal string" do
480
+ @d.lit(:x & :a & 'a'.lit).should == "(x AND a AND a)"
481
+ end
482
+
483
+ it "should allowing + of integer expression and literal string" do
484
+ @d.lit(:x + :a + 'a'.lit).should == "(x + a + a)"
485
+ end
486
+
487
+ it "should allowing + of string expression and literal string" do
488
+ @d.lit(:x + 'a' + 'a'.lit).should == "(x || 'a' || a)"
489
+ end
490
+
491
+ it "should allow sql_{string,boolean,number} methods on numeric expressions" do
492
+ @d.lit((:x + 1).sql_string + 'a').should == "((x + 1) || 'a')"
493
+ @d.lit((:x + 1).sql_boolean & 1).should == "((x + 1) AND 1)"
494
+ @d.lit((:x + 1).sql_number + 'a').should == "(x + 1 + 'a')"
495
+ end
496
+
497
+ it "should allow sql_{string,boolean,number} methods on string expressions" do
498
+ @d.lit((:x + 'a').sql_string + 'a').should == "(x || 'a' || 'a')"
499
+ @d.lit((:x + 'a').sql_boolean & 1).should == "((x || 'a') AND 1)"
500
+ @d.lit((:x + 'a').sql_number + 'a').should == "((x || 'a') + 'a')"
501
+ end
502
+
503
+ it "should allow sql_{string,boolean,number} methods on boolean expressions" do
504
+ @d.lit((:x & :y).sql_string + 'a').should == "((x AND y) || 'a')"
505
+ @d.lit((:x & :y).sql_boolean & 1).should == "(x AND y AND 1)"
506
+ @d.lit((:x & :y).sql_number + 'a').should == "((x AND y) + 'a')"
507
+ end
508
+
431
509
  it "should raise an error if trying to literalize an invalid complex expression" do
432
510
  ce = :x + 1
433
511
  ce.instance_variable_set(:@op, :BANG)
@@ -439,26 +517,65 @@ describe "Blockless Ruby Filters" do
439
517
  e2 = ~:comment.like('%:hidden:%')
440
518
  e1.should == e2
441
519
  end
520
+
521
+ it "should support expression filter methods on Datasets" do
522
+ d = @d.select(:a)
523
+
524
+ @d.lit(d + 1).should == '((SELECT a FROM items) + 1)'
525
+ @d.lit(d - 1).should == '((SELECT a FROM items) - 1)'
526
+ @d.lit(d * 1).should == '((SELECT a FROM items) * 1)'
527
+ @d.lit(d / 1).should == '((SELECT a FROM items) / 1)'
528
+
529
+ @d.lit(d => 1).should == '((SELECT a FROM items) = 1)'
530
+ @d.lit(~{d => 1}).should == '((SELECT a FROM items) != 1)'
531
+ @d.lit(d > 1).should == '((SELECT a FROM items) > 1)'
532
+ @d.lit(d < 1).should == '((SELECT a FROM items) < 1)'
533
+ @d.lit(d >= 1).should == '((SELECT a FROM items) >= 1)'
534
+ @d.lit(d <= 1).should == '((SELECT a FROM items) <= 1)'
535
+
536
+ @d.lit(d.as(:b)).should == '(SELECT a FROM items) AS b'
537
+
538
+ @d.lit(d & :b).should == '((SELECT a FROM items) AND b)'
539
+ @d.lit(d | :b).should == '((SELECT a FROM items) OR b)'
540
+ @d.lit(~d).should == 'NOT (SELECT a FROM items)'
541
+
542
+ @d.lit(d.cast(Integer)).should == 'CAST((SELECT a FROM items) AS integer)'
543
+ @d.lit(d.cast_numeric).should == 'CAST((SELECT a FROM items) AS integer)'
544
+ @d.lit(d.cast_string).should == 'CAST((SELECT a FROM items) AS varchar(255))'
545
+ @d.lit(d.cast_numeric << :b).should == '(CAST((SELECT a FROM items) AS integer) << b)'
546
+ @d.lit(d.cast_string + :b).should == '(CAST((SELECT a FROM items) AS varchar(255)) || b)'
547
+
548
+ @d.lit(d.extract(:year)).should == 'extract(year FROM (SELECT a FROM items))'
549
+ @d.lit(d.sql_boolean & :b).should == '((SELECT a FROM items) AND b)'
550
+ @d.lit(d.sql_number << :b).should == '((SELECT a FROM items) << b)'
551
+ @d.lit(d.sql_string + :b).should == '((SELECT a FROM items) || b)'
552
+
553
+ @d.lit(d.asc).should == '(SELECT a FROM items) ASC'
554
+ @d.lit(d.desc).should == '(SELECT a FROM items) DESC'
555
+
556
+ @d.lit(d.like(:b)).should == '((SELECT a FROM items) LIKE b)'
557
+ @d.lit(d.ilike(:b)).should == '((SELECT a FROM items) ILIKE b)'
558
+ end
442
559
 
443
560
  if RUBY_VERSION < '1.9.0'
444
561
  it "should not allow inequality operations on true, false, or nil" do
445
- proc{:x > 1}.should_not raise_error
446
- proc{:x < true}.should raise_error(Sequel::Error)
447
- proc{:x >= false}.should raise_error(Sequel::Error)
448
- proc{:x <= nil}.should raise_error(Sequel::Error)
562
+ @d.lit(:x > 1).should == "(x > 1)"
563
+ @d.lit(:x < true).should == "(x < 't')"
564
+ @d.lit(:x >= false).should == "(x >= 'f')"
565
+ @d.lit(:x <= nil).should == "(x <= NULL)"
449
566
  end
450
567
 
451
568
  it "should not allow inequality operations on boolean complex expressions" do
452
- proc{:x > (:y > 5)}.should raise_error(Sequel::Error)
453
- proc{:x < (:y < 5)}.should raise_error(Sequel::Error)
454
- proc{:x >= (:y >= 5)}.should raise_error(Sequel::Error)
455
- proc{:x <= (:y <= 5)}.should raise_error(Sequel::Error)
456
- proc{:x > {:y => nil}}.should raise_error(Sequel::Error)
457
- proc{:x < ~{:y => nil}}.should raise_error(Sequel::Error)
458
- proc{:x >= {:y => 5}}.should raise_error(Sequel::Error)
459
- proc{:x <= ~{:y => 5}}.should raise_error(Sequel::Error)
460
- proc{:x >= {:y => [1,2,3]}}.should raise_error(Sequel::Error)
461
- proc{:x <= ~{:y => [1,2,3]}}.should raise_error(Sequel::Error)
569
+ @d.lit(:x > (:y > 5)).should == "(x > (y > 5))"
570
+ @d.lit(:x < (:y < 5)).should == "(x < (y < 5))"
571
+ @d.lit(:x >= (:y >= 5)).should == "(x >= (y >= 5))"
572
+ @d.lit(:x <= (:y <= 5)).should == "(x <= (y <= 5))"
573
+ @d.lit(:x > {:y => nil}).should == "(x > (y IS NULL))"
574
+ @d.lit(:x < ~{:y => nil}).should == "(x < (y IS NOT NULL))"
575
+ @d.lit(:x >= {:y => 5}).should == "(x >= (y = 5))"
576
+ @d.lit(:x <= ~{:y => 5}).should == "(x <= (y != 5))"
577
+ @d.lit(:x >= {:y => [1,2,3]}).should == "(x >= (y IN (1, 2, 3)))"
578
+ @d.lit(:x <= ~{:y => [1,2,3]}).should == "(x <= (y NOT IN (1, 2, 3)))"
462
579
  end
463
580
 
464
581
  it "should support >, <, >=, and <= via Symbol#>,<,>=,<=" do
@@ -553,7 +670,7 @@ describe Sequel::SQL::VirtualRow do
553
670
  end
554
671
 
555
672
  it "should support :frame=>:rows option for window function calls" do
556
- @d.l{rank(:over, :frame=>:rows){}}.should == 'rank() OVER (ROWS UNBOUNDED PRECEDING)'
673
+ @d.l{rank(:over, :frame=>:rows){}}.should == 'rank() OVER (ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)'
557
674
  end
558
675
 
559
676
  it "should support :frame=>'some string' option for window function calls" do
@@ -565,7 +682,7 @@ describe Sequel::SQL::VirtualRow do
565
682
  end
566
683
 
567
684
  it "should support all these options together" do
568
- @d.l{count(:over, :* =>true, :partition=>a, :order=>b, :window=>:win, :frame=>:rows){}}.should == 'count(*) OVER ("win" PARTITION BY "a" ORDER BY "b" ROWS UNBOUNDED PRECEDING)'
685
+ @d.l{count(:over, :* =>true, :partition=>a, :order=>b, :window=>:win, :frame=>:rows){}}.should == 'count(*) OVER ("win" PARTITION BY "a" ORDER BY "b" ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)'
569
686
  end
570
687
 
571
688
  it "should raise an error if window functions are not supported" do