sequel 3.21.0 → 3.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +294 -0
- data/README.rdoc +20 -6
- data/Rakefile +20 -15
- data/doc/association_basics.rdoc +210 -43
- data/doc/dataset_basics.rdoc +4 -4
- data/doc/mass_assignment.rdoc +54 -0
- data/doc/migration.rdoc +15 -538
- data/doc/model_hooks.rdoc +64 -27
- data/doc/opening_databases.rdoc +37 -10
- data/doc/prepared_statements.rdoc +16 -10
- data/doc/reflection.rdoc +8 -2
- data/doc/release_notes/3.22.0.txt +39 -0
- data/doc/release_notes/3.23.0.txt +172 -0
- data/doc/release_notes/3.24.0.txt +420 -0
- data/doc/release_notes/3.25.0.txt +88 -0
- data/doc/release_notes/3.26.0.txt +88 -0
- data/doc/release_notes/3.27.0.txt +82 -0
- data/doc/release_notes/3.28.0.txt +304 -0
- data/doc/schema_modification.rdoc +547 -0
- data/doc/testing.rdoc +106 -0
- data/doc/transactions.rdoc +97 -0
- data/doc/virtual_rows.rdoc +2 -2
- data/lib/sequel/adapters/ado.rb +12 -1
- data/lib/sequel/adapters/amalgalite.rb +4 -0
- data/lib/sequel/adapters/db2.rb +95 -58
- data/lib/sequel/adapters/do.rb +12 -0
- data/lib/sequel/adapters/firebird.rb +25 -203
- data/lib/sequel/adapters/ibmdb.rb +440 -0
- data/lib/sequel/adapters/informix.rb +4 -19
- data/lib/sequel/adapters/jdbc/as400.rb +0 -7
- data/lib/sequel/adapters/jdbc/db2.rb +49 -0
- data/lib/sequel/adapters/jdbc/firebird.rb +34 -0
- data/lib/sequel/adapters/jdbc/h2.rb +16 -5
- data/lib/sequel/adapters/jdbc/informix.rb +31 -0
- data/lib/sequel/adapters/jdbc/jtds.rb +34 -0
- data/lib/sequel/adapters/jdbc/mssql.rb +0 -32
- data/lib/sequel/adapters/jdbc/mysql.rb +9 -0
- data/lib/sequel/adapters/jdbc/oracle.rb +2 -27
- data/lib/sequel/adapters/jdbc/postgresql.rb +6 -0
- data/lib/sequel/adapters/jdbc/sqlserver.rb +46 -0
- data/lib/sequel/adapters/jdbc/transactions.rb +34 -0
- data/lib/sequel/adapters/jdbc.rb +62 -29
- data/lib/sequel/adapters/mysql.rb +22 -139
- data/lib/sequel/adapters/mysql2.rb +9 -14
- data/lib/sequel/adapters/odbc/db2.rb +21 -0
- data/lib/sequel/adapters/odbc.rb +15 -3
- data/lib/sequel/adapters/oracle.rb +17 -1
- data/lib/sequel/adapters/postgres.rb +111 -16
- data/lib/sequel/adapters/shared/access.rb +21 -0
- data/lib/sequel/adapters/shared/db2.rb +290 -0
- data/lib/sequel/adapters/shared/firebird.rb +214 -0
- data/lib/sequel/adapters/shared/informix.rb +45 -0
- data/lib/sequel/adapters/shared/mssql.rb +85 -47
- data/lib/sequel/adapters/shared/mysql.rb +50 -7
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +143 -0
- data/lib/sequel/adapters/shared/oracle.rb +0 -4
- data/lib/sequel/adapters/shared/postgres.rb +75 -43
- data/lib/sequel/adapters/shared/sqlite.rb +56 -8
- data/lib/sequel/adapters/sqlite.rb +12 -11
- data/lib/sequel/adapters/swift/mysql.rb +9 -0
- data/lib/sequel/adapters/tinytds.rb +139 -7
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +55 -0
- data/lib/sequel/ast_transformer.rb +190 -0
- data/lib/sequel/connection_pool/threaded.rb +3 -2
- data/lib/sequel/connection_pool.rb +1 -1
- data/lib/sequel/core.rb +6 -5
- data/lib/sequel/database/connecting.rb +5 -5
- data/lib/sequel/database/dataset.rb +1 -1
- data/lib/sequel/database/dataset_defaults.rb +1 -1
- data/lib/sequel/database/logging.rb +1 -1
- data/lib/sequel/database/misc.rb +38 -17
- data/lib/sequel/database/query.rb +50 -19
- data/lib/sequel/database/schema_generator.rb +8 -5
- data/lib/sequel/database/schema_methods.rb +52 -27
- data/lib/sequel/dataset/actions.rb +167 -48
- data/lib/sequel/dataset/features.rb +57 -8
- data/lib/sequel/dataset/graph.rb +1 -1
- data/lib/sequel/dataset/misc.rb +39 -20
- data/lib/sequel/dataset/mutation.rb +3 -3
- data/lib/sequel/dataset/prepared_statements.rb +29 -14
- data/lib/sequel/dataset/query.rb +182 -32
- data/lib/sequel/dataset/sql.rb +31 -58
- data/lib/sequel/dataset.rb +8 -0
- data/lib/sequel/exceptions.rb +4 -0
- data/lib/sequel/extensions/columns_introspection.rb +61 -0
- data/lib/sequel/extensions/migration.rb +6 -4
- data/lib/sequel/extensions/to_dot.rb +95 -83
- data/lib/sequel/model/associations.rb +893 -309
- data/lib/sequel/model/base.rb +302 -105
- data/lib/sequel/model/errors.rb +1 -1
- data/lib/sequel/model/exceptions.rb +5 -1
- data/lib/sequel/model.rb +13 -7
- data/lib/sequel/plugins/association_pks.rb +22 -4
- data/lib/sequel/plugins/defaults_setter.rb +58 -0
- data/lib/sequel/plugins/identity_map.rb +113 -6
- data/lib/sequel/plugins/many_through_many.rb +67 -5
- data/lib/sequel/plugins/prepared_statements.rb +140 -0
- data/lib/sequel/plugins/prepared_statements_associations.rb +84 -0
- data/lib/sequel/plugins/prepared_statements_safe.rb +82 -0
- data/lib/sequel/plugins/prepared_statements_with_pk.rb +59 -0
- data/lib/sequel/plugins/serialization_modification_detection.rb +51 -0
- data/lib/sequel/plugins/sharding.rb +12 -20
- data/lib/sequel/plugins/single_table_inheritance.rb +2 -0
- data/lib/sequel/plugins/update_primary_key.rb +1 -1
- data/lib/sequel/plugins/xml_serializer.rb +3 -3
- data/lib/sequel/sql.rb +107 -51
- data/lib/sequel/timezones.rb +12 -3
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/db2_spec.rb +146 -0
- data/spec/adapters/mssql_spec.rb +36 -0
- data/spec/adapters/mysql_spec.rb +36 -19
- data/spec/adapters/postgres_spec.rb +115 -28
- data/spec/adapters/spec_helper.rb +6 -0
- data/spec/adapters/sqlite_spec.rb +11 -0
- data/spec/core/connection_pool_spec.rb +62 -77
- data/spec/core/database_spec.rb +244 -287
- data/spec/core/dataset_spec.rb +383 -34
- data/spec/core/expression_filters_spec.rb +159 -41
- data/spec/core/schema_spec.rb +326 -3
- data/spec/core/spec_helper.rb +45 -0
- data/spec/extensions/association_pks_spec.rb +38 -0
- data/spec/extensions/columns_introspection_spec.rb +91 -0
- data/spec/extensions/defaults_setter_spec.rb +64 -0
- data/spec/extensions/identity_map_spec.rb +162 -0
- data/spec/extensions/many_through_many_spec.rb +195 -20
- data/spec/extensions/migration_spec.rb +17 -17
- data/spec/extensions/nested_attributes_spec.rb +1 -0
- data/spec/extensions/prepared_statements_associations_spec.rb +126 -0
- data/spec/extensions/prepared_statements_safe_spec.rb +79 -0
- data/spec/extensions/prepared_statements_spec.rb +72 -0
- data/spec/extensions/prepared_statements_with_pk_spec.rb +38 -0
- data/spec/extensions/schema_dumper_spec.rb +2 -2
- data/spec/extensions/schema_spec.rb +12 -20
- data/spec/extensions/serialization_modification_detection_spec.rb +36 -0
- data/spec/extensions/single_table_inheritance_spec.rb +11 -0
- data/spec/extensions/spec_helper.rb +3 -1
- data/spec/extensions/to_dot_spec.rb +3 -5
- data/spec/extensions/xml_serializer_spec.rb +16 -4
- data/spec/integration/associations_test.rb +405 -15
- data/spec/integration/database_test.rb +4 -2
- data/spec/integration/dataset_test.rb +240 -20
- data/spec/integration/plugin_test.rb +142 -5
- data/spec/integration/prepared_statement_test.rb +174 -95
- data/spec/integration/schema_test.rb +128 -16
- data/spec/integration/spec_helper.rb +15 -0
- data/spec/integration/transaction_test.rb +40 -0
- data/spec/integration/type_test.rb +16 -2
- data/spec/model/association_reflection_spec.rb +91 -0
- data/spec/model/associations_spec.rb +476 -5
- data/spec/model/base_spec.rb +91 -1
- data/spec/model/eager_loading_spec.rb +519 -31
- data/spec/model/hooks_spec.rb +161 -0
- data/spec/model/model_spec.rb +89 -2
- data/spec/model/plugins_spec.rb +17 -0
- data/spec/model/record_spec.rb +184 -12
- data/spec/model/spec_helper.rb +5 -0
- data/spec/model/validations_spec.rb +11 -0
- metadata +85 -34
|
@@ -186,31 +186,26 @@ describe "Blockless Ruby Filters" do
|
|
|
186
186
|
@d.l(~((((:x - :y)/(:x + :y))*:z) <= 100)).should == '((((x - y) / (x + y)) * z) > 100)'
|
|
187
187
|
end
|
|
188
188
|
|
|
189
|
-
it "should not
|
|
190
|
-
proc{~:x.sql_string}.should raise_error
|
|
191
|
-
proc{~([:x, :y].sql_string_join)}.should raise_error
|
|
189
|
+
it "should not add ~ method to string expressions" do
|
|
190
|
+
proc{~:x.sql_string}.should raise_error(NoMethodError)
|
|
192
191
|
end
|
|
193
192
|
|
|
194
|
-
it "should
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
193
|
+
it "should allow mathematical or string operations on true, false, or nil" do
|
|
194
|
+
@d.lit(:x + 1).should == '(x + 1)'
|
|
195
|
+
@d.lit(:x - true).should == "(x - 't')"
|
|
196
|
+
@d.lit(:x / false).should == "(x / 'f')"
|
|
197
|
+
@d.lit(:x * nil).should == '(x * NULL)'
|
|
198
|
+
@d.lit([:x, nil].sql_string_join).should == '(x || NULL)'
|
|
200
199
|
end
|
|
201
200
|
|
|
202
|
-
it "should
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
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)
|
|
201
|
+
it "should allow mathematical or string operations on boolean complex expressions" do
|
|
202
|
+
@d.lit(:x + (:y + 1)).should == '(x + y + 1)'
|
|
203
|
+
@d.lit(:x - ~:y).should == '(x - NOT y)'
|
|
204
|
+
@d.lit(:x / (:y & :z)).should == '(x / (y AND z))'
|
|
205
|
+
@d.lit(:x * (:y | :z)).should == '(x * (y OR z))'
|
|
206
|
+
@d.lit(:x + :y.like('a')).should == "(x + (y LIKE 'a'))"
|
|
207
|
+
@d.lit(:x - ~:y.like('a')).should == "(x - (y NOT LIKE 'a'))"
|
|
208
|
+
@d.lit([:x, ~:y.like('a')].sql_string_join).should == "(x || (y NOT LIKE 'a'))"
|
|
214
209
|
end
|
|
215
210
|
|
|
216
211
|
it "should support AND conditions via &" do
|
|
@@ -382,12 +377,12 @@ describe "Blockless Ruby Filters" do
|
|
|
382
377
|
@d.l((:x + 1) & (:x + 2) > 100).should == '(((x + 1) & (x + 2)) > 100)'
|
|
383
378
|
end
|
|
384
379
|
|
|
385
|
-
it "should
|
|
386
|
-
|
|
380
|
+
it "should allow using a Bitwise method on a ComplexExpression that isn't a NumericExpression" do
|
|
381
|
+
@d.lit((:x + 1) & (:x + '2')).should == "((x + 1) & (x || '2'))"
|
|
387
382
|
end
|
|
388
383
|
|
|
389
|
-
it "should
|
|
390
|
-
|
|
384
|
+
it "should allow using a Boolean method on a ComplexExpression that isn't a BooleanExpression" do
|
|
385
|
+
@d.l(:x & (:x + '2')).should == "(x AND (x || '2'))"
|
|
391
386
|
end
|
|
392
387
|
|
|
393
388
|
it "should raise an error if attempting to invert a ComplexExpression that isn't a BooleanExpression" do
|
|
@@ -424,10 +419,94 @@ describe "Blockless Ruby Filters" do
|
|
|
424
419
|
@d.l(~{:x => Sequel::SQLFALSE}).should == '(x IS NOT FALSE)'
|
|
425
420
|
end
|
|
426
421
|
|
|
422
|
+
it "should support direct negation of SQL::Constants" do
|
|
423
|
+
@d.l({:x => ~Sequel::NULL}).should == '(x IS NOT NULL)'
|
|
424
|
+
@d.l({:x => ~Sequel::NOTNULL}).should == '(x IS NULL)'
|
|
425
|
+
@d.l({:x => ~Sequel::TRUE}).should == '(x IS FALSE)'
|
|
426
|
+
@d.l({:x => ~Sequel::FALSE}).should == '(x IS TRUE)'
|
|
427
|
+
@d.l({:x => ~Sequel::SQLTRUE}).should == '(x IS FALSE)'
|
|
428
|
+
@d.l({:x => ~Sequel::SQLFALSE}).should == '(x IS TRUE)'
|
|
429
|
+
end
|
|
430
|
+
|
|
431
|
+
it "should raise an error if trying to invert an invalid SQL::Constant" do
|
|
432
|
+
proc{~Sequel::CURRENT_DATE}.should raise_error(Sequel::Error)
|
|
433
|
+
end
|
|
434
|
+
|
|
427
435
|
it "should raise an error if trying to create an invalid complex expression" do
|
|
428
436
|
proc{Sequel::SQL::ComplexExpression.new(:BANG, 1, 2)}.should raise_error(Sequel::Error)
|
|
429
437
|
end
|
|
430
438
|
|
|
439
|
+
it "should use a string concatentation for + if given a string" do
|
|
440
|
+
@d.lit(:x + '1').should == "(x || '1')"
|
|
441
|
+
@d.lit(:x + '1' + '1').should == "(x || '1' || '1')"
|
|
442
|
+
end
|
|
443
|
+
|
|
444
|
+
it "should use an addition for + if given a literal string" do
|
|
445
|
+
@d.lit(:x + '1'.lit).should == "(x + 1)"
|
|
446
|
+
@d.lit(:x + '1'.lit + '1'.lit).should == "(x + 1 + 1)"
|
|
447
|
+
end
|
|
448
|
+
|
|
449
|
+
it "should use a bitwise operator for & and | if given an integer" do
|
|
450
|
+
@d.lit(:x & 1).should == "(x & 1)"
|
|
451
|
+
@d.lit(:x | 1).should == "(x | 1)"
|
|
452
|
+
@d.lit(:x & 1 & 1).should == "(x & 1 & 1)"
|
|
453
|
+
@d.lit(:x | 1 | 1).should == "(x | 1 | 1)"
|
|
454
|
+
end
|
|
455
|
+
|
|
456
|
+
it "should allow adding a string to an integer expression" do
|
|
457
|
+
@d.lit(:x + 1 + 'a').should == "(x + 1 + 'a')"
|
|
458
|
+
end
|
|
459
|
+
|
|
460
|
+
it "should allow adding an integer to an string expression" do
|
|
461
|
+
@d.lit(:x + 'a' + 1).should == "(x || 'a' || 1)"
|
|
462
|
+
end
|
|
463
|
+
|
|
464
|
+
it "should allow adding a boolean to an integer expression" do
|
|
465
|
+
@d.lit(:x + 1 + true).should == "(x + 1 + 't')"
|
|
466
|
+
end
|
|
467
|
+
|
|
468
|
+
it "should allow adding a boolean to an string expression" do
|
|
469
|
+
@d.lit(:x + 'a' + true).should == "(x || 'a' || 't')"
|
|
470
|
+
end
|
|
471
|
+
|
|
472
|
+
it "should allow using a boolean operation with an integer on an boolean expression" do
|
|
473
|
+
@d.lit(:x & :a & 1).should == "(x AND a AND 1)"
|
|
474
|
+
end
|
|
475
|
+
|
|
476
|
+
it "should allow using a boolean operation with a string on an boolean expression" do
|
|
477
|
+
@d.lit(:x & :a & 'a').should == "(x AND a AND 'a')"
|
|
478
|
+
end
|
|
479
|
+
|
|
480
|
+
it "should allowing AND of boolean expression and literal string" do
|
|
481
|
+
@d.lit(:x & :a & 'a'.lit).should == "(x AND a AND a)"
|
|
482
|
+
end
|
|
483
|
+
|
|
484
|
+
it "should allowing + of integer expression and literal string" do
|
|
485
|
+
@d.lit(:x + :a + 'a'.lit).should == "(x + a + a)"
|
|
486
|
+
end
|
|
487
|
+
|
|
488
|
+
it "should allowing + of string expression and literal string" do
|
|
489
|
+
@d.lit(:x + 'a' + 'a'.lit).should == "(x || 'a' || a)"
|
|
490
|
+
end
|
|
491
|
+
|
|
492
|
+
it "should allow sql_{string,boolean,number} methods on numeric expressions" do
|
|
493
|
+
@d.lit((:x + 1).sql_string + 'a').should == "((x + 1) || 'a')"
|
|
494
|
+
@d.lit((:x + 1).sql_boolean & 1).should == "((x + 1) AND 1)"
|
|
495
|
+
@d.lit((:x + 1).sql_number + 'a').should == "(x + 1 + 'a')"
|
|
496
|
+
end
|
|
497
|
+
|
|
498
|
+
it "should allow sql_{string,boolean,number} methods on string expressions" do
|
|
499
|
+
@d.lit((:x + 'a').sql_string + 'a').should == "(x || 'a' || 'a')"
|
|
500
|
+
@d.lit((:x + 'a').sql_boolean & 1).should == "((x || 'a') AND 1)"
|
|
501
|
+
@d.lit((:x + 'a').sql_number + 'a').should == "((x || 'a') + 'a')"
|
|
502
|
+
end
|
|
503
|
+
|
|
504
|
+
it "should allow sql_{string,boolean,number} methods on boolean expressions" do
|
|
505
|
+
@d.lit((:x & :y).sql_string + 'a').should == "((x AND y) || 'a')"
|
|
506
|
+
@d.lit((:x & :y).sql_boolean & 1).should == "(x AND y AND 1)"
|
|
507
|
+
@d.lit((:x & :y).sql_number + 'a').should == "((x AND y) + 'a')"
|
|
508
|
+
end
|
|
509
|
+
|
|
431
510
|
it "should raise an error if trying to literalize an invalid complex expression" do
|
|
432
511
|
ce = :x + 1
|
|
433
512
|
ce.instance_variable_set(:@op, :BANG)
|
|
@@ -439,26 +518,65 @@ describe "Blockless Ruby Filters" do
|
|
|
439
518
|
e2 = ~:comment.like('%:hidden:%')
|
|
440
519
|
e1.should == e2
|
|
441
520
|
end
|
|
521
|
+
|
|
522
|
+
it "should support expression filter methods on Datasets" do
|
|
523
|
+
d = @d.select(:a)
|
|
524
|
+
|
|
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
|
+
@d.lit(d / 1).should == '((SELECT a FROM items) / 1)'
|
|
529
|
+
|
|
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
|
+
@d.lit(d <= 1).should == '((SELECT a FROM items) <= 1)'
|
|
536
|
+
|
|
537
|
+
@d.lit(d.as(:b)).should == '(SELECT a FROM items) AS b'
|
|
538
|
+
|
|
539
|
+
@d.lit(d & :b).should == '((SELECT a FROM items) AND b)'
|
|
540
|
+
@d.lit(d | :b).should == '((SELECT a FROM items) OR b)'
|
|
541
|
+
@d.lit(~d).should == 'NOT (SELECT a FROM items)'
|
|
542
|
+
|
|
543
|
+
@d.lit(d.cast(Integer)).should == 'CAST((SELECT a FROM items) AS integer)'
|
|
544
|
+
@d.lit(d.cast_numeric).should == 'CAST((SELECT a FROM items) AS integer)'
|
|
545
|
+
@d.lit(d.cast_string).should == 'CAST((SELECT a FROM items) AS varchar(255))'
|
|
546
|
+
@d.lit(d.cast_numeric << :b).should == '(CAST((SELECT a FROM items) AS integer) << b)'
|
|
547
|
+
@d.lit(d.cast_string + :b).should == '(CAST((SELECT a FROM items) AS varchar(255)) || b)'
|
|
548
|
+
|
|
549
|
+
@d.lit(d.extract(:year)).should == 'extract(year FROM (SELECT a FROM items))'
|
|
550
|
+
@d.lit(d.sql_boolean & :b).should == '((SELECT a FROM items) AND b)'
|
|
551
|
+
@d.lit(d.sql_number << :b).should == '((SELECT a FROM items) << b)'
|
|
552
|
+
@d.lit(d.sql_string + :b).should == '((SELECT a FROM items) || b)'
|
|
553
|
+
|
|
554
|
+
@d.lit(d.asc).should == '(SELECT a FROM items) ASC'
|
|
555
|
+
@d.lit(d.desc).should == '(SELECT a FROM items) DESC'
|
|
556
|
+
|
|
557
|
+
@d.lit(d.like(:b)).should == '((SELECT a FROM items) LIKE b)'
|
|
558
|
+
@d.lit(d.ilike(:b)).should == '((SELECT a FROM items) ILIKE b)'
|
|
559
|
+
end
|
|
442
560
|
|
|
443
561
|
if RUBY_VERSION < '1.9.0'
|
|
444
562
|
it "should not allow inequality operations on true, false, or nil" do
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
563
|
+
@d.lit(:x > 1).should == "(x > 1)"
|
|
564
|
+
@d.lit(:x < true).should == "(x < 't')"
|
|
565
|
+
@d.lit(:x >= false).should == "(x >= 'f')"
|
|
566
|
+
@d.lit(:x <= nil).should == "(x <= NULL)"
|
|
449
567
|
end
|
|
450
568
|
|
|
451
569
|
it "should not allow inequality operations on boolean complex expressions" do
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
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 <= 5)).should == "(x <= (y <= 5))"
|
|
574
|
+
@d.lit(:x > {:y => nil}).should == "(x > (y IS NULL))"
|
|
575
|
+
@d.lit(:x < ~{:y => nil}).should == "(x < (y IS NOT NULL))"
|
|
576
|
+
@d.lit(:x >= {:y => 5}).should == "(x >= (y = 5))"
|
|
577
|
+
@d.lit(:x <= ~{:y => 5}).should == "(x <= (y != 5))"
|
|
578
|
+
@d.lit(:x >= {:y => [1,2,3]}).should == "(x >= (y IN (1, 2, 3)))"
|
|
579
|
+
@d.lit(:x <= ~{:y => [1,2,3]}).should == "(x <= (y NOT IN (1, 2, 3)))"
|
|
462
580
|
end
|
|
463
581
|
|
|
464
582
|
it "should support >, <, >=, and <= via Symbol#>,<,>=,<=" do
|
|
@@ -553,7 +671,7 @@ describe Sequel::SQL::VirtualRow do
|
|
|
553
671
|
end
|
|
554
672
|
|
|
555
673
|
it "should support :frame=>:rows option for window function calls" do
|
|
556
|
-
@d.l{rank(:over, :frame=>:rows){}}.should == 'rank() OVER (ROWS UNBOUNDED PRECEDING)'
|
|
674
|
+
@d.l{rank(:over, :frame=>:rows){}}.should == 'rank() OVER (ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)'
|
|
557
675
|
end
|
|
558
676
|
|
|
559
677
|
it "should support :frame=>'some string' option for window function calls" do
|
|
@@ -565,7 +683,7 @@ describe Sequel::SQL::VirtualRow do
|
|
|
565
683
|
end
|
|
566
684
|
|
|
567
685
|
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)'
|
|
686
|
+
@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
687
|
end
|
|
570
688
|
|
|
571
689
|
it "should raise an error if window functions are not supported" do
|
data/spec/core/schema_spec.rb
CHANGED
|
@@ -281,6 +281,13 @@ describe "DB#create_table" do
|
|
|
281
281
|
@db.sqls.should == ["CREATE TABLE cats (project_id integer REFERENCES projects DEFERRABLE INITIALLY DEFERRED)"]
|
|
282
282
|
end
|
|
283
283
|
|
|
284
|
+
specify "should accept collation" do
|
|
285
|
+
@db.create_table(:cats) do
|
|
286
|
+
varchar :name, :collate => :utf8_bin
|
|
287
|
+
end
|
|
288
|
+
@db.sqls.should == ["CREATE TABLE cats (name varchar(255) COLLATE utf8_bin)"]
|
|
289
|
+
end
|
|
290
|
+
|
|
284
291
|
specify "should accept inline index definition" do
|
|
285
292
|
@db.create_table(:cats) do
|
|
286
293
|
integer :id, :index => true
|
|
@@ -548,8 +555,15 @@ describe "DB#create_table!" do
|
|
|
548
555
|
@db = SchemaDummyDatabase.new
|
|
549
556
|
end
|
|
550
557
|
|
|
551
|
-
specify "should
|
|
552
|
-
@db.
|
|
558
|
+
specify "should create the table if it does not exist" do
|
|
559
|
+
@db.meta_def(:table_exists?){|a| false}
|
|
560
|
+
@db.create_table!(:cats){|*a|}
|
|
561
|
+
@db.sqls.should == ['CREATE TABLE cats ()']
|
|
562
|
+
end
|
|
563
|
+
|
|
564
|
+
specify "should drop the table before creating it if it already exists" do
|
|
565
|
+
@db.meta_def(:table_exists?){|a| true}
|
|
566
|
+
@db.create_table!(:cats){|*a|}
|
|
553
567
|
@db.sqls.should == ['DROP TABLE cats', 'CREATE TABLE cats ()']
|
|
554
568
|
end
|
|
555
569
|
end
|
|
@@ -570,6 +584,12 @@ describe "DB#create_table?" do
|
|
|
570
584
|
@db.create_table?(:cats){|*a|}
|
|
571
585
|
@db.sqls.should == ['CREATE TABLE cats ()']
|
|
572
586
|
end
|
|
587
|
+
|
|
588
|
+
specify "should use IF NOT EXISTS if the database supports that" do
|
|
589
|
+
@db.meta_def(:supports_create_table_if_not_exists?){true}
|
|
590
|
+
@db.create_table?(:cats){|*a|}
|
|
591
|
+
@db.sqls.should == ['CREATE TABLE IF NOT EXISTS cats ()']
|
|
592
|
+
end
|
|
573
593
|
end
|
|
574
594
|
|
|
575
595
|
describe "DB#drop_table" do
|
|
@@ -581,6 +601,16 @@ describe "DB#drop_table" do
|
|
|
581
601
|
@db.drop_table :cats
|
|
582
602
|
@db.sqls.should == ['DROP TABLE cats']
|
|
583
603
|
end
|
|
604
|
+
|
|
605
|
+
specify "should drop multiple tables at once" do
|
|
606
|
+
@db.drop_table :cats, :dogs
|
|
607
|
+
@db.sqls.should == ['DROP TABLE cats', 'DROP TABLE dogs']
|
|
608
|
+
end
|
|
609
|
+
|
|
610
|
+
specify "should take an options hash and support the :cascade option" do
|
|
611
|
+
@db.drop_table :cats, :dogs, :cascade=>true
|
|
612
|
+
@db.sqls.should == ['DROP TABLE cats CASCADE', 'DROP TABLE dogs CASCADE']
|
|
613
|
+
end
|
|
584
614
|
end
|
|
585
615
|
|
|
586
616
|
describe "DB#alter_table" do
|
|
@@ -709,6 +739,13 @@ describe "DB#alter_table" do
|
|
|
709
739
|
@db.sqls.should == ["ALTER TABLE cats DROP COLUMN score"]
|
|
710
740
|
end
|
|
711
741
|
|
|
742
|
+
specify "should support drop_column with :cascade=>true option" do
|
|
743
|
+
@db.alter_table(:cats) do
|
|
744
|
+
drop_column :score, :cascade=>true
|
|
745
|
+
end
|
|
746
|
+
@db.sqls.should == ["ALTER TABLE cats DROP COLUMN score CASCADE"]
|
|
747
|
+
end
|
|
748
|
+
|
|
712
749
|
specify "should support drop_constraint" do
|
|
713
750
|
@db.alter_table(:cats) do
|
|
714
751
|
drop_constraint :valid_score
|
|
@@ -716,6 +753,13 @@ describe "DB#alter_table" do
|
|
|
716
753
|
@db.sqls.should == ["ALTER TABLE cats DROP CONSTRAINT valid_score"]
|
|
717
754
|
end
|
|
718
755
|
|
|
756
|
+
specify "should support drop_constraint with :cascade=>true option" do
|
|
757
|
+
@db.alter_table(:cats) do
|
|
758
|
+
drop_constraint :valid_score, :cascade=>true
|
|
759
|
+
end
|
|
760
|
+
@db.sqls.should == ["ALTER TABLE cats DROP CONSTRAINT valid_score CASCADE"]
|
|
761
|
+
end
|
|
762
|
+
|
|
719
763
|
specify "should support drop_index" do
|
|
720
764
|
@db.alter_table(:cats) do
|
|
721
765
|
drop_index :name
|
|
@@ -763,6 +807,286 @@ describe "DB#alter_table" do
|
|
|
763
807
|
end
|
|
764
808
|
end
|
|
765
809
|
|
|
810
|
+
describe "Database#create_table" do
|
|
811
|
+
before do
|
|
812
|
+
@db = DummyDatabase.new
|
|
813
|
+
end
|
|
814
|
+
|
|
815
|
+
specify "should construct proper SQL" do
|
|
816
|
+
@db.create_table :test do
|
|
817
|
+
primary_key :id, :integer, :null => false
|
|
818
|
+
column :name, :text
|
|
819
|
+
index :name, :unique => true
|
|
820
|
+
end
|
|
821
|
+
@db.sqls.should == [
|
|
822
|
+
'CREATE TABLE test (id integer NOT NULL PRIMARY KEY AUTOINCREMENT, name text)',
|
|
823
|
+
'CREATE UNIQUE INDEX test_name_index ON test (name)'
|
|
824
|
+
]
|
|
825
|
+
end
|
|
826
|
+
|
|
827
|
+
specify "should create a temporary table" do
|
|
828
|
+
@db.create_table :test_tmp, :temp => true do
|
|
829
|
+
primary_key :id, :integer, :null => false
|
|
830
|
+
column :name, :text
|
|
831
|
+
index :name, :unique => true
|
|
832
|
+
end
|
|
833
|
+
|
|
834
|
+
@db.sqls.should == [
|
|
835
|
+
'CREATE TEMPORARY TABLE test_tmp (id integer NOT NULL PRIMARY KEY AUTOINCREMENT, name text)',
|
|
836
|
+
'CREATE UNIQUE INDEX test_tmp_name_index ON test_tmp (name)'
|
|
837
|
+
]
|
|
838
|
+
end
|
|
839
|
+
|
|
840
|
+
specify "should not use default schema when creating a temporary table" do
|
|
841
|
+
@db.default_schema = :foo
|
|
842
|
+
@db.create_table :test_tmp, :temp => true do
|
|
843
|
+
column :name, :text
|
|
844
|
+
end
|
|
845
|
+
@db.sqls.should == ['CREATE TEMPORARY TABLE test_tmp (name text)']
|
|
846
|
+
end
|
|
847
|
+
end
|
|
848
|
+
|
|
849
|
+
describe "Database#alter_table" do
|
|
850
|
+
before do
|
|
851
|
+
@db = DummyDatabase.new
|
|
852
|
+
end
|
|
853
|
+
|
|
854
|
+
specify "should construct proper SQL" do
|
|
855
|
+
@db.alter_table :xyz do
|
|
856
|
+
add_column :aaa, :text, :null => false, :unique => true
|
|
857
|
+
drop_column :bbb
|
|
858
|
+
rename_column :ccc, :ddd
|
|
859
|
+
set_column_type :eee, :integer
|
|
860
|
+
set_column_default :hhh, 'abcd'
|
|
861
|
+
|
|
862
|
+
add_index :fff, :unique => true
|
|
863
|
+
drop_index :ggg
|
|
864
|
+
end
|
|
865
|
+
|
|
866
|
+
@db.sqls.should == [
|
|
867
|
+
'ALTER TABLE xyz ADD COLUMN aaa text NOT NULL UNIQUE',
|
|
868
|
+
'ALTER TABLE xyz DROP COLUMN bbb',
|
|
869
|
+
'ALTER TABLE xyz RENAME COLUMN ccc TO ddd',
|
|
870
|
+
'ALTER TABLE xyz ALTER COLUMN eee TYPE integer',
|
|
871
|
+
"ALTER TABLE xyz ALTER COLUMN hhh SET DEFAULT 'abcd'",
|
|
872
|
+
|
|
873
|
+
'CREATE UNIQUE INDEX xyz_fff_index ON xyz (fff)',
|
|
874
|
+
'DROP INDEX xyz_ggg_index'
|
|
875
|
+
]
|
|
876
|
+
end
|
|
877
|
+
end
|
|
878
|
+
|
|
879
|
+
describe "Database#add_column" do
|
|
880
|
+
before do
|
|
881
|
+
@db = DummyDatabase.new
|
|
882
|
+
end
|
|
883
|
+
|
|
884
|
+
specify "should construct proper SQL" do
|
|
885
|
+
@db.add_column :test, :name, :text, :unique => true
|
|
886
|
+
@db.sqls.should == [
|
|
887
|
+
'ALTER TABLE test ADD COLUMN name text UNIQUE'
|
|
888
|
+
]
|
|
889
|
+
end
|
|
890
|
+
end
|
|
891
|
+
|
|
892
|
+
describe "Database#drop_column" do
|
|
893
|
+
before do
|
|
894
|
+
@db = DummyDatabase.new
|
|
895
|
+
end
|
|
896
|
+
|
|
897
|
+
specify "should construct proper SQL" do
|
|
898
|
+
@db.drop_column :test, :name
|
|
899
|
+
@db.sqls.should == ['ALTER TABLE test DROP COLUMN name']
|
|
900
|
+
end
|
|
901
|
+
|
|
902
|
+
specify "should use CASCADE for :cascade=>true option" do
|
|
903
|
+
@db.drop_column :test, :name, :cascade=>true
|
|
904
|
+
@db.sqls.should == ['ALTER TABLE test DROP COLUMN name CASCADE']
|
|
905
|
+
end
|
|
906
|
+
end
|
|
907
|
+
|
|
908
|
+
describe "Database#rename_column" do
|
|
909
|
+
before do
|
|
910
|
+
@db = DummyDatabase.new
|
|
911
|
+
end
|
|
912
|
+
|
|
913
|
+
specify "should construct proper SQL" do
|
|
914
|
+
@db.rename_column :test, :abc, :def
|
|
915
|
+
@db.sqls.should == [
|
|
916
|
+
'ALTER TABLE test RENAME COLUMN abc TO def'
|
|
917
|
+
]
|
|
918
|
+
end
|
|
919
|
+
end
|
|
920
|
+
|
|
921
|
+
describe "Database#set_column_type" do
|
|
922
|
+
before do
|
|
923
|
+
@db = DummyDatabase.new
|
|
924
|
+
end
|
|
925
|
+
|
|
926
|
+
specify "should construct proper SQL" do
|
|
927
|
+
@db.set_column_type :test, :name, :integer
|
|
928
|
+
@db.sqls.should == [
|
|
929
|
+
'ALTER TABLE test ALTER COLUMN name TYPE integer'
|
|
930
|
+
]
|
|
931
|
+
end
|
|
932
|
+
end
|
|
933
|
+
|
|
934
|
+
describe "Database#set_column_default" do
|
|
935
|
+
before do
|
|
936
|
+
@db = DummyDatabase.new
|
|
937
|
+
end
|
|
938
|
+
|
|
939
|
+
specify "should construct proper SQL" do
|
|
940
|
+
@db.set_column_default :test, :name, 'zyx'
|
|
941
|
+
@db.sqls.should == [
|
|
942
|
+
"ALTER TABLE test ALTER COLUMN name SET DEFAULT 'zyx'"
|
|
943
|
+
]
|
|
944
|
+
end
|
|
945
|
+
end
|
|
946
|
+
|
|
947
|
+
describe "Database#add_index" do
|
|
948
|
+
before do
|
|
949
|
+
@db = DummyDatabase.new
|
|
950
|
+
end
|
|
951
|
+
|
|
952
|
+
specify "should construct proper SQL" do
|
|
953
|
+
@db.add_index :test, :name, :unique => true
|
|
954
|
+
@db.sqls.should == [
|
|
955
|
+
'CREATE UNIQUE INDEX test_name_index ON test (name)'
|
|
956
|
+
]
|
|
957
|
+
end
|
|
958
|
+
|
|
959
|
+
specify "should accept multiple columns" do
|
|
960
|
+
@db.add_index :test, [:one, :two]
|
|
961
|
+
@db.sqls.should == [
|
|
962
|
+
'CREATE INDEX test_one_two_index ON test (one, two)'
|
|
963
|
+
]
|
|
964
|
+
end
|
|
965
|
+
end
|
|
966
|
+
|
|
967
|
+
describe "Database#drop_index" do
|
|
968
|
+
before do
|
|
969
|
+
@db = DummyDatabase.new
|
|
970
|
+
end
|
|
971
|
+
|
|
972
|
+
specify "should construct proper SQL" do
|
|
973
|
+
@db.drop_index :test, :name
|
|
974
|
+
@db.sqls.should == [
|
|
975
|
+
'DROP INDEX test_name_index'
|
|
976
|
+
]
|
|
977
|
+
end
|
|
978
|
+
|
|
979
|
+
end
|
|
980
|
+
|
|
981
|
+
describe "Database#drop_table" do
|
|
982
|
+
before do
|
|
983
|
+
@db = DummyDatabase.new
|
|
984
|
+
end
|
|
985
|
+
|
|
986
|
+
specify "should construct proper SQL" do
|
|
987
|
+
@db.drop_table :test
|
|
988
|
+
@db.sqls.should == ['DROP TABLE test']
|
|
989
|
+
end
|
|
990
|
+
|
|
991
|
+
specify "should accept multiple table names" do
|
|
992
|
+
@db.drop_table :a, :bb, :ccc
|
|
993
|
+
@db.sqls.should == [
|
|
994
|
+
'DROP TABLE a',
|
|
995
|
+
'DROP TABLE bb',
|
|
996
|
+
'DROP TABLE ccc'
|
|
997
|
+
]
|
|
998
|
+
end
|
|
999
|
+
end
|
|
1000
|
+
|
|
1001
|
+
describe "Database#rename_table" do
|
|
1002
|
+
before do
|
|
1003
|
+
@db = DummyDatabase.new
|
|
1004
|
+
end
|
|
1005
|
+
|
|
1006
|
+
specify "should construct proper SQL" do
|
|
1007
|
+
@db.rename_table :abc, :xyz
|
|
1008
|
+
@db.sqls.should == ['ALTER TABLE abc RENAME TO xyz']
|
|
1009
|
+
end
|
|
1010
|
+
end
|
|
1011
|
+
|
|
1012
|
+
describe "Database#create_view" do
|
|
1013
|
+
before do
|
|
1014
|
+
@db = DummyDatabase.new
|
|
1015
|
+
end
|
|
1016
|
+
|
|
1017
|
+
specify "should construct proper SQL with raw SQL" do
|
|
1018
|
+
@db.create_view :test, "SELECT * FROM xyz"
|
|
1019
|
+
@db.sqls.should == ['CREATE VIEW test AS SELECT * FROM xyz']
|
|
1020
|
+
@db.sqls.clear
|
|
1021
|
+
@db.create_view :test.identifier, "SELECT * FROM xyz"
|
|
1022
|
+
@db.sqls.should == ['CREATE VIEW test AS SELECT * FROM xyz']
|
|
1023
|
+
end
|
|
1024
|
+
|
|
1025
|
+
specify "should construct proper SQL with dataset" do
|
|
1026
|
+
@db.create_view :test, @db[:items].select(:a, :b).order(:c)
|
|
1027
|
+
@db.sqls.should == ['CREATE VIEW test AS SELECT a, b FROM items ORDER BY c']
|
|
1028
|
+
@db.sqls.clear
|
|
1029
|
+
@db.create_view :test.qualify(:sch), @db[:items].select(:a, :b).order(:c)
|
|
1030
|
+
@db.sqls.should == ['CREATE VIEW sch.test AS SELECT a, b FROM items ORDER BY c']
|
|
1031
|
+
end
|
|
1032
|
+
end
|
|
1033
|
+
|
|
1034
|
+
describe "Database#create_or_replace_view" do
|
|
1035
|
+
before do
|
|
1036
|
+
@db = DummyDatabase.new
|
|
1037
|
+
end
|
|
1038
|
+
|
|
1039
|
+
specify "should construct proper SQL with raw SQL" do
|
|
1040
|
+
@db.create_or_replace_view :test, "SELECT * FROM xyz"
|
|
1041
|
+
@db.sqls.should == ['CREATE OR REPLACE VIEW test AS SELECT * FROM xyz']
|
|
1042
|
+
@db.sqls.clear
|
|
1043
|
+
@db.create_or_replace_view :sch__test, "SELECT * FROM xyz"
|
|
1044
|
+
@db.sqls.should == ['CREATE OR REPLACE VIEW sch.test AS SELECT * FROM xyz']
|
|
1045
|
+
end
|
|
1046
|
+
|
|
1047
|
+
specify "should construct proper SQL with dataset" do
|
|
1048
|
+
@db.create_or_replace_view :test, @db[:items].select(:a, :b).order(:c)
|
|
1049
|
+
@db.sqls.should == ['CREATE OR REPLACE VIEW test AS SELECT a, b FROM items ORDER BY c']
|
|
1050
|
+
@db.sqls.clear
|
|
1051
|
+
@db.create_or_replace_view :test.identifier, @db[:items].select(:a, :b).order(:c)
|
|
1052
|
+
@db.sqls.should == ['CREATE OR REPLACE VIEW test AS SELECT a, b FROM items ORDER BY c']
|
|
1053
|
+
end
|
|
1054
|
+
end
|
|
1055
|
+
|
|
1056
|
+
describe "Database#drop_view" do
|
|
1057
|
+
before do
|
|
1058
|
+
@db = DummyDatabase.new
|
|
1059
|
+
end
|
|
1060
|
+
|
|
1061
|
+
specify "should construct proper SQL" do
|
|
1062
|
+
@db.drop_view :test
|
|
1063
|
+
@db.drop_view :test.identifier
|
|
1064
|
+
@db.drop_view :sch__test
|
|
1065
|
+
@db.drop_view :test.qualify(:sch)
|
|
1066
|
+
@db.sqls.should == ['DROP VIEW test', 'DROP VIEW test', 'DROP VIEW sch.test', 'DROP VIEW sch.test']
|
|
1067
|
+
end
|
|
1068
|
+
|
|
1069
|
+
specify "should drop multiple views at once" do
|
|
1070
|
+
@db.drop_view :cats, :dogs
|
|
1071
|
+
@db.sqls.should == ['DROP VIEW cats', 'DROP VIEW dogs']
|
|
1072
|
+
end
|
|
1073
|
+
|
|
1074
|
+
specify "should take an options hash and support the :cascade option" do
|
|
1075
|
+
@db.drop_view :cats, :dogs, :cascade=>true
|
|
1076
|
+
@db.sqls.should == ['DROP VIEW cats CASCADE', 'DROP VIEW dogs CASCADE']
|
|
1077
|
+
end
|
|
1078
|
+
end
|
|
1079
|
+
|
|
1080
|
+
describe "Database#alter_table_sql" do
|
|
1081
|
+
before do
|
|
1082
|
+
@db = DummyDatabase.new
|
|
1083
|
+
end
|
|
1084
|
+
|
|
1085
|
+
specify "should raise error for an invalid op" do
|
|
1086
|
+
proc {@db.send(:alter_table_sql, :mau, :op => :blah)}.should raise_error(Sequel::Error)
|
|
1087
|
+
end
|
|
1088
|
+
end
|
|
1089
|
+
|
|
766
1090
|
describe "Schema Parser" do
|
|
767
1091
|
before do
|
|
768
1092
|
@sqls = []
|
|
@@ -829,7 +1153,6 @@ describe "Schema Parser" do
|
|
|
829
1153
|
@db.schema(:"time with time zone").first.last[:type].should == :time
|
|
830
1154
|
@db.schema(:"time without time zone").first.last[:type].should == :time
|
|
831
1155
|
@db.schema(:boolean).first.last[:type].should == :boolean
|
|
832
|
-
@db.schema(:bit).first.last[:type].should == :boolean
|
|
833
1156
|
@db.schema(:real).first.last[:type].should == :float
|
|
834
1157
|
@db.schema(:float).first.last[:type].should == :float
|
|
835
1158
|
@db.schema(:double).first.last[:type].should == :float
|