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.
Files changed (78) hide show
  1. data/CHANGELOG +56 -0
  2. data/{README → README.rdoc} +85 -57
  3. data/Rakefile +10 -5
  4. data/bin/sequel +7 -16
  5. data/doc/advanced_associations.rdoc +5 -17
  6. data/doc/cheat_sheet.rdoc +18 -20
  7. data/doc/dataset_filtering.rdoc +8 -32
  8. data/doc/schema.rdoc +20 -0
  9. data/lib/sequel_core.rb +35 -1
  10. data/lib/sequel_core/adapters/ado.rb +1 -1
  11. data/lib/sequel_core/adapters/db2.rb +2 -2
  12. data/lib/sequel_core/adapters/dbi.rb +2 -11
  13. data/lib/sequel_core/adapters/do.rb +205 -0
  14. data/lib/sequel_core/adapters/do/mysql.rb +38 -0
  15. data/lib/sequel_core/adapters/do/postgres.rb +92 -0
  16. data/lib/sequel_core/adapters/do/sqlite.rb +31 -0
  17. data/lib/sequel_core/adapters/firebird.rb +298 -0
  18. data/lib/sequel_core/adapters/informix.rb +10 -1
  19. data/lib/sequel_core/adapters/jdbc.rb +78 -19
  20. data/lib/sequel_core/adapters/jdbc/h2.rb +69 -0
  21. data/lib/sequel_core/adapters/jdbc/mysql.rb +10 -0
  22. data/lib/sequel_core/adapters/jdbc/postgresql.rb +7 -3
  23. data/lib/sequel_core/adapters/mysql.rb +53 -77
  24. data/lib/sequel_core/adapters/odbc.rb +1 -1
  25. data/lib/sequel_core/adapters/openbase.rb +1 -1
  26. data/lib/sequel_core/adapters/oracle.rb +2 -2
  27. data/lib/sequel_core/adapters/postgres.rb +16 -14
  28. data/lib/sequel_core/adapters/shared/mysql.rb +44 -9
  29. data/lib/sequel_core/adapters/shared/oracle.rb +4 -5
  30. data/lib/sequel_core/adapters/shared/postgres.rb +86 -82
  31. data/lib/sequel_core/adapters/shared/sqlite.rb +39 -24
  32. data/lib/sequel_core/adapters/sqlite.rb +11 -1
  33. data/lib/sequel_core/connection_pool.rb +10 -2
  34. data/lib/sequel_core/core_sql.rb +13 -3
  35. data/lib/sequel_core/database.rb +131 -30
  36. data/lib/sequel_core/database/schema.rb +5 -5
  37. data/lib/sequel_core/dataset.rb +31 -6
  38. data/lib/sequel_core/dataset/convenience.rb +11 -11
  39. data/lib/sequel_core/dataset/query.rb +2 -2
  40. data/lib/sequel_core/dataset/sql.rb +6 -6
  41. data/lib/sequel_core/exceptions.rb +4 -0
  42. data/lib/sequel_core/migration.rb +4 -4
  43. data/lib/sequel_core/schema/generator.rb +19 -3
  44. data/lib/sequel_core/schema/sql.rb +24 -20
  45. data/lib/sequel_core/sql.rb +13 -16
  46. data/lib/sequel_core/version.rb +11 -0
  47. data/lib/sequel_model.rb +2 -0
  48. data/lib/sequel_model/base.rb +2 -2
  49. data/lib/sequel_model/hooks.rb +46 -7
  50. data/lib/sequel_model/record.rb +11 -9
  51. data/lib/sequel_model/schema.rb +1 -1
  52. data/lib/sequel_model/validations.rb +72 -61
  53. data/spec/adapters/firebird_spec.rb +371 -0
  54. data/spec/adapters/mysql_spec.rb +118 -62
  55. data/spec/adapters/oracle_spec.rb +5 -5
  56. data/spec/adapters/postgres_spec.rb +33 -18
  57. data/spec/adapters/sqlite_spec.rb +2 -2
  58. data/spec/integration/dataset_test.rb +3 -3
  59. data/spec/integration/schema_test.rb +55 -5
  60. data/spec/integration/spec_helper.rb +11 -0
  61. data/spec/integration/type_test.rb +59 -16
  62. data/spec/sequel_core/connection_pool_spec.rb +14 -0
  63. data/spec/sequel_core/core_sql_spec.rb +24 -14
  64. data/spec/sequel_core/database_spec.rb +96 -11
  65. data/spec/sequel_core/dataset_spec.rb +97 -37
  66. data/spec/sequel_core/expression_filters_spec.rb +51 -40
  67. data/spec/sequel_core/object_graph_spec.rb +2 -2
  68. data/spec/sequel_core/schema_generator_spec.rb +31 -6
  69. data/spec/sequel_core/schema_spec.rb +25 -9
  70. data/spec/sequel_core/spec_helper.rb +4 -1
  71. data/spec/sequel_core/version_spec.rb +7 -0
  72. data/spec/sequel_model/associations_spec.rb +1 -1
  73. data/spec/sequel_model/hooks_spec.rb +68 -13
  74. data/spec/sequel_model/model_spec.rb +4 -4
  75. data/spec/sequel_model/record_spec.rb +22 -0
  76. data/spec/sequel_model/spec_helper.rb +2 -1
  77. data/spec/sequel_model/validations_spec.rb +107 -7
  78. 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[:gdp])).sql.should ==
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[:gdp])
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[:population], :avg[:gdp])
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[:population] > 10}.sql.should ==
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[:def]).select_sql.should ==
805
+ @dataset.from(:abc.sql_function(:def)).select_sql.should ==
746
806
  "SELECT * FROM abc(def)"
747
807
 
748
- @dataset.from(:a[:i]).select_sql.should ==
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[:t], :x___y).sql.should == "SELECT NULL, sum(t), x AS y FROM test"
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[]).should == 'NOT is_blah()'
31
- @d.l(~:is_blah[:x]).should == 'NOT is_blah(x)'
32
- @d.l(~:is_blah[:x__y]).should == 'NOT is_blah(x.y)'
33
- @d.l(~:is_blah[:x, :x__y]).should == 'NOT is_blah(x, x.y)'
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, inequality, or string operations on true, false, or nil" do
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, inequality, or string operations on boolean complex expressions" do
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 > 200) & (:y < 200)).should == '((x > 200) AND (y < 200))'
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[1], :y|1].sql_string_join).should == '(x(1) || y[1])'
282
- @d.lit([:x[1], 'y.z'.lit].sql_string_join(', ')).should == "(x(1) || ', ' || y.z)"
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