sequel 2.9.0 → 2.10.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +56 -0
- data/{README → README.rdoc} +85 -57
- data/Rakefile +10 -5
- data/bin/sequel +7 -16
- data/doc/advanced_associations.rdoc +5 -17
- data/doc/cheat_sheet.rdoc +18 -20
- data/doc/dataset_filtering.rdoc +8 -32
- data/doc/schema.rdoc +20 -0
- data/lib/sequel_core.rb +35 -1
- data/lib/sequel_core/adapters/ado.rb +1 -1
- data/lib/sequel_core/adapters/db2.rb +2 -2
- data/lib/sequel_core/adapters/dbi.rb +2 -11
- data/lib/sequel_core/adapters/do.rb +205 -0
- data/lib/sequel_core/adapters/do/mysql.rb +38 -0
- data/lib/sequel_core/adapters/do/postgres.rb +92 -0
- data/lib/sequel_core/adapters/do/sqlite.rb +31 -0
- data/lib/sequel_core/adapters/firebird.rb +298 -0
- data/lib/sequel_core/adapters/informix.rb +10 -1
- data/lib/sequel_core/adapters/jdbc.rb +78 -19
- data/lib/sequel_core/adapters/jdbc/h2.rb +69 -0
- data/lib/sequel_core/adapters/jdbc/mysql.rb +10 -0
- data/lib/sequel_core/adapters/jdbc/postgresql.rb +7 -3
- data/lib/sequel_core/adapters/mysql.rb +53 -77
- data/lib/sequel_core/adapters/odbc.rb +1 -1
- data/lib/sequel_core/adapters/openbase.rb +1 -1
- data/lib/sequel_core/adapters/oracle.rb +2 -2
- data/lib/sequel_core/adapters/postgres.rb +16 -14
- data/lib/sequel_core/adapters/shared/mysql.rb +44 -9
- data/lib/sequel_core/adapters/shared/oracle.rb +4 -5
- data/lib/sequel_core/adapters/shared/postgres.rb +86 -82
- data/lib/sequel_core/adapters/shared/sqlite.rb +39 -24
- data/lib/sequel_core/adapters/sqlite.rb +11 -1
- data/lib/sequel_core/connection_pool.rb +10 -2
- data/lib/sequel_core/core_sql.rb +13 -3
- data/lib/sequel_core/database.rb +131 -30
- data/lib/sequel_core/database/schema.rb +5 -5
- data/lib/sequel_core/dataset.rb +31 -6
- data/lib/sequel_core/dataset/convenience.rb +11 -11
- data/lib/sequel_core/dataset/query.rb +2 -2
- data/lib/sequel_core/dataset/sql.rb +6 -6
- data/lib/sequel_core/exceptions.rb +4 -0
- data/lib/sequel_core/migration.rb +4 -4
- data/lib/sequel_core/schema/generator.rb +19 -3
- data/lib/sequel_core/schema/sql.rb +24 -20
- data/lib/sequel_core/sql.rb +13 -16
- data/lib/sequel_core/version.rb +11 -0
- data/lib/sequel_model.rb +2 -0
- data/lib/sequel_model/base.rb +2 -2
- data/lib/sequel_model/hooks.rb +46 -7
- data/lib/sequel_model/record.rb +11 -9
- data/lib/sequel_model/schema.rb +1 -1
- data/lib/sequel_model/validations.rb +72 -61
- data/spec/adapters/firebird_spec.rb +371 -0
- data/spec/adapters/mysql_spec.rb +118 -62
- data/spec/adapters/oracle_spec.rb +5 -5
- data/spec/adapters/postgres_spec.rb +33 -18
- data/spec/adapters/sqlite_spec.rb +2 -2
- data/spec/integration/dataset_test.rb +3 -3
- data/spec/integration/schema_test.rb +55 -5
- data/spec/integration/spec_helper.rb +11 -0
- data/spec/integration/type_test.rb +59 -16
- data/spec/sequel_core/connection_pool_spec.rb +14 -0
- data/spec/sequel_core/core_sql_spec.rb +24 -14
- data/spec/sequel_core/database_spec.rb +96 -11
- data/spec/sequel_core/dataset_spec.rb +97 -37
- data/spec/sequel_core/expression_filters_spec.rb +51 -40
- data/spec/sequel_core/object_graph_spec.rb +2 -2
- data/spec/sequel_core/schema_generator_spec.rb +31 -6
- data/spec/sequel_core/schema_spec.rb +25 -9
- data/spec/sequel_core/spec_helper.rb +4 -1
- data/spec/sequel_core/version_spec.rb +7 -0
- data/spec/sequel_model/associations_spec.rb +1 -1
- data/spec/sequel_model/hooks_spec.rb +68 -13
- data/spec/sequel_model/model_spec.rb +4 -4
- data/spec/sequel_model/record_spec.rb +22 -0
- data/spec/sequel_model/spec_helper.rb +2 -1
- data/spec/sequel_model/validations_spec.rb +107 -7
- metadata +15 -5
@@ -39,6 +39,66 @@ context "Dataset" do
|
|
39
39
|
specify "should include Enumerable" do
|
40
40
|
Sequel::Dataset.included_modules.should include(Enumerable)
|
41
41
|
end
|
42
|
+
|
43
|
+
specify "should get quote_identifiers default from database" do
|
44
|
+
db = Sequel::Database.new(:quote_identifiers=>true)
|
45
|
+
db[:a].quote_identifiers?.should == true
|
46
|
+
db = Sequel::Database.new(:quote_identifiers=>false)
|
47
|
+
db[:a].quote_identifiers?.should == false
|
48
|
+
end
|
49
|
+
|
50
|
+
specify "should get identifier_input_method default from database" do
|
51
|
+
db = Sequel::Database.new(:identifier_input_method=>:upcase)
|
52
|
+
db[:a].identifier_input_method.should == :upcase
|
53
|
+
db = Sequel::Database.new(:identifier_input_method=>:downcase)
|
54
|
+
db[:a].identifier_input_method.should == :downcase
|
55
|
+
end
|
56
|
+
|
57
|
+
specify "should get identifier_output_method default from database" do
|
58
|
+
db = Sequel::Database.new(:identifier_output_method=>:upcase)
|
59
|
+
db[:a].identifier_output_method.should == :upcase
|
60
|
+
db = Sequel::Database.new(:identifier_output_method=>:downcase)
|
61
|
+
db[:a].identifier_output_method.should == :downcase
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context "Dataset" do
|
66
|
+
setup do
|
67
|
+
@dataset = Sequel::Dataset.new("db")
|
68
|
+
end
|
69
|
+
|
70
|
+
specify "should have quote_identifiers= method which changes literalization of identifiers" do
|
71
|
+
@dataset.quote_identifiers = true
|
72
|
+
@dataset.literal(:a).should == '"a"'
|
73
|
+
@dataset.quote_identifiers = false
|
74
|
+
@dataset.literal(:a).should == 'a'
|
75
|
+
end
|
76
|
+
|
77
|
+
specify "should have upcase_identifiers= method which changes literalization of identifiers" do
|
78
|
+
@dataset.upcase_identifiers = true
|
79
|
+
@dataset.literal(:a).should == 'A'
|
80
|
+
@dataset.upcase_identifiers = false
|
81
|
+
@dataset.literal(:a).should == 'a'
|
82
|
+
end
|
83
|
+
|
84
|
+
specify "should have identifier_input_method= method which changes literalization of identifiers" do
|
85
|
+
@dataset.identifier_input_method = :upcase
|
86
|
+
@dataset.literal(:a).should == 'A'
|
87
|
+
@dataset.identifier_input_method = :downcase
|
88
|
+
@dataset.literal(:A).should == 'a'
|
89
|
+
@dataset.identifier_input_method = :reverse
|
90
|
+
@dataset.literal(:at_b).should == 'b_ta'
|
91
|
+
end
|
92
|
+
|
93
|
+
specify "should have identifier_output_method= method which changes identifiers returned from the database" do
|
94
|
+
@dataset.send(:output_identifier, "at_b_C").should == :at_b_C
|
95
|
+
@dataset.identifier_output_method = :upcase
|
96
|
+
@dataset.send(:output_identifier, "at_b_C").should == :AT_B_C
|
97
|
+
@dataset.identifier_output_method = :downcase
|
98
|
+
@dataset.send(:output_identifier, "at_b_C").should == :at_b_c
|
99
|
+
@dataset.identifier_output_method = :reverse
|
100
|
+
@dataset.send(:output_identifier, "at_b_C").should == :C_b_ta
|
101
|
+
end
|
42
102
|
end
|
43
103
|
|
44
104
|
context "Dataset#clone" do
|
@@ -194,8 +254,8 @@ end
|
|
194
254
|
context "Dataset#exists" do
|
195
255
|
setup do
|
196
256
|
@ds1 = Sequel::Dataset.new(nil).from(:test)
|
197
|
-
@ds2 = @ds1.filter(:price < 100)
|
198
|
-
@ds3 = @ds1.filter(:price > 50)
|
257
|
+
@ds2 = @ds1.filter(:price.sql_number < 100)
|
258
|
+
@ds3 = @ds1.filter(:price.sql_number > 50)
|
199
259
|
end
|
200
260
|
|
201
261
|
specify "should work in filters" do
|
@@ -290,7 +350,7 @@ context "Dataset#where" do
|
|
290
350
|
end
|
291
351
|
|
292
352
|
specify "should be composable using AND operator (for scoping) with block" do
|
293
|
-
@d3.where{:e < 5}.select_sql.should ==
|
353
|
+
@d3.where{:e.sql_number < 5}.select_sql.should ==
|
294
354
|
"SELECT * FROM test WHERE ((a = 1) AND (e < 5))"
|
295
355
|
end
|
296
356
|
|
@@ -318,7 +378,7 @@ context "Dataset#where" do
|
|
318
378
|
end
|
319
379
|
|
320
380
|
specify "should accept a subquery" do
|
321
|
-
@dataset.filter('gdp > ?', @d1.select(:avg
|
381
|
+
@dataset.filter('gdp > ?', @d1.select(:avg.sql_function(:gdp))).sql.should ==
|
322
382
|
"SELECT * FROM test WHERE (gdp > (SELECT avg(gdp) FROM test WHERE (region = 'Asia')))"
|
323
383
|
|
324
384
|
@dataset.filter(:id => @d1.select(:id)).sql.should ==
|
@@ -326,20 +386,20 @@ context "Dataset#where" do
|
|
326
386
|
end
|
327
387
|
|
328
388
|
specify "should accept a subquery for an EXISTS clause" do
|
329
|
-
a = @dataset.filter(:price < 100)
|
389
|
+
a = @dataset.filter(:price.sql_number < 100)
|
330
390
|
@dataset.filter(a.exists).sql.should ==
|
331
391
|
'SELECT * FROM test WHERE (EXISTS (SELECT * FROM test WHERE (price < 100)))'
|
332
392
|
end
|
333
393
|
|
334
394
|
specify "should accept proc expressions" do
|
335
|
-
d = @d1.select(:avg
|
336
|
-
@dataset.filter {:gdp > d}.sql.should ==
|
395
|
+
d = @d1.select(:avg.sql_function(:gdp))
|
396
|
+
@dataset.filter {:gdp.sql_number > d}.sql.should ==
|
337
397
|
"SELECT * FROM test WHERE (gdp > (SELECT avg(gdp) FROM test WHERE (region = 'Asia')))"
|
338
398
|
|
339
|
-
@dataset.filter {:a < 1}.sql.should ==
|
399
|
+
@dataset.filter {:a.sql_number < 1}.sql.should ==
|
340
400
|
'SELECT * FROM test WHERE (a < 1)'
|
341
401
|
|
342
|
-
@dataset.filter {(:a >= 1) & (:b <= 2)}.sql.should ==
|
402
|
+
@dataset.filter {(:a.sql_number >= 1) & (:b.sql_number <= 2)}.sql.should ==
|
343
403
|
'SELECT * FROM test WHERE ((a >= 1) AND (b <= 2))'
|
344
404
|
|
345
405
|
@dataset.filter {:c.like 'ABC%'}.sql.should ==
|
@@ -365,7 +425,7 @@ context "Dataset#where" do
|
|
365
425
|
end
|
366
426
|
|
367
427
|
specify "should allow the use of blocks and arguments simultaneously" do
|
368
|
-
@dataset.filter(:zz < 3){:yy > 3}.sql.should ==
|
428
|
+
@dataset.filter(:zz.sql_number < 3){:yy.sql_number > 3}.sql.should ==
|
369
429
|
'SELECT * FROM test WHERE ((zz < 3) AND (yy > 3))'
|
370
430
|
end
|
371
431
|
|
@@ -405,12 +465,12 @@ context "Dataset#or" do
|
|
405
465
|
specify "should accept all forms of filters" do
|
406
466
|
@d1.or('y > ?', 2).sql.should ==
|
407
467
|
'SELECT * FROM test WHERE ((x = 1) OR (y > 2))'
|
408
|
-
@d1.or(:yy > 3).sql.should ==
|
468
|
+
@d1.or(:yy.sql_number > 3).sql.should ==
|
409
469
|
'SELECT * FROM test WHERE ((x = 1) OR (yy > 3))'
|
410
470
|
end
|
411
471
|
|
412
472
|
specify "should accept blocks passed to filter" do
|
413
|
-
@d1.or{:yy > 3}.sql.should ==
|
473
|
+
@d1.or{:yy.sql_number > 3}.sql.should ==
|
414
474
|
'SELECT * FROM test WHERE ((x = 1) OR (yy > 3))'
|
415
475
|
end
|
416
476
|
|
@@ -423,7 +483,7 @@ context "Dataset#or" do
|
|
423
483
|
end
|
424
484
|
|
425
485
|
specify "should allow the use of blocks and arguments simultaneously" do
|
426
|
-
@d1.or(:zz < 3){:yy > 3}.sql.should ==
|
486
|
+
@d1.or(:zz.sql_number < 3){:yy.sql_number > 3}.sql.should ==
|
427
487
|
'SELECT * FROM test WHERE ((x = 1) OR ((zz < 3) AND (yy > 3)))'
|
428
488
|
end
|
429
489
|
end
|
@@ -450,12 +510,12 @@ context "Dataset#and" do
|
|
450
510
|
# probably not exhaustive, but good enough
|
451
511
|
@d1.and('y > ?', 2).sql.should ==
|
452
512
|
'SELECT * FROM test WHERE ((x = 1) AND (y > 2))'
|
453
|
-
@d1.and(:yy > 3).sql.should ==
|
513
|
+
@d1.and(:yy.sql_number > 3).sql.should ==
|
454
514
|
'SELECT * FROM test WHERE ((x = 1) AND (yy > 3))'
|
455
515
|
end
|
456
516
|
|
457
517
|
specify "should accept blocks passed to filter" do
|
458
|
-
@d1.and {:yy > 3}.sql.should ==
|
518
|
+
@d1.and {:yy.sql_number > 3}.sql.should ==
|
459
519
|
'SELECT * FROM test WHERE ((x = 1) AND (yy > 3))'
|
460
520
|
end
|
461
521
|
|
@@ -500,12 +560,12 @@ context "Dataset#exclude" do
|
|
500
560
|
end
|
501
561
|
|
502
562
|
specify "should support proc expressions" do
|
503
|
-
@dataset.exclude{:id < 6}.sql.should ==
|
563
|
+
@dataset.exclude{:id.sql_number < 6}.sql.should ==
|
504
564
|
'SELECT * FROM test WHERE (id >= 6)'
|
505
565
|
end
|
506
566
|
|
507
567
|
specify "should allow the use of blocks and arguments simultaneously" do
|
508
|
-
@dataset.exclude(:id => (7..11)){:id < 6}.sql.should ==
|
568
|
+
@dataset.exclude(:id => (7..11)){:id.sql_number < 6}.sql.should ==
|
509
569
|
'SELECT * FROM test WHERE (((id < 7) OR (id > 11)) OR (id >= 6))'
|
510
570
|
end
|
511
571
|
end
|
@@ -531,7 +591,7 @@ end
|
|
531
591
|
context "Dataset#having" do
|
532
592
|
setup do
|
533
593
|
@dataset = Sequel::Dataset.new(nil).from(:test)
|
534
|
-
@grouped = @dataset.group(:region).select(:region, :sum
|
594
|
+
@grouped = @dataset.group(:region).select(:region, :sum.sql_function(:population), :avg.sql_function(:gdp))
|
535
595
|
@d1 = @grouped.having('sum(population) > 10')
|
536
596
|
@d2 = @grouped.having(:region => 'Asia')
|
537
597
|
@columns = "region, sum(population), avg(gdp)"
|
@@ -547,12 +607,12 @@ context "Dataset#having" do
|
|
547
607
|
end
|
548
608
|
|
549
609
|
specify "should support proc expressions" do
|
550
|
-
@grouped.having {:sum
|
610
|
+
@grouped.having {:sum.sql_function(:population) > 10}.sql.should ==
|
551
611
|
"SELECT #{@columns} FROM test GROUP BY region HAVING (sum(population) > 10)"
|
552
612
|
end
|
553
613
|
|
554
614
|
specify "should work with and on the having clause" do
|
555
|
-
@grouped.having( :a > 1 ).and( :b < 2 ).sql.should ==
|
615
|
+
@grouped.having( :a.sql_number > 1 ).and( :b.sql_number < 2 ).sql.should ==
|
556
616
|
"SELECT #{@columns} FROM test GROUP BY region HAVING ((a > 1) AND (b < 2))"
|
557
617
|
end
|
558
618
|
end
|
@@ -742,10 +802,10 @@ context "Dataset#from" do
|
|
742
802
|
end
|
743
803
|
|
744
804
|
specify "should accept sql functions" do
|
745
|
-
@dataset.from(:abc
|
805
|
+
@dataset.from(:abc.sql_function(:def)).select_sql.should ==
|
746
806
|
"SELECT * FROM abc(def)"
|
747
807
|
|
748
|
-
@dataset.from(:a
|
808
|
+
@dataset.from(:a.sql_function(:i)).select_sql.should ==
|
749
809
|
"SELECT * FROM a(i)"
|
750
810
|
end
|
751
811
|
|
@@ -803,7 +863,7 @@ context "Dataset#select" do
|
|
803
863
|
specify "should accept arbitrary objects and literalize them correctly" do
|
804
864
|
@d.select(1, :a, 't').sql.should == "SELECT 1, a, 't' FROM test"
|
805
865
|
|
806
|
-
@d.select(nil, :sum
|
866
|
+
@d.select(nil, :sum.sql_function(:t), :x___y).sql.should == "SELECT NULL, sum(t), x AS y FROM test"
|
807
867
|
|
808
868
|
@d.select(nil, 1, :x => :y).sql.should == "SELECT NULL, 1, x AS y FROM test"
|
809
869
|
end
|
@@ -1161,7 +1221,7 @@ context "Dataset#count" do
|
|
1161
1221
|
end
|
1162
1222
|
|
1163
1223
|
specify "should include the where clause if it's there" do
|
1164
|
-
@dataset.filter(:abc < 30).count.should == 1
|
1224
|
+
@dataset.filter(:abc.sql_number < 30).count.should == 1
|
1165
1225
|
@c.sql.should == 'SELECT COUNT(*) FROM test WHERE (abc < 30) LIMIT 1'
|
1166
1226
|
end
|
1167
1227
|
|
@@ -1268,7 +1328,7 @@ context "Dataset#join_table" do
|
|
1268
1328
|
end
|
1269
1329
|
|
1270
1330
|
specify "should include WHERE clause if applicable" do
|
1271
|
-
@d.filter(:price < 100).join_table(:right_outer, :categories, :category_id => :id).sql.should ==
|
1331
|
+
@d.filter(:price.sql_number < 100).join_table(:right_outer, :categories, :category_id => :id).sql.should ==
|
1272
1332
|
'SELECT * FROM "items" RIGHT OUTER JOIN "categories" ON ("categories"."category_id" = "items"."id") WHERE ("price" < 100)'
|
1273
1333
|
end
|
1274
1334
|
|
@@ -1428,7 +1488,7 @@ context "Dataset#join_table" do
|
|
1428
1488
|
end
|
1429
1489
|
|
1430
1490
|
specify "should support using an expression as the join condition" do
|
1431
|
-
@d.join(:categories, :number > 10).sql.should ==
|
1491
|
+
@d.join(:categories, :number.sql_number > 10).sql.should ==
|
1432
1492
|
'SELECT * FROM "items" INNER JOIN "categories" ON ("number" > 10)'
|
1433
1493
|
end
|
1434
1494
|
|
@@ -1634,7 +1694,7 @@ context "Dataset#range" do
|
|
1634
1694
|
@d.range(:stamp)
|
1635
1695
|
@d.last_sql.should == "SELECT min(stamp) AS v1, max(stamp) AS v2 FROM test LIMIT 1"
|
1636
1696
|
|
1637
|
-
@d.filter(:price > 100).range(:stamp)
|
1697
|
+
@d.filter(:price.sql_number > 100).range(:stamp)
|
1638
1698
|
@d.last_sql.should == "SELECT min(stamp) AS v1, max(stamp) AS v2 FROM test WHERE (price > 100) LIMIT 1"
|
1639
1699
|
end
|
1640
1700
|
|
@@ -1662,7 +1722,7 @@ context "Dataset#interval" do
|
|
1662
1722
|
@d.interval(:stamp)
|
1663
1723
|
@d.last_sql.should == "SELECT (max(stamp) - min(stamp)) FROM test LIMIT 1"
|
1664
1724
|
|
1665
|
-
@d.filter(:price > 100).interval(:stamp)
|
1725
|
+
@d.filter(:price.sql_number > 100).interval(:stamp)
|
1666
1726
|
@d.last_sql.should == "SELECT (max(stamp) - min(stamp)) FROM test WHERE (price > 100) LIMIT 1"
|
1667
1727
|
end
|
1668
1728
|
|
@@ -1703,20 +1763,20 @@ context "Dataset #first and #last" do
|
|
1703
1763
|
end
|
1704
1764
|
|
1705
1765
|
specify "should return the first matching record if a block is given without an argument" do
|
1706
|
-
@d.first{:z > 26}.should == [:a,1,:b,2, 'SELECT * FROM test WHERE (z > 26) LIMIT 1']
|
1707
|
-
@d.order(:name).last{:z > 26}.should == [:a,1,:b,2, 'SELECT * FROM test WHERE (z > 26) ORDER BY name DESC LIMIT 1']
|
1766
|
+
@d.first{:z.sql_number > 26}.should == [:a,1,:b,2, 'SELECT * FROM test WHERE (z > 26) LIMIT 1']
|
1767
|
+
@d.order(:name).last{:z.sql_number > 26}.should == [:a,1,:b,2, 'SELECT * FROM test WHERE (z > 26) ORDER BY name DESC LIMIT 1']
|
1708
1768
|
end
|
1709
1769
|
|
1710
1770
|
specify "should combine block and standard argument filters if argument is not an Integer" do
|
1711
|
-
@d.first(:y=>25){:z > 26}.should == [:a,1,:b,2, 'SELECT * FROM test WHERE ((z > 26) AND (y = 25)) LIMIT 1']
|
1712
|
-
@d.order(:name).last('y = ?', 16){:z > 26}.should == [:a,1,:b,2, 'SELECT * FROM test WHERE ((z > 26) AND (y = 16)) ORDER BY name DESC LIMIT 1']
|
1771
|
+
@d.first(:y=>25){:z.sql_number > 26}.should == [:a,1,:b,2, 'SELECT * FROM test WHERE ((z > 26) AND (y = 25)) LIMIT 1']
|
1772
|
+
@d.order(:name).last('y = ?', 16){:z.sql_number > 26}.should == [:a,1,:b,2, 'SELECT * FROM test WHERE ((z > 26) AND (y = 16)) ORDER BY name DESC LIMIT 1']
|
1713
1773
|
end
|
1714
1774
|
|
1715
1775
|
specify "should filter and return an array of records if an Integer argument is provided and a block is given" do
|
1716
1776
|
i = rand(10) + 10
|
1717
|
-
r = @d.order(:a).first(i){:z > 26}.should == [[:a,1,:b,2, "SELECT * FROM test WHERE (z > 26) ORDER BY a LIMIT #{i}"]] * i
|
1777
|
+
r = @d.order(:a).first(i){:z.sql_number > 26}.should == [[:a,1,:b,2, "SELECT * FROM test WHERE (z > 26) ORDER BY a LIMIT #{i}"]] * i
|
1718
1778
|
i = rand(10) + 10
|
1719
|
-
r = @d.order(:a).last(i){:z > 26}.should == [[:a,1,:b,2, "SELECT * FROM test WHERE (z > 26) ORDER BY a DESC LIMIT #{i}"]] * i
|
1779
|
+
r = @d.order(:a).last(i){:z.sql_number > 26}.should == [[:a,1,:b,2, "SELECT * FROM test WHERE (z > 26) ORDER BY a DESC LIMIT #{i}"]] * i
|
1720
1780
|
end
|
1721
1781
|
|
1722
1782
|
specify "#last should raise if no order is given" do
|
@@ -2537,7 +2597,7 @@ context "Dataset#query" do
|
|
2537
2597
|
q.sql.should == "SELECT * FROM zzz WHERE ((x + 2) > (y + 3))"
|
2538
2598
|
|
2539
2599
|
q = @d.from(:zzz).query do
|
2540
|
-
where((:x > 1) & (:y > 2))
|
2600
|
+
where((:x.sql_number > 1) & (:y.sql_number > 2))
|
2541
2601
|
end
|
2542
2602
|
q.class.should == @d.class
|
2543
2603
|
q.sql.should == "SELECT * FROM zzz WHERE ((x > 1) AND (y > 2))"
|
@@ -2553,7 +2613,7 @@ context "Dataset#query" do
|
|
2553
2613
|
q = @d.query do
|
2554
2614
|
from :abc
|
2555
2615
|
group_by :id
|
2556
|
-
having(:x >= 2)
|
2616
|
+
having(:x.sql_number >= 2)
|
2557
2617
|
end
|
2558
2618
|
q.class.should == @d.class
|
2559
2619
|
q.sql.should == "SELECT * FROM abc GROUP BY id HAVING (x >= 2)"
|
@@ -2606,7 +2666,7 @@ context "Dataset" do
|
|
2606
2666
|
end
|
2607
2667
|
|
2608
2668
|
specify "should support self-changing filter! with block" do
|
2609
|
-
@d.filter!{:y < 2}
|
2669
|
+
@d.filter!{:y.sql_number < 2}
|
2610
2670
|
@d.sql.should == "SELECT * FROM x WHERE (y < 2)"
|
2611
2671
|
end
|
2612
2672
|
|
@@ -27,34 +27,19 @@ context "Blockless Ruby Filters" do
|
|
27
27
|
end
|
28
28
|
|
29
29
|
it "should support NOT with SQL functions" do
|
30
|
-
@d.l(~:is_blah
|
31
|
-
@d.l(~:is_blah
|
32
|
-
@d.l(~:is_blah
|
33
|
-
@d.l(~:is_blah
|
30
|
+
@d.l(~:is_blah.sql_function).should == 'NOT is_blah()'
|
31
|
+
@d.l(~:is_blah.sql_function(:x)).should == 'NOT is_blah(x)'
|
32
|
+
@d.l(~:is_blah.sql_function(:x__y)).should == 'NOT is_blah(x.y)'
|
33
|
+
@d.l(~:is_blah.sql_function(:x, :x__y)).should == 'NOT is_blah(x, x.y)'
|
34
34
|
end
|
35
35
|
|
36
36
|
it "should handle multiple ~" do
|
37
37
|
@d.l(~~:x).should == 'x'
|
38
38
|
@d.l(~~~:x).should == 'NOT x'
|
39
|
-
@d.l(~~(:x > 100)).should == '(x > 100)'
|
40
39
|
@d.l(~~(:x & :y)).should == '(x AND y)'
|
41
40
|
@d.l(~~(:x | :y)).should == '(x OR y)'
|
42
41
|
end
|
43
42
|
|
44
|
-
it "should support >, <, >=, and <= via Symbol#>,<,>=,<=" do
|
45
|
-
@d.l(:x > 100).should == '(x > 100)'
|
46
|
-
@d.l(:x < 100.01).should == '(x < 100.01)'
|
47
|
-
@d.l(:x >= 100000000000000000000000000000000000).should == '(x >= 100000000000000000000000000000000000)'
|
48
|
-
@d.l(:x <= 100).should == '(x <= 100)'
|
49
|
-
end
|
50
|
-
|
51
|
-
it "should support negation of >, <, >=, and <= via Symbol#~" do
|
52
|
-
@d.l(~(:x > 100)).should == '(x <= 100)'
|
53
|
-
@d.l(~(:x < 100.01)).should == '(x >= 100.01)'
|
54
|
-
@d.l(~(:x >= 100000000000000000000000000000000000)).should == '(x < 100000000000000000000000000000000000)'
|
55
|
-
@d.l(~(:x <= 100)).should == '(x > 100)'
|
56
|
-
end
|
57
|
-
|
58
43
|
it "should support = via Hash" do
|
59
44
|
@d.l(:x => 100).should == '(x = 100)'
|
60
45
|
@d.l(:x => 'a').should == '(x = \'a\')'
|
@@ -135,33 +120,19 @@ context "Blockless Ruby Filters" do
|
|
135
120
|
proc{~([:x, :y].sql_string_join)}.should raise_error
|
136
121
|
end
|
137
122
|
|
138
|
-
it "should not allow mathematical
|
123
|
+
it "should not allow mathematical or string operations on true, false, or nil" do
|
139
124
|
proc{:x + 1}.should_not raise_error
|
140
125
|
proc{:x - true}.should raise_error(Sequel::Error)
|
141
126
|
proc{:x / false}.should raise_error(Sequel::Error)
|
142
127
|
proc{:x * nil}.should raise_error(Sequel::Error)
|
143
|
-
proc{:x > 1}.should_not raise_error
|
144
|
-
proc{:x < true}.should raise_error(Sequel::Error)
|
145
|
-
proc{:x >= false}.should raise_error(Sequel::Error)
|
146
|
-
proc{:x <= nil}.should raise_error(Sequel::Error)
|
147
128
|
proc{[:x, nil].sql_string_join}.should raise_error(Sequel::Error)
|
148
129
|
end
|
149
130
|
|
150
|
-
it "should not allow mathematical
|
131
|
+
it "should not allow mathematical or string operations on boolean complex expressions" do
|
151
132
|
proc{:x + (:y + 1)}.should_not raise_error
|
152
133
|
proc{:x - (~:y)}.should raise_error(Sequel::Error)
|
153
134
|
proc{:x / (:y & :z)}.should raise_error(Sequel::Error)
|
154
135
|
proc{:x * (:y | :z)}.should raise_error(Sequel::Error)
|
155
|
-
proc{:x > (:y > 5)}.should raise_error(Sequel::Error)
|
156
|
-
proc{:x < (:y < 5)}.should raise_error(Sequel::Error)
|
157
|
-
proc{:x >= (:y >= 5)}.should raise_error(Sequel::Error)
|
158
|
-
proc{:x <= (:y <= 5)}.should raise_error(Sequel::Error)
|
159
|
-
proc{:x > {:y => nil}}.should raise_error(Sequel::Error)
|
160
|
-
proc{:x < ~{:y => nil}}.should raise_error(Sequel::Error)
|
161
|
-
proc{:x >= {:y => 5}}.should raise_error(Sequel::Error)
|
162
|
-
proc{:x <= ~{:y => 5}}.should raise_error(Sequel::Error)
|
163
|
-
proc{:x >= {:y => [1,2,3]}}.should raise_error(Sequel::Error)
|
164
|
-
proc{:x <= ~{:y => [1,2,3]}}.should raise_error(Sequel::Error)
|
165
136
|
proc{:x + :y.like('a')}.should raise_error(Sequel::Error)
|
166
137
|
proc{:x - :y.like(/a/)}.should raise_error(Sequel::Error)
|
167
138
|
proc{:x * :y.like(/a/i)}.should raise_error(Sequel::Error)
|
@@ -178,7 +149,7 @@ context "Blockless Ruby Filters" do
|
|
178
149
|
@d.l(:x & {:y => :z}).should == '(x AND (y = z))'
|
179
150
|
@d.l({:y => :z} & :x).should == '((y = z) AND x)'
|
180
151
|
@d.l({:x => :a} & {:y => :z}).should == '((x = a) AND (y = z))'
|
181
|
-
@d.l((:x
|
152
|
+
@d.l((:x + 200 < 0) & (:y - 200 < 0)).should == '(((x + 200) < 0) AND ((y - 200) < 0))'
|
182
153
|
@d.l(:x & ~:y).should == '(x AND NOT y)'
|
183
154
|
@d.l(~:x & :y).should == '(NOT x AND y)'
|
184
155
|
@d.l(~:x & ~:y).should == '(NOT x AND NOT y)'
|
@@ -191,7 +162,7 @@ context "Blockless Ruby Filters" do
|
|
191
162
|
@d.l(:x | {:y => :z}).should == '(x OR (y = z))'
|
192
163
|
@d.l({:y => :z} | :x).should == '((y = z) OR x)'
|
193
164
|
@d.l({:x => :a} | {:y => :z}).should == '((x = a) OR (y = z))'
|
194
|
-
@d.l((:x > 200) | (:y < 200)).should == '((x > 200) OR (y < 200))'
|
165
|
+
@d.l((:x.sql_number > 200) | (:y.sql_number < 200)).should == '((x > 200) OR (y < 200))'
|
195
166
|
end
|
196
167
|
|
197
168
|
it "should support & | combinations" do
|
@@ -204,7 +175,7 @@ context "Blockless Ruby Filters" do
|
|
204
175
|
@d.l(~((:x | :y) & :z)).should == '((NOT x AND NOT y) OR NOT z)'
|
205
176
|
@d.l(~(:x | (:y & :z))).should == '(NOT x AND (NOT y OR NOT z))'
|
206
177
|
@d.l(~((:x & :w) | (:y & :z))).should == '((NOT x OR NOT w) AND (NOT y OR NOT z))'
|
207
|
-
@d.l(~((:x > 200) | (:y & :z))).should == '((x <= 200) AND (NOT y OR NOT z))'
|
178
|
+
@d.l(~((:x.sql_number > 200) | (:y & :z))).should == '((x <= 200) AND (NOT y OR NOT z))'
|
208
179
|
end
|
209
180
|
|
210
181
|
it "should support LiteralString" do
|
@@ -278,8 +249,8 @@ context "Blockless Ruby Filters" do
|
|
278
249
|
@d.lit([:x].sql_string_join(', ')).should == '(x)'
|
279
250
|
@d.lit([:x, :y].sql_string_join).should == '(x || y)'
|
280
251
|
@d.lit([:x, :y].sql_string_join(', ')).should == "(x || ', ' || y)"
|
281
|
-
@d.lit([:x
|
282
|
-
@d.lit([:x
|
252
|
+
@d.lit([:x.sql_function(1), :y|1].sql_string_join).should == '(x(1) || y[1])'
|
253
|
+
@d.lit([:x.sql_function(1), 'y.z'.lit].sql_string_join(', ')).should == "(x(1) || ', ' || y.z)"
|
283
254
|
@d.lit([:x, 1, :y].sql_string_join).should == "(x || '1' || y)"
|
284
255
|
@d.lit([:x, 1, :y].sql_string_join(', ')).should == "(x || ', ' || '1' || ', ' || y)"
|
285
256
|
@d.lit([:x, 1, :y].sql_string_join(:y__z)).should == "(x || y.z || '1' || y.z || y)"
|
@@ -349,4 +320,44 @@ context "Blockless Ruby Filters" do
|
|
349
320
|
e2 = ~:comment.like('%:hidden:%')
|
350
321
|
e1.should == e2
|
351
322
|
end
|
323
|
+
|
324
|
+
if RUBY_VERSION < '1.9.0'
|
325
|
+
it "should not allow inequality operations on true, false, or nil" do
|
326
|
+
proc{:x > 1}.should_not raise_error
|
327
|
+
proc{:x < true}.should raise_error(Sequel::Error)
|
328
|
+
proc{:x >= false}.should raise_error(Sequel::Error)
|
329
|
+
proc{:x <= nil}.should raise_error(Sequel::Error)
|
330
|
+
end
|
331
|
+
|
332
|
+
it "should not allow inequality operations on boolean complex expressions" do
|
333
|
+
proc{:x > (:y > 5)}.should raise_error(Sequel::Error)
|
334
|
+
proc{:x < (:y < 5)}.should raise_error(Sequel::Error)
|
335
|
+
proc{:x >= (:y >= 5)}.should raise_error(Sequel::Error)
|
336
|
+
proc{:x <= (:y <= 5)}.should raise_error(Sequel::Error)
|
337
|
+
proc{:x > {:y => nil}}.should raise_error(Sequel::Error)
|
338
|
+
proc{:x < ~{:y => nil}}.should raise_error(Sequel::Error)
|
339
|
+
proc{:x >= {:y => 5}}.should raise_error(Sequel::Error)
|
340
|
+
proc{:x <= ~{:y => 5}}.should raise_error(Sequel::Error)
|
341
|
+
proc{:x >= {:y => [1,2,3]}}.should raise_error(Sequel::Error)
|
342
|
+
proc{:x <= ~{:y => [1,2,3]}}.should raise_error(Sequel::Error)
|
343
|
+
end
|
344
|
+
|
345
|
+
it "should support >, <, >=, and <= via Symbol#>,<,>=,<=" do
|
346
|
+
@d.l(:x > 100).should == '(x > 100)'
|
347
|
+
@d.l(:x < 100.01).should == '(x < 100.01)'
|
348
|
+
@d.l(:x >= 100000000000000000000000000000000000).should == '(x >= 100000000000000000000000000000000000)'
|
349
|
+
@d.l(:x <= 100).should == '(x <= 100)'
|
350
|
+
end
|
351
|
+
|
352
|
+
it "should support negation of >, <, >=, and <= via Symbol#~" do
|
353
|
+
@d.l(~(:x > 100)).should == '(x <= 100)'
|
354
|
+
@d.l(~(:x < 100.01)).should == '(x >= 100.01)'
|
355
|
+
@d.l(~(:x >= 100000000000000000000000000000000000)).should == '(x < 100000000000000000000000000000000000)'
|
356
|
+
@d.l(~(:x <= 100)).should == '(x > 100)'
|
357
|
+
end
|
358
|
+
|
359
|
+
it "should support double negation via ~" do
|
360
|
+
@d.l(~~(:x > 100)).should == '(x > 100)'
|
361
|
+
end
|
362
|
+
end
|
352
363
|
end
|