sequel 2.9.0 → 2.10.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 +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
|