arel_extensions 1.6.0 → 2.0.0.rc3

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 (146) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +2 -1
  3. data/.gitignore +6 -7
  4. data/.rubocop.yml +3 -67
  5. data/.travis/oracle/download.js +152 -0
  6. data/.travis/oracle/download.sh +30 -0
  7. data/.travis/oracle/download_ojdbc.js +116 -0
  8. data/.travis/oracle/install.sh +34 -0
  9. data/.travis/setup_accounts.sh +9 -0
  10. data/.travis/sqlite3/extension-functions.sh +6 -0
  11. data/.travis.yml +223 -0
  12. data/Gemfile +28 -2
  13. data/README.md +91 -258
  14. data/Rakefile +30 -48
  15. data/TODO +1 -0
  16. data/appveyor.yml +22 -60
  17. data/arel_extensions.gemspec +14 -13
  18. data/functions.html +3 -3
  19. data/gemfiles/rails3.gemfile +20 -0
  20. data/gemfiles/rails4.gemfile +29 -0
  21. data/gemfiles/rails5_0.gemfile +29 -0
  22. data/gemfiles/rails5_1_4.gemfile +14 -14
  23. data/gemfiles/rails5_2.gemfile +14 -16
  24. data/init/mssql.sql +4 -4
  25. data/init/mysql.sql +38 -38
  26. data/init/oracle.sql +0 -0
  27. data/init/postgresql.sql +25 -24
  28. data/init/sqlite.sql +0 -0
  29. data/lib/arel_extensions/attributes.rb +3 -7
  30. data/lib/arel_extensions/boolean_functions.rb +14 -53
  31. data/lib/arel_extensions/common_sql_functions.rb +17 -16
  32. data/lib/arel_extensions/comparators.rb +28 -29
  33. data/lib/arel_extensions/date_duration.rb +13 -17
  34. data/lib/arel_extensions/insert_manager.rb +15 -18
  35. data/lib/arel_extensions/math.rb +53 -55
  36. data/lib/arel_extensions/math_functions.rb +39 -46
  37. data/lib/arel_extensions/nodes/abs.rb +1 -0
  38. data/lib/arel_extensions/nodes/blank.rb +2 -1
  39. data/lib/arel_extensions/nodes/case.rb +19 -20
  40. data/lib/arel_extensions/nodes/cast.rb +8 -10
  41. data/lib/arel_extensions/nodes/ceil.rb +1 -1
  42. data/lib/arel_extensions/nodes/coalesce.rb +4 -3
  43. data/lib/arel_extensions/nodes/collate.rb +10 -9
  44. data/lib/arel_extensions/nodes/concat.rb +18 -9
  45. data/lib/arel_extensions/nodes/date_diff.rb +26 -42
  46. data/lib/arel_extensions/nodes/duration.rb +3 -0
  47. data/lib/arel_extensions/nodes/find_in_set.rb +1 -0
  48. data/lib/arel_extensions/nodes/floor.rb +1 -1
  49. data/lib/arel_extensions/nodes/format.rb +8 -35
  50. data/lib/arel_extensions/nodes/formatted_number.rb +23 -22
  51. data/lib/arel_extensions/nodes/function.rb +37 -46
  52. data/lib/arel_extensions/nodes/is_null.rb +0 -0
  53. data/lib/arel_extensions/nodes/json.rb +39 -52
  54. data/lib/arel_extensions/nodes/length.rb +0 -5
  55. data/lib/arel_extensions/nodes/levenshtein_distance.rb +1 -1
  56. data/lib/arel_extensions/nodes/locate.rb +2 -1
  57. data/lib/arel_extensions/nodes/log10.rb +2 -1
  58. data/lib/arel_extensions/nodes/matches.rb +8 -6
  59. data/lib/arel_extensions/nodes/md5.rb +1 -0
  60. data/lib/arel_extensions/nodes/power.rb +5 -5
  61. data/lib/arel_extensions/nodes/rand.rb +1 -0
  62. data/lib/arel_extensions/nodes/repeat.rb +5 -3
  63. data/lib/arel_extensions/nodes/replace.rb +8 -16
  64. data/lib/arel_extensions/nodes/round.rb +6 -5
  65. data/lib/arel_extensions/nodes/soundex.rb +15 -15
  66. data/lib/arel_extensions/nodes/std.rb +21 -18
  67. data/lib/arel_extensions/nodes/substring.rb +16 -8
  68. data/lib/arel_extensions/nodes/then.rb +1 -1
  69. data/lib/arel_extensions/nodes/trim.rb +6 -4
  70. data/lib/arel_extensions/nodes/union.rb +8 -5
  71. data/lib/arel_extensions/nodes/union_all.rb +7 -4
  72. data/lib/arel_extensions/nodes/wday.rb +4 -0
  73. data/lib/arel_extensions/nodes.rb +1 -1
  74. data/lib/arel_extensions/null_functions.rb +5 -19
  75. data/lib/arel_extensions/predications.rb +44 -45
  76. data/lib/arel_extensions/railtie.rb +5 -5
  77. data/lib/arel_extensions/set_functions.rb +7 -5
  78. data/lib/arel_extensions/string_functions.rb +35 -91
  79. data/lib/arel_extensions/tasks.rb +6 -6
  80. data/lib/arel_extensions/version.rb +1 -1
  81. data/lib/arel_extensions/visitors/ibm_db.rb +31 -24
  82. data/lib/arel_extensions/visitors/mssql.rb +194 -440
  83. data/lib/arel_extensions/visitors/mysql.rb +212 -368
  84. data/lib/arel_extensions/visitors/oracle.rb +179 -236
  85. data/lib/arel_extensions/visitors/oracle12.rb +31 -18
  86. data/lib/arel_extensions/visitors/postgresql.rb +173 -271
  87. data/lib/arel_extensions/visitors/sqlite.rb +127 -157
  88. data/lib/arel_extensions/visitors/to_sql.rb +238 -300
  89. data/lib/arel_extensions/visitors.rb +62 -83
  90. data/lib/arel_extensions.rb +31 -235
  91. data/test/database.yml +10 -20
  92. data/test/helper.rb +18 -0
  93. data/test/real_db_test.rb +118 -121
  94. data/test/support/fake_record.rb +3 -11
  95. data/test/test_comparators.rb +17 -14
  96. data/test/visitors/test_bulk_insert_oracle.rb +12 -12
  97. data/test/visitors/test_bulk_insert_sqlite.rb +14 -13
  98. data/test/visitors/test_bulk_insert_to_sql.rb +13 -11
  99. data/test/visitors/test_oracle.rb +55 -55
  100. data/test/visitors/test_to_sql.rb +226 -419
  101. data/test/with_ar/all_agnostic_test.rb +370 -773
  102. data/test/with_ar/insert_agnostic_test.rb +22 -28
  103. data/test/with_ar/test_bulk_sqlite.rb +17 -18
  104. data/test/with_ar/test_math_sqlite.rb +27 -27
  105. data/test/with_ar/test_string_mysql.rb +34 -32
  106. data/test/with_ar/test_string_sqlite.rb +35 -31
  107. metadata +38 -52
  108. data/.github/workflows/publish.yml +0 -30
  109. data/.github/workflows/release.yml +0 -30
  110. data/.github/workflows/ruby.yml +0 -452
  111. data/CONTRIBUTING.md +0 -102
  112. data/Makefile +0 -18
  113. data/NEWS.md +0 -116
  114. data/bin/build +0 -15
  115. data/bin/publish +0 -8
  116. data/dev/arelx.dockerfile +0 -41
  117. data/dev/compose.yaml +0 -69
  118. data/dev/postgres.dockerfile +0 -5
  119. data/dev/rbenv +0 -189
  120. data/gemfiles/rails5.gemfile +0 -29
  121. data/gemfiles/rails6.gemfile +0 -34
  122. data/gemfiles/rails6_1.gemfile +0 -42
  123. data/gemfiles/rails7.gemfile +0 -42
  124. data/gemfiles/rails7_1.gemfile +0 -41
  125. data/gemfiles/rails7_2.gemfile +0 -41
  126. data/gemfiles/rails8.gemfile +0 -40
  127. data/gemfiles/rails8_1.gemfile +0 -41
  128. data/gemspecs/arel_extensions-v1.gemspec +0 -27
  129. data/gemspecs/arel_extensions-v2.gemspec +0 -27
  130. data/generate_gems.sh +0 -15
  131. data/lib/arel_extensions/aliases.rb +0 -14
  132. data/lib/arel_extensions/constants.rb +0 -13
  133. data/lib/arel_extensions/helpers.rb +0 -61
  134. data/lib/arel_extensions/nodes/aggregate_function.rb +0 -13
  135. data/lib/arel_extensions/nodes/byte_size.rb +0 -11
  136. data/lib/arel_extensions/nodes/char_length.rb +0 -11
  137. data/lib/arel_extensions/nodes/formatted_date.rb +0 -42
  138. data/lib/arel_extensions/nodes/rollup.rb +0 -36
  139. data/lib/arel_extensions/nodes/select.rb +0 -10
  140. data/lib/arel_extensions/nodes/sum.rb +0 -7
  141. data/lib/arel_extensions/visitors/convert_format.rb +0 -37
  142. data/lib/arel_extensions/warning.rb +0 -42
  143. data/test/arelx_test_helper.rb +0 -94
  144. data/test/config_loader.rb +0 -9
  145. data/version_v1.rb +0 -3
  146. data/version_v2.rb +0 -3
@@ -1,31 +1,10 @@
1
- require 'arelx_test_helper'
1
+ require 'helper'
2
2
  require 'set'
3
3
 
4
4
  module ArelExtensions
5
5
  module VisitorToSql
6
6
  describe 'the to_sql visitor' do
7
7
  before do
8
- if Arel::Table.engine.is_a?(ActiveRecord::Base)
9
- puts 'This is a hack.'
10
- # As a matter of fact, if the whole if-block is removed, the to_sql
11
- # test become flaky.
12
- #
13
- # The first time `Arel::Table.engine` is called
14
- # from `ArelExtensions.column_of_via_arel_table(table_name, column_name)`
15
- # in `lib/arel_extensions/helpers.rb`
16
- # will almost always fail. It's important to note that when the test
17
- # fails, it's always on 1 test case, and every subsequent test that
18
- # calls to these methods passes.
19
- #
20
- # After investigation, it turned out that `Arel::Table.engine` will be
21
- # of type `ActiveRecord::Base` instead of the expected `FakeRecord::Base`
22
- # as set in this `before` block, in the `@conn` instance variable.
23
- # Subsequent calls to `column_of_via_arel_table` will have
24
- # `Arel::Table.engine` of the expected type.
25
- #
26
- # It is still unclear why the call in the condition of this if-block
27
- # fixes this behavior.
28
- end
29
8
  @conn = FakeRecord::Base.new
30
9
  Arel::Table.engine = @conn
31
10
  @visitor = Arel::Visitors::ToSql.new @conn.connection
@@ -43,540 +22,368 @@ module ArelExtensions
43
22
  end
44
23
  end
45
24
 
46
- describe 'primitive methods' do
47
- it 'should be able to recognize equal nodes' do
48
- c = @table[:id]
49
- _(c == 1).must_be :eql?, (c == 1)
50
- _((c == 1).right.hash).must_equal (c == 1).right.hash
51
- _((c == 1).hash).must_equal (c == 1).hash
52
-
53
- _([c == 1, c == 1].uniq).must_equal [c == 1]
54
- end
55
- end
56
-
57
25
  # Math Functions
58
- it 'should not break Arel functions' do
59
- _(compile(@price + 42)).must_be_like %{("products"."price" + 42)}
60
- _(compile(@table[:id] + @table[:pas_en_base]))
26
+ it "should not break Arel functions" do
27
+ compile(@price + 42).must_be_like %{("products"."price" + 42)}
28
+ compile(@table[:id] + @table[:pas_en_base])
61
29
  .must_be_like %{("users"."id" + "users"."pas_en_base")}
62
- _(compile(@table[:pas_en_base] + @table[:id]))
30
+ compile(@table[:pas_en_base] + @table[:id])
63
31
  .must_be_like %{("users"."pas_en_base" + "users"."id")}
64
- _(compile(@table[:id] - @table[:pas_en_base]))
32
+ compile(@table[:id] - @table[:pas_en_base])
65
33
  .must_be_like %{("users"."id" - "users"."pas_en_base")}
66
- _(compile(@table[:pas_en_base] - @table[:id]))
34
+ compile(@table[:pas_en_base] - @table[:id])
67
35
  .must_be_like %{("users"."pas_en_base" - "users"."id")}
68
- _(compile(@table[:id] * @table[:pas_en_base]))
36
+ compile(@table[:id] * @table[:pas_en_base])
69
37
  .must_be_like %{"users"."id" * "users"."pas_en_base"}
70
- _(compile(@table[:pas_en_base] * @table[:id]))
38
+ compile(@table[:pas_en_base] * @table[:id])
71
39
  .must_be_like %{"users"."pas_en_base" * "users"."id"}
72
40
  end
73
41
 
74
- it 'should return right calculations on numbers' do
75
- # puts (@price.abs + 42).inspect
76
- _(compile(@price.abs + 42)).must_be_like %{(ABS("products"."price") + 42)}
77
- _(compile(@price.ceil + 42)).must_be_like %{(CEIL("products"."price") + 42)}
78
- _(compile(@price.floor + 42)).must_be_like %{(FLOOR("products"."price") + 42)}
79
- _(compile(@price.log10 + 42)).must_be_like %{(LOG10("products"."price") + 42)}
80
- _(compile(@price.power(42) + 42)).must_be_like %{(POW("products"."price", 42) + 42)}
81
- _(compile(@price.pow(42) + 42)).must_be_like %{(POW("products"."price", 42) + 42)}
82
- _(compile(@price.ceil + @price.floor)).must_be_like %{(CEIL("products"."price") + FLOOR("products"."price"))}
83
- _(compile((@price.ceil + @price.floor).abs)).must_be_like %{ABS((CEIL("products"."price") + FLOOR("products"."price")))}
84
- _(compile(@price.round + 42)).must_be_like %{(ROUND("products"."price") + 42)}
85
- _(compile(@price.round(2) + 42)).must_be_like %{(ROUND("products"."price", 2) + 42)}
86
- _(compile(Arel.rand + 42)).must_be_like %{(RAND() + 42)}
87
- _(compile(@price.sum + 42)).must_be_like %{(SUM("products"."price") + 42)}
88
- _(compile((@price + 42).sum)).must_be_like %{SUM(("products"."price" + 42))}
89
- _(compile((@price + 42).average)).must_be_like %{AVG(("products"."price" + 42))}
90
- _(compile((Arel.rand * 9).round + 42)).must_be_like %{(ROUND(RAND() * 9) + 42)}
91
- _(compile((Arel.rand * @price).round(2) + @price)).must_be_like %{(ROUND(RAND() * "products"."price", 2) + "products"."price")}
92
-
93
- _(compile(@price.std + 42)).must_be_like %{(STD("products"."price") + 42)}
94
- _(compile(@price.variance + 42)).must_be_like %{(VARIANCE("products"."price") + 42)}
95
-
96
- _(compile(@price.coalesce(0) - 42)).must_be_like %{(COALESCE("products"."price", 0) - 42)}
97
- _(compile(@price.sum - 42)).must_be_like %{(SUM("products"."price") - 42)}
98
- _(compile(@price.std - 42)).must_be_like %{(STD("products"."price") - 42)}
99
- _(compile(@price.variance - 42)).must_be_like %{(VARIANCE("products"."price") - 42)}
100
-
101
- _(compile(@price * 42.0)).must_be_like %{"products"."price" * 42.0}
102
- _(compile(@price / 42.0)).must_be_like %{"products"."price" / 42.0}
42
+ it "should return right calculations on numbers" do
43
+ #puts (@price.abs + 42).inspect
44
+ compile(@price.abs + 42).must_be_like %{(ABS("products"."price") + 42)}
45
+ compile(@price.ceil + 42).must_be_like %{(CEIL("products"."price") + 42)}
46
+ compile(@price.floor + 42).must_be_like %{(FLOOR("products"."price") + 42)}
47
+ compile(@price.log10 + 42).must_be_like %{(LOG10("products"."price") + 42)}
48
+ compile(@price.power(42) + 42).must_be_like %{(POW("products"."price", 42) + 42)}
49
+ compile(@price.pow(42) + 42).must_be_like %{(POW("products"."price", 42) + 42)}
50
+ compile(@price.ceil + @price.floor).must_be_like %{(CEIL("products"."price") + FLOOR("products"."price"))}
51
+ compile((@price.ceil + @price.floor).abs).must_be_like %{ABS((CEIL("products"."price") + FLOOR("products"."price")))}
52
+ compile(@price.round + 42).must_be_like %{(ROUND("products"."price") + 42)}
53
+ compile(@price.round(2) + 42).must_be_like %{(ROUND("products"."price", 2) + 42)}
54
+ compile(Arel.rand + 42).must_be_like %{(RAND() + 42)}
55
+ compile(@price.sum + 42).must_be_like %{(SUM("products"."price") + 42)}
56
+ compile((@price + 42).sum).must_be_like %{SUM(("products"."price" + 42))}
57
+ compile((@price + 42).average).must_be_like %{AVG(("products"."price" + 42))}
58
+ compile((Arel.rand * 9).round + 42).must_be_like %{(ROUND(RAND() * 9) + 42)}
59
+ compile((Arel.rand * @price).round(2) + @price).must_be_like %{(ROUND(RAND() * "products"."price", 2) + "products"."price")}
60
+
61
+ compile(@price.std + 42).must_be_like %{(STD("products"."price") + 42)}
62
+ compile(@price.variance + 42).must_be_like %{(VARIANCE("products"."price") + 42)}
63
+
64
+ compile(@price.coalesce(0) - 42).must_be_like %{(COALESCE("products"."price", 0) - 42)}
65
+ compile(@price.sum - 42).must_be_like %{(SUM("products"."price") - 42)}
66
+ compile(@price.std - 42).must_be_like %{(STD("products"."price") - 42)}
67
+ compile(@price.variance - 42).must_be_like %{(VARIANCE("products"."price") - 42)}
68
+
69
+ compile(@price * 42.0).must_be_like %{"products"."price" * 42.0}
70
+ compile(@price / 42.0).must_be_like %{"products"."price" / 42.0}
103
71
 
104
72
  fake_table = Arel::Table.new('fake_tables')
105
73
 
106
- _(compile(fake_table[:fake_att] - 42)).must_be_like %{("fake_tables"."fake_att" - 42)}
107
- _(compile(fake_table[:fake_att].coalesce(0) - 42)).must_be_like %{(COALESCE("fake_tables"."fake_att", 0) - 42)}
74
+ compile(fake_table[:fake_att] - 42).must_be_like %{("fake_tables"."fake_att" - 42)}
75
+ compile(fake_table[:fake_att].coalesce(0) - 42).must_be_like %{(COALESCE("fake_tables"."fake_att", 0) - 42)}
108
76
  end
109
77
 
110
78
  # String Functions
111
- it 'should accept functions on strings' do
79
+ it "should accept functions on strings" do
112
80
  c = @table[:name]
113
- _(compile(c + 'test')).must_be_like %{CONCAT(\"users\".\"name\", 'test')}
114
- _(compile(c.length)).must_be_like %{LENGTH("users"."name")}
115
- # puts (c.length.round + 42).inspect
116
- _(compile(c.length.round + 42)).must_be_like %{(ROUND(LENGTH("users"."name")) + 42)}
117
- _(compile(c.locate('test'))).must_be_like %{LOCATE('test', "users"."name")}
118
- _(compile(c & 42)).must_be_like %{FIND_IN_SET('42', "users"."name")}
119
-
120
- _(compile((c >= 'test').as('new_name'))).must_be_like %{("users"."name" >= 'test') AS new_name}
121
- _(compile(c <= @table[:comments])).must_be_like %{"users"."name" <= "users"."comments"}
122
- _(compile(c =~ /\Atest\Z/)).must_be_like %{"users"."name" REGEXP '^test$'}
123
- _(compile(c =~ /\Atest\z/)).must_be_like %{"users"."name" REGEXP '^test$'}
124
- _(compile(c !~ /\Ate\Dst\Z/)).must_be_like %{"users"."name" NOT REGEXP '^te[^0-9]st$'}
125
- _(compile(c.imatches('%test%'))).must_be_like %{"users"."name" ILIKE '%test%'}
126
- _(compile(c.imatches_any(['%test%', 't2']))).must_be_like %{(("users"."name" ILIKE '%test%') OR ("users"."name" ILIKE 't2'))}
127
- _(compile(c.idoes_not_match('%test%'))).must_be_like %{"users"."name" NOT ILIKE '%test%'}
128
-
129
- _(compile(c.substring(1))).must_be_like %{SUBSTRING("users"."name", 1)}
130
- _(compile(c + '0')).must_be_like %{CONCAT("users"."name", '0')}
131
- _(compile(c.substring(1) + '0')).must_be_like %{CONCAT(SUBSTRING("users"."name", 1), '0')}
132
- _(compile(c.substring(1) + c.substring(2))).must_be_like %{CONCAT(SUBSTRING("users"."name", 1), SUBSTRING("users"."name", 2))}
133
- _(compile(c.concat(c).concat(c))).must_be_like %{CONCAT("users"."name", "users"."name", "users"."name")}
134
- _(compile(c + c + c)).must_be_like %{CONCAT("users"."name", "users"."name", "users"."name")}
81
+ compile(c + 'test').must_be_like %{CONCAT(\"users\".\"name\", 'test')}
82
+ compile(c.length).must_be_like %{LENGTH("users"."name")}
83
+ #puts (c.length.round + 42).inspect
84
+ compile(c.length.round + 42).must_be_like %{(ROUND(LENGTH("users"."name")) + 42)}
85
+ compile(c.locate('test')).must_be_like %{LOCATE('test', "users"."name")}
86
+ compile(c & 42).must_be_like %{FIND_IN_SET(42, "users"."name")}
87
+
88
+ compile((c >= 'test').as('new_name')).must_be_like %{("users"."name" >= 'test') AS new_name}
89
+ compile(c <= @table[:comments]).must_be_like %{"users"."name" <= "users"."comments"}
90
+ compile(c =~ /\Atest\Z/).must_be_like %{"users"."name" REGEXP '^test$'}
91
+ compile(c !~ /\Ate\Dst\Z/).must_be_like %{"users"."name" NOT REGEXP '^te[^0-9]st$'}
92
+ compile(c.imatches('%test%')).must_be_like %{"users"."name" ILIKE '%test%'}
93
+ compile(c.imatches_any(['%test%', 't2'])).must_be_like %{(("users"."name" ILIKE '%test%') OR ("users"."name" ILIKE 't2'))}
94
+ compile(c.idoes_not_match('%test%')).must_be_like %{"users"."name" NOT ILIKE '%test%'}
95
+
96
+ compile(c.substring(1)).must_be_like %{SUBSTRING("users"."name", 1)}
97
+ compile(c + '0').must_be_like %{CONCAT("users"."name", '0')}
98
+ compile(c.substring(1) + '0').must_be_like %{CONCAT(SUBSTRING("users"."name", 1), '0')}
99
+ compile(c.substring(1) + c.substring(2)).must_be_like %{CONCAT(SUBSTRING("users"."name", 1), SUBSTRING("users"."name", 2))}
100
+ compile(c.concat(c).concat(c)).must_be_like %{CONCAT("users"."name", "users"."name", "users"."name")}
101
+ compile(c + c + c).must_be_like %{CONCAT("users"."name", "users"."name", "users"."name")}
135
102
 
136
103
  # some optimization on concat
137
- _(compile(c + 'test' + ' chain')).must_be_like %{CONCAT(\"users\".\"name\", 'test chain')}
138
- _(compile(Arel.quoted('test') + ' chain')).must_be_like %{'test chain'}
139
- _(compile(c + '' + c)).must_be_like %{CONCAT(\"users\".\"name\", \"users\".\"name\")}
104
+ compile(c + 'test' + ' chain').must_be_like %{CONCAT(\"users\".\"name\", 'test chain')}
105
+ compile(Arel::Nodes.build_quoted('test') + ' chain').must_be_like %{'test chain'}
106
+ compile(c + '' + c).must_be_like %{CONCAT(\"users\".\"name\", \"users\".\"name\")}
140
107
 
141
- _(compile(c.md5)).must_be_like %{MD5(\"users\".\"name\")}
108
+ compile(c.md5).must_be_like %{MD5(\"users\".\"name\")}
142
109
  end
143
110
 
144
111
  # Comparators
145
112
 
146
- it 'should accept comparators on integers' do
147
- _(compile(@table[:id] == 42)).must_match %{"users"."id" = 42}
148
- _(compile(@table[:id] == @table[:id])).must_be_like %{"users"."id" = "users"."id"}
149
- _(compile(@table[:id] != 42)).must_match %{"users"."id" != 42}
150
- _(compile(@table[:id] > 42)).must_match %{"users"."id" > 42}
151
- _(compile(@table[:id] >= 42)).must_match %{"users"."id" >= 42}
152
- _(compile(@table[:id] >= @table[:id])).must_be_like %{"users"."id" >= "users"."id"}
153
- _(compile(@table[:id] < 42)).must_match %{"users"."id" < 42}
154
- _(compile(@table[:id] <= 42)).must_match %{"users"."id" <= 42}
155
- _(compile((@table[:id] <= 42).as('new_name'))).must_match %{("users"."id" <= 42) AS new_name}
156
- _(compile(@table[:id].count.eq 42)).must_match %{COUNT("users"."id") = 42}
157
- # _(compile(@table[:id].count == 42)).must_match %{COUNT("users"."id") = 42} # TODO
158
- # _(compile(@table[:id].count != 42)).must_match %{COUNT("users"."id") != 42}
159
- # _(compile(@table[:id].count >= 42)).must_match %{COUNT("users"."id") >= 42}
113
+ it "should accept comparators on integers" do
114
+ compile(@table[:id] == 42).must_match %{"users"."id" = 42}
115
+ compile(@table[:id] == @table[:id]).must_be_like %{"users"."id" = "users"."id"}
116
+ compile(@table[:id] != 42).must_match %{"users"."id" != 42}
117
+ compile(@table[:id] > 42).must_match %{"users"."id" > 42}
118
+ compile(@table[:id] >= 42).must_match %{"users"."id" >= 42}
119
+ compile(@table[:id] >= @table[:id]).must_be_like %{"users"."id" >= "users"."id"}
120
+ compile(@table[:id] < 42).must_match %{"users"."id" < 42}
121
+ compile(@table[:id] <= 42).must_match %{"users"."id" <= 42}
122
+ compile((@table[:id] <= 42).as('new_name')).must_match %{("users"."id" <= 42) AS new_name}
160
123
  end
161
124
 
162
- it 'should accept comparators on dates' do
125
+ it "should accept comparators on dates" do
163
126
  c = @table[:created_at]
164
127
  u = @table[:updated_at]
165
- _(compile(c > @date)).must_be_like %{"users"."created_at" > '2016-03-31'}
166
- _(compile(u >= @date)).must_be_like %{"users"."updated_at" >= '2016-03-31'}
167
- _(compile(c < u)).must_be_like %{"users"."created_at" < "users"."updated_at"}
128
+ compile(c > @date).must_be_like %{"users"."created_at" > '2016-03-31'}
129
+ compile(u >= @date).must_be_like %{"users"."updated_at" >= '2016-03-31'}
130
+ compile(c < u).must_be_like %{"users"."created_at" < "users"."updated_at"}
168
131
  end
169
132
 
170
- it 'should accept comparators on strings' do
133
+ it "should accept comparators on strings" do
171
134
  c = @table[:name]
172
- _(compile(c == 'test')).must_be_like %{"users"."name" = 'test'}
173
- _(compile(c != 'test')).must_be_like %{"users"."name" != 'test'}
174
- _(compile(c > 'test')).must_be_like %{"users"."name" > 'test'}
175
- _(compile((c >= 'test').as('new_name'))).must_be_like %{("users"."name" >= 'test') AS new_name}
176
- _(compile(c <= @table[:comments])).must_be_like %{"users"."name" <= "users"."comments"}
177
- _(compile(c =~ /\Atest\Z/)).must_be_like %{"users"."name" REGEXP '^test$'}
178
- _(compile(c !~ /\Ate\Dst\Z/)).must_be_like %{"users"."name" NOT REGEXP '^te[^0-9]st$'}
179
- _(compile(c.imatches('%test%'))).must_be_like %{"users"."name" ILIKE '%test%'}
180
- _(compile(c.imatches_any(['%test%', 't2']))).must_be_like %{(("users"."name" ILIKE '%test%') OR ("users"."name" ILIKE 't2'))}
181
- _(compile(c.idoes_not_match('%test%'))).must_be_like %{"users"."name" NOT ILIKE '%test%'}
135
+ compile(c == 'test').must_be_like %{"users"."name" = 'test'}
136
+ compile(c != 'test').must_be_like %{"users"."name" != 'test'}
137
+ compile(c > 'test').must_be_like %{"users"."name" > 'test'}
138
+ compile((c >= 'test').as('new_name')).must_be_like %{("users"."name" >= 'test') AS new_name}
139
+ compile(c <= @table[:comments]).must_be_like %{"users"."name" <= "users"."comments"}
140
+ compile(c =~ /\Atest\Z/).must_be_like %{"users"."name" REGEXP '^test$'}
141
+ compile(c !~ /\Ate\Dst\Z/).must_be_like %{"users"."name" NOT REGEXP '^te[^0-9]st$'}
142
+ compile(c.imatches('%test%')).must_be_like %{"users"."name" ILIKE '%test%'}
143
+ compile(c.imatches_any(['%test%', 't2'])).must_be_like %{(("users"."name" ILIKE '%test%') OR ("users"."name" ILIKE 't2'))}
144
+ compile(c.idoes_not_match('%test%')).must_be_like %{"users"."name" NOT ILIKE '%test%'}
182
145
  end
183
146
 
184
147
  # Maths
185
148
  # DateDiff
186
- it 'should diff date col and date' do
187
- _(compile(@table[:created_at] - Date.new(2016, 3, 31))).must_match %{DATEDIFF("users"."created_at", '2016-03-31')}
149
+ it "should diff date col and date" do
150
+ compile(@table[:created_at] - Date.new(2016, 3, 31)).must_match %{DATEDIFF("users"."created_at", '2016-03-31')}
188
151
  end
189
152
 
190
- it 'should diff date col and datetime col' do
191
- _(compile(@table[:created_at] - @table[:updated_at])).must_match %{DATEDIFF("users"."created_at", "users"."updated_at")}
153
+ it "should diff date col and datetime col" do
154
+ compile(@table[:created_at] - @table[:updated_at]).must_match %{DATEDIFF("users"."created_at", "users"."updated_at")}
192
155
  end
193
156
 
194
- it 'should diff date col and datetime col with AS' do
195
- _(compile((@table[:updated_at] - @table[:created_at]).as('new_name')))
196
- .must_match %{TIMEDIFF("users"."updated_at", "users"."created_at") AS new_name}
157
+ it "should diff date col and datetime col with AS" do
158
+ sql = compile((@table[:updated_at] - @table[:created_at]).as('new_name'))
159
+ sql.must_match %{TIMEDIFF("users"."updated_at", "users"."created_at") AS new_name}
197
160
  end
198
161
 
199
- it 'should diff between time values' do
200
- d2 = Time.new(2015, 6, 1)
201
- d1 = DateTime.new(2015, 6, 2)
202
- _(compile(ArelExtensions::Nodes::DateDiff.new([d1, d2])))
203
- .must_match("DATEDIFF('2015-06-02', '2015-06-01')")
162
+ it "should diff between time values" do
163
+ d2 = Time.new(2015,6,1)
164
+ d1 = DateTime.new(2015,6,2)
165
+ sql = compile(ArelExtensions::Nodes::DateDiff.new([d1, d2]))
166
+ sql.must_match("DATEDIFF('2015-06-02', '2015-06-01')")
204
167
  end
205
168
 
206
- it 'should diff between time values and time col' do
207
- d1 = DateTime.new(2015, 6, 2)
208
- _(compile(ArelExtensions::Nodes::DateDiff.new([d1, @table[:updated_at]])))
209
- .must_match %{DATEDIFF('2015-06-02', "users"."updated_at")}
169
+ it "should diff between time values and time col" do
170
+ d1 = DateTime.new(2015,6,2)
171
+ sql = compile(ArelExtensions::Nodes::DateDiff.new([d1, @table[:updated_at]]))
172
+ sql.must_match %{DATEDIFF('2015-06-02', "users"."updated_at")}
210
173
  end
211
174
 
212
- it 'should diff between date col and duration' do
175
+ it "should diff between date col and duration" do
213
176
  d1 = 10
214
177
  d2 = -10
215
- _(compile(@table[:created_at] - d1))
216
- .must_match %{DATE_SUB("users"."created_at", 10)}
217
- _(compile(@table[:created_at] - d2))
218
- .must_match %{DATE_SUB("users"."created_at", -10)}
178
+ compile(@table[:created_at] - d1).
179
+ must_match %{DATE_SUB("users"."created_at", 10)}
180
+ compile(@table[:created_at] - d2).
181
+ must_match %{DATE_SUB("users"."created_at", -10)}
219
182
  end
220
183
 
221
- it 'should accept operators on dates with numbers' do
184
+ it "should accept operators on dates with numbers" do
222
185
  c = @table[:created_at]
223
- # u = @table[:updated_at]
224
- _(compile(c - 42)).must_be_like %{DATE_SUB("users"."created_at", 42)}
225
- _(compile(c - @table[:id])).must_be_like %{DATE_SUB("users"."created_at", "users"."id")}
186
+ #u = @table[:updated_at]
187
+ compile(c - 42).must_be_like %{DATE_SUB("users"."created_at", 42)}
188
+ compile(c - @table[:id]).must_be_like %{DATE_SUB("users"."created_at", "users"."id")}
226
189
  end
227
190
 
228
191
  # Maths on sums
229
- it 'should accept math operators on anything' do
192
+ it "should accept math operators on anything" do
230
193
  c = @table[:name]
231
- _((c == 'test').to_sql)
232
- .must_be_like %{"users"."name" = 'test'}
233
- _((c != 'test').to_sql)
234
- .must_be_like %{"users"."name" != 'test'}
235
- _((c > 'test').to_sql)
236
- .must_be_like %{"users"."name" > 'test'}
237
- _(compile((c >= 'test').as('new_name'))).must_be_like %{("users"."name" >= 'test') AS new_name}
238
- _(compile(c <= @table[:comments])).must_be_like %{"users"."name" <= "users"."comments"}
239
- _(compile(c =~ /\Atest\Z/)).must_be_like %{"users"."name" REGEXP '^test$'}
240
- _(compile(c !~ /\Ate\Dst\Z/)).must_be_like %{"users"."name" NOT REGEXP '^te[^0-9]st$'}
194
+ (c == 'test').to_sql.must_be_like %{"users"."name" = 'test'}
195
+ (c != 'test').to_sql.must_be_like %{"users"."name" != 'test'}
196
+ (c > 'test').to_sql.must_be_like %{"users"."name" > 'test'}
197
+ compile((c >= 'test').as('new_name')).must_be_like %{("users"."name" >= 'test') AS new_name}
198
+ compile(c <= @table[:comments]).must_be_like %{"users"."name" <= "users"."comments"}
199
+ compile(c =~ /\Atest\Z/).must_be_like %{"users"."name" REGEXP '^test$'}
200
+ compile(c !~ /\Ate\Dst\Z/).must_be_like %{"users"."name" NOT REGEXP '^te[^0-9]st$'}
241
201
  end
242
202
 
243
- it 'should manage complex formulas' do
203
+ it "should manage complex formulas" do
244
204
  c = @table[:name]
245
- _(compile(
246
- (c.length / 42).round(2).floor > (@table[:updated_at] - Date.new(2000, 3, 31)).abs.ceil
247
- ))
248
- .must_be_like %{FLOOR(ROUND(LENGTH("users"."name") / 42, 2)) > CEIL(ABS(TIMEDIFF("users"."updated_at", '2000-03-31 00:00:00 UTC')))}
205
+ compile(
206
+ (c.length / 42).round(2).floor > (@table[:updated_at] - Date.new(2000, 3, 31)).abs.ceil
207
+ ).must_be_like %{FLOOR(ROUND(LENGTH("users"."name") / 42, 2)) > CEIL(ABS(TIMEDIFF("users"."updated_at", '2000-03-31 00:00:00 UTC')))}
249
208
  end
250
209
 
251
- it 'should accept aggregator like GROUP CONCAT' do
252
- _(@table.project(@table[:first_name].group_concat).group(@table[:last_name]).to_sql)
210
+ it "should accept aggregator like GROUP CONCAT" do
211
+ @table.project(@table[:first_name].group_concat).group(@table[:last_name]).to_sql
253
212
  .must_be_like %{SELECT GROUP_CONCAT("users"."first_name") FROM "users" GROUP BY "users"."last_name"}
254
- _(@table.project(@table[:first_name].group_concat('++')).group(@table[:last_name]).to_sql)
213
+ @table.project(@table[:first_name].group_concat('++')).group(@table[:last_name]).to_sql
255
214
  .must_be_like %{SELECT GROUP_CONCAT("users"."first_name", '++') FROM "users" GROUP BY "users"."last_name"}
256
215
  end
257
216
 
258
217
  # Unions
259
- it 'should accept union operators on queries and union nodes' do
218
+ it "should accept union operators on queries and union nodes" do
260
219
  c = @table.project(@table[:name])
261
- _(compile(c + c))
220
+ compile(c + c)
262
221
  .must_be_like %{(SELECT "users"."name" FROM "users") UNION (SELECT "users"."name" FROM "users")}
263
- _((c + c).to_sql)
222
+ (c + c).to_sql
264
223
  .must_be_like %{(SELECT "users"."name" FROM "users") UNION (SELECT "users"."name" FROM "users")}
265
- _((c + (c + c)).to_sql)
224
+ (c + (c + c)).to_sql
266
225
  .must_be_like %{(SELECT "users"."name" FROM "users") UNION (SELECT "users"."name" FROM "users") UNION (SELECT "users"."name" FROM "users")}
267
- _(((c + c) + c).to_sql)
226
+ ((c + c) + c).to_sql
268
227
  .must_be_like %{(SELECT "users"."name" FROM "users") UNION (SELECT "users"."name" FROM "users") UNION (SELECT "users"."name" FROM "users")}
269
- _((c + c + c).to_sql)
228
+ (c + c + c).to_sql
270
229
  .must_be_like %{(SELECT "users"."name" FROM "users") UNION (SELECT "users"."name" FROM "users") UNION (SELECT "users"."name" FROM "users")}
271
- _((c + c).as('union_table').to_sql)
230
+ (c + c).as('union_table').to_sql
272
231
  .must_be_like %{((SELECT "users"."name" FROM "users") UNION (SELECT "users"."name" FROM "users")) union_table}
273
232
  c = @table.project(@table[:name])
274
- _(compile(c.union_all(c)))
233
+ compile(c.union_all(c))
275
234
  .must_be_like %{(SELECT "users"."name" FROM "users") UNION ALL (SELECT "users"."name" FROM "users")}
276
- _(c.union_all(c).to_sql)
235
+ (c.union_all(c)).to_sql
277
236
  .must_be_like %{(SELECT "users"."name" FROM "users") UNION ALL (SELECT "users"."name" FROM "users")}
278
- _(c.union_all(c.union_all(c)).to_sql)
237
+ (c.union_all(c.union_all(c))).to_sql
279
238
  .must_be_like %{(SELECT "users"."name" FROM "users") UNION ALL (SELECT "users"."name" FROM "users") UNION ALL (SELECT "users"."name" FROM "users")}
280
- _((c.union_all(c)).union_all(c).to_sql)
239
+ ((c.union_all(c)).union_all(c)).to_sql
281
240
  .must_be_like %{(SELECT "users"."name" FROM "users") UNION ALL (SELECT "users"."name" FROM "users") UNION ALL (SELECT "users"."name" FROM "users")}
282
- _(c.union_all(c).union_all(c).to_sql)
241
+ (c.union_all(c).union_all(c)).to_sql
283
242
  .must_be_like %{(SELECT "users"."name" FROM "users") UNION ALL (SELECT "users"."name" FROM "users") UNION ALL (SELECT "users"."name" FROM "users")}
284
- _((c.union_all(c)).as('union_table').to_sql)
243
+ (c.union_all(c)).as('union_table').to_sql
285
244
  .must_be_like %{((SELECT "users"."name" FROM "users") UNION ALL (SELECT "users"."name" FROM "users")) union_table}
286
245
  end
287
246
 
288
247
  # Case
289
- it 'should accept case clause' do
290
- _(@table[:name].when('smith').then('cool').when('doe').then('fine').else('uncool').to_sql)
248
+ it "should accept case clause" do
249
+ @table[:name].when("smith").then("cool").when("doe").then("fine").else("uncool").to_sql
291
250
  .must_be_like %{CASE "users"."name" WHEN 'smith' THEN 'cool' WHEN 'doe' THEN 'fine' ELSE 'uncool' END}
292
- _(@table[:name].when('smith').then(1).when('doe').then(2).else(0).to_sql)
251
+ @table[:name].when("smith").then(1).when("doe").then(2).else(0).to_sql
293
252
  .must_be_like %{CASE "users"."name" WHEN 'smith' THEN 1 WHEN 'doe' THEN 2 ELSE 0 END}
294
- _(Arel.when(@table[:name] == 'smith').then(1).when(@table[:name] == 'doe').then(2).else(0).to_sql)
253
+ ArelExtensions::Nodes::Case.new.when(@table[:name] == "smith").then(1).when(@table[:name] == "doe").then(2).else(0).to_sql
295
254
  .must_be_like %{CASE WHEN "users"."name" = 'smith' THEN 1 WHEN "users"."name" = 'doe' THEN 2 ELSE 0 END}
296
- _(ArelExtensions::Nodes::Case.new(@table[:name]).when('smith').then(1).when('doe').then(2).else(0).to_sql)
255
+ ArelExtensions::Nodes::Case.new(@table[:name]).when("smith").then(1).when("doe").then(2).else(0).to_sql
297
256
  .must_be_like %{CASE "users"."name" WHEN 'smith' THEN 1 WHEN 'doe' THEN 2 ELSE 0 END}
298
- _(@table[:name].when('smith').then(1).when('doe').then(2).else(0).sum.to_sql)
257
+ @table[:name].when("smith").then(1).when("doe").then(2).else(0).sum.to_sql
299
258
  .must_be_like %{SUM(CASE "users"."name" WHEN 'smith' THEN 1 WHEN 'doe' THEN 2 ELSE 0 END)}
300
- _(@table[:name].when('smith').then('cool').else('uncool').matches('value', false).to_sql)
259
+ @table[:name].when("smith").then("cool").else("uncool").matches('value',false).to_sql
301
260
  .must_be_like %{CASE "users"."name" WHEN 'smith' THEN 'cool' ELSE 'uncool' END LIKE 'value'}
302
- _(@table[:name].when('smith').then('cool').else('uncool').imatches('value', false).to_sql)
261
+ @table[:name].when("smith").then("cool").else("uncool").imatches('value',false).to_sql
303
262
  .must_be_like %{CASE "users"."name" WHEN 'smith' THEN 'cool' ELSE 'uncool' END ILIKE 'value'}
304
263
  end
305
264
 
306
- it 'should be possible to use as/xas on anything' do
307
- {
308
- @table[:name] => %{"users"."name" AS alias},
309
- @table[:name].concat(' test') => %{CONCAT("users"."name", ' test') AS alias},
310
- (@table[:name] + ' test') => %{CONCAT("users"."name", ' test') AS alias},
311
- (@table[:age] + 42) => %{("users"."age" + 42) AS alias},
312
- @table[:name].coalesce('') => %{COALESCE("users"."name", '') AS alias},
313
- Arel.quoted('test') => %{'test' AS alias},
314
- @table.project(@table[:name]) => %{(SELECT "users"."name" FROM "users") "alias"},
315
- @table[:name].when('smith').then('cool').else('uncool') => %{CASE "users"."name" WHEN 'smith' THEN 'cool' ELSE 'uncool' END AS alias},
316
- }.each do |exp, res|
317
- _(compile(exp.as('alias'))).must_be_like res
318
- _(compile(exp.xas('alias'))).must_be_like res
319
-
320
- res_no_alias = res.gsub(/\s*(?:AS alias|"alias")\s*\z/, '')
321
- _(compile(exp.xas(nil))).must_be_like res_no_alias
322
- end
265
+ it "should be possible to use as on anything" do
266
+ compile(@table[:name].as('alias')).must_be_like %{"users"."name" AS alias}
267
+ compile(@table[:name].concat(' test').as('alias')).must_be_like %{CONCAT("users"."name", ' test') AS alias}
268
+ compile((@table[:name] + ' test').as('alias')).must_be_like %{CONCAT("users"."name", ' test') AS alias}
269
+ compile((@table[:age] + 42).as('alias')).must_be_like %{("users"."age" + 42) AS alias}
270
+ compile(@table[:name].coalesce('').as('alias')).must_be_like %{COALESCE("users"."name", '') AS alias}
271
+ compile(Arel::Nodes.build_quoted('test').as('alias')).must_be_like %{'test' AS alias}
272
+ compile(@table.project(@table[:name]).as('alias')).must_be_like %{(SELECT "users"."name" FROM "users") alias}
273
+ compile(@table[:name].when("smith").then("cool").else("uncool").as('alias')).
274
+ must_be_like %{CASE "users"."name" WHEN 'smith' THEN 'cool' ELSE 'uncool' END AS alias}
323
275
  end
324
276
 
325
- it 'should accept comparators on functions' do
277
+ it "should accept comparators on functions" do
326
278
  c = @table[:name]
327
- _(compile(c.soundex == 'test')).must_be_like %{SOUNDEX("users"."name") = 'test'}
328
- _(compile(c.soundex != 'test')).must_be_like %{SOUNDEX("users"."name") != 'test'}
329
- _(compile(c.length >= 0)).must_be_like %{LENGTH("users"."name") >= 0}
279
+ compile(c.soundex == 'test').must_be_like %{SOUNDEX("users"."name") = 'test'}
280
+ compile(c.soundex != 'test').must_be_like %{SOUNDEX("users"."name") != 'test'}
281
+ compile(c.length >= 0 ).must_be_like %{LENGTH("users"."name") >= 0}
330
282
  end
331
283
 
332
- it 'should accept in on select statement' do
284
+ it "should accept in on select statement" do
333
285
  c = @table[:name]
334
- _(compile(c.in(@table.project(@table[:name]))))
286
+ compile(c.in(@table.project(@table[:name])))
335
287
  .must_be_like %{"users"."name" IN (SELECT "users"."name" FROM "users")}
336
288
  end
337
289
 
338
- it 'should accept coalesce function properly even on none actual tables and attributes' do
290
+ it "should accept coalesce function properly even on none actual tables and attributes" do
339
291
  fake_at = Arel::Table.new('fake_table')
340
- _(compile(fake_at['fake_attribute'].coalesce('other_value')))
292
+ compile(fake_at['fake_attribute'].coalesce('other_value'))
341
293
  .must_be_like %{COALESCE("fake_table"."fake_attribute", 'other_value')}
342
- _(compile(fake_at['fake_attribute'].coalesce('other_value1', 'other_value2')))
294
+ compile(fake_at['fake_attribute'].coalesce('other_value1','other_value2'))
343
295
  .must_be_like %{COALESCE("fake_table"."fake_attribute", 'other_value1', 'other_value2')}
344
- _(compile(fake_at['fake_attribute'].coalesce('other_value1').coalesce('other_value2')))
296
+ compile(fake_at['fake_attribute'].coalesce('other_value1').coalesce('other_value2'))
345
297
  .must_be_like %{COALESCE(COALESCE("fake_table"."fake_attribute", 'other_value1'), 'other_value2')}
346
- _(compile(fake_at['fake_attribute'].coalesce('other_value').matches('truc')))
298
+ compile(fake_at['fake_attribute'].coalesce('other_value').matches('truc'))
347
299
  .must_be_like %{COALESCE("fake_table"."fake_attribute", 'other_value') LIKE 'truc'}
348
- _(compile(fake_at['fake_attribute'].coalesce('other_value').imatches('truc')))
300
+ compile(fake_at['fake_attribute'].coalesce('other_value').imatches('truc'))
349
301
  .must_be_like %{COALESCE("fake_table"."fake_attribute", 'other_value') ILIKE 'truc'}
350
302
  end
351
303
 
352
- it 'should be possible to cast nodes types' do
353
- _(compile(@table[:id].cast('char')))
304
+ it "should be possible to cast nodes types" do
305
+ compile(@table[:id].cast('char'))
354
306
  .must_be_like %{CAST("users"."id" AS char)}
355
- _(compile(@table[:id].coalesce(' ').cast('char')))
307
+ compile(@table[:id].coalesce(' ').cast('char'))
356
308
  .must_be_like %{CAST(COALESCE("users"."id", ' ') AS char)}
357
- _(compile(@table[:id].coalesce(' ').cast(:string)))
309
+ compile(@table[:id].coalesce(' ').cast(:string))
358
310
  .must_be_like %{CAST(COALESCE("users"."id", ' ') AS char)}
359
- _(compile(@table[:id].cast(:string).coalesce(' ')))
311
+ compile(@table[:id].cast(:string).coalesce(' '))
360
312
  .must_be_like %{COALESCE(CAST(\"users\".\"id\" AS char), ' ')}
361
- _(compile(@table[:id].cast('char') + ' '))
313
+ compile(@table[:id].cast('char') + ' ')
362
314
  .must_be_like %{CONCAT(CAST("users"."id" AS char), ' ')}
363
- _(compile(@table[:id].cast('int') + 2))
315
+ compile(@table[:id].cast('int') + 2)
364
316
  .must_be_like %{(CAST("users"."id" AS int) + 2)}
365
317
  end
366
318
 
367
- describe 'the function in' do
368
- it 'should be possible to have nil element in the function IN' do
369
- _(compile(@table[:id].in(nil)))
370
- .must_be_like %{ISNULL("users"."id")}
371
- _(compile(@table[:id].in([nil])))
372
- .must_be_like %{ISNULL("users"."id")}
373
- _(compile(@table[:id].in([nil, 1])))
374
- .must_be_like %{(ISNULL("users"."id")) OR ("users"."id" = 1)}
375
- _(compile(@table[:id].in([nil, 1, 2])))
376
- .must_be_like %{(ISNULL("users"."id")) OR ("users"."id" IN (1, 2))}
377
- _(compile(@table[:id].in(1)))
378
- .must_be_like %{"users"."id" IN (1)}
379
- _(compile(@table[:id].in([1])))
380
- .must_be_like %{"users"."id" = 1}
381
- _(compile(@table[:id].in([1, 2])))
382
- .must_be_like %{"users"."id" IN (1, 2)}
383
- _(compile(@table[:id].in([])))
384
- .must_be_like %{1 = 0}
385
- end
386
-
387
- it 'should be possible to correctly use a Range on an IN' do
388
- _(compile(@table[:id].in(1..4)))
389
- .must_be_like %{"users"."id" BETWEEN (1) AND (4)}
390
- _(compile(@table[:created_at].in(Date.new(2016, 3, 31)..Date.new(2017, 3, 31))))
391
- .must_be_like %{"users"."created_at" BETWEEN ('2016-03-31') AND ('2017-03-31')}
392
- end
393
-
394
- it 'should be possible to use a list of values and ranges on an IN' do
395
- _(compile(@table[:id].in [1..10, 20, 30, 40..50]))
396
- .must_be_like %{("users"."id" IN (20, 30)) OR ("users"."id" BETWEEN (1) AND (10)) OR ("users"."id" BETWEEN (40) AND (50))}
397
- _(compile(@table[:created_at].in(Date.new(2016, 1, 1), Date.new(2016, 2, 1)..Date.new(2016, 2, 28), Date.new(2016, 3, 31)..Date.new(2017, 3, 31), Date.new(2018, 1, 1))))
398
- .must_be_like %{ ("users"."created_at" IN ('2016-01-01', '2018-01-01'))
399
- OR ("users"."created_at" BETWEEN ('2016-02-01') AND ('2016-02-28'))
400
- OR ("users"."created_at" BETWEEN ('2016-03-31') AND ('2017-03-31'))}
401
- end
402
-
403
- it 'should respecting Grouping' do
404
- g = ->(*v) { Arel.grouping(v) }
405
- _(compile(g[@table[:id], @table[:age]].in [g[1, 42]]))
406
- .must_be_like %{("users"."id", "users"."age") IN ((1, 42))}
407
- _(compile(g[@table[:id], @table[:age]].in [g[1, 42], g[2, 51]]))
408
- .must_be_like %{("users"."id", "users"."age") IN ((1, 42), (2, 51))}
409
-
410
- _(compile(g[@table[:id], @table[:age]].in(g[1, 42], g[2, 51])))
411
- .must_be_like %{("users"."id", "users"."age") IN ((1, 42), (2, 51))}
412
- end
319
+ it "should be possible to have nil element in the function NIL" do
320
+ compile(@table[:id].in(nil))
321
+ .must_be_like %{ISNULL("users"."id")}
322
+ compile(@table[:id].in([nil]))
323
+ .must_be_like %{ISNULL("users"."id")}
324
+ compile(@table[:id].in([nil,1]))
325
+ .must_be_like %{(ISNULL("users"."id")) OR ("users"."id" = 1)}
326
+ compile(@table[:id].in([nil,1,2]))
327
+ .must_be_like %{(ISNULL("users"."id")) OR ("users"."id" IN (1, 2))}
328
+ compile(@table[:id].in(1))
329
+ .must_be_like %{"users"."id" IN (1)}
330
+ compile(@table[:id].in([1]))
331
+ .must_be_like %{"users"."id" IN (1)}
332
+ compile(@table[:id].in([1,2]))
333
+ .must_be_like %{"users"."id" IN (1, 2)}
413
334
  end
414
335
 
415
- describe 'the function not_in' do
416
- it 'should be possible to have nil element in the function IN' do
417
- _(compile(@table[:id].not_in nil))
418
- .must_be_like %{NOT ISNULL("users"."id")}
419
- _(compile(@table[:id].not_in [nil]))
420
- .must_be_like %{NOT ISNULL("users"."id")}
421
- _(compile(@table[:id].not_in [nil, 1]))
422
- .must_be_like %{(NOT ISNULL("users"."id")) AND ("users"."id" != 1)}
423
- _(compile(@table[:id].not_in [nil, 1, 2]))
424
- .must_be_like %{(NOT ISNULL("users"."id")) AND ("users"."id" NOT IN (1, 2))}
425
- _(compile(@table[:id].not_in 1))
426
- .must_be_like %{"users"."id" NOT IN (1)}
427
- _(compile(@table[:id].not_in [1]))
428
- .must_be_like %{"users"."id" != 1}
429
- _(compile(@table[:id].not_in [1, 2]))
430
- .must_be_like %{"users"."id" NOT IN (1, 2)}
431
- _(compile(@table[:id].not_in []))
432
- .must_be_like %{1 = 1}
433
- end
434
-
435
- it 'should be possible to correctly use a Range on an IN' do
436
- # FIXME: Should use NOT BETWEEN
437
- _(compile(@table[:id].not_in 1..4))
438
- .must_be_like %{NOT ("users"."id" BETWEEN (1) AND (4))}
439
- # FIXME: Should use NOT BETWEEN
440
- _(compile(@table[:created_at].not_in Date.new(2016, 3, 31)..Date.new(2017, 3, 31)))
441
- .must_be_like %{NOT ("users"."created_at" BETWEEN ('2016-03-31') AND ('2017-03-31'))}
442
- end
443
-
444
- it 'should be possible to use a list of values and ranges on an IN' do
445
- _(compile(@table[:id].not_in [1..10, 20, 30, 40..50]))
446
- .must_be_like %{ ("users"."id" NOT IN (20, 30))
447
- AND (NOT ("users"."id" BETWEEN (1) AND (10)))
448
- AND (NOT ("users"."id" BETWEEN (40) AND (50)))}
449
- _(compile(@table[:created_at].not_in Date.new(2016, 1, 1), Date.new(2016, 2, 1)..Date.new(2016, 2, 28), Date.new(2016, 3, 31)..Date.new(2017, 3, 31), Date.new(2018, 1, 1)))
450
- .must_be_like %{ ("users"."created_at" NOT IN ('2016-01-01', '2018-01-01'))
451
- AND (NOT ("users"."created_at" BETWEEN ('2016-02-01') AND ('2016-02-28')))
452
- AND (NOT ("users"."created_at" BETWEEN ('2016-03-31') AND ('2017-03-31')))}
453
- end
336
+ it "should be possible to correctly use a Range on an IN" do
337
+ compile(@table[:id].in(1..4))
338
+ .must_be_like %{"users"."id" BETWEEN (1) AND (4)}
339
+ compile(@table[:created_at].in(@date .. Date.new(2017, 3, 31))) # @date = Date.new(2016, 3, 31)
340
+ .must_be_like %{"users"."created_at" BETWEEN ('2016-03-31') AND ('2017-03-31')}
454
341
  end
455
342
 
456
- it 'should be possible to add and substract as much as we want' do
343
+ it "should be possible to add and substract as much as we want" do
457
344
  c = @table[:name]
458
- _(compile(c.locate('test') + 1))
345
+ compile(c.locate('test')+1)
459
346
  .must_be_like %{(LOCATE('test', "users"."name") + 1)}
460
- _(compile(c.locate('test') - 1))
347
+ compile(c.locate('test')-1)
461
348
  .must_be_like %{(LOCATE('test', "users"."name") - 1)}
462
- _(compile(c.locate('test') + c.locate('test')))
349
+ compile(c.locate('test')+c.locate('test'))
463
350
  .must_be_like %{(LOCATE('test', "users"."name") + LOCATE('test', "users"."name"))}
464
- _(compile(c.locate('test') + 1 + c.locate('test') - 1 + 1))
351
+ compile(c.locate('test')+1+c.locate('test')-1 + 1)
465
352
  .must_be_like %{((((LOCATE('test', "users"."name") + 1) + LOCATE('test', "users"."name")) - 1) + 1)}
466
353
  end
467
354
 
468
- it 'should be possible to add and substract on some nodes' do
355
+ it "should be possible to add and substract on some nodes" do
469
356
  c = @table[:name]
470
- _(compile(c.when(0, 0).else(42) + 42)).must_be_like %{(CASE "users"."name" WHEN 0 THEN 0 ELSE 42 END + 42)}
471
- _(compile(c.when(0, 0).else(42) - 42)).must_be_like %{(CASE "users"."name" WHEN 0 THEN 0 ELSE 42 END - 42)}
472
- _(compile(c.when(0, '0').else('42') + '42')).must_be_like %{CONCAT(CASE "users"."name" WHEN 0 THEN '0' ELSE '42' END, '42')}
357
+ compile(c.when(0,0).else(42) + 42).must_be_like %{(CASE "users"."name" WHEN 0 THEN 0 ELSE 42 END + 42)}
358
+ compile(c.when(0,0).else(42) - 42).must_be_like %{(CASE "users"."name" WHEN 0 THEN 0 ELSE 42 END - 42)}
359
+ compile(c.when(0,"0").else("42") + "42").must_be_like %{CONCAT(CASE "users"."name" WHEN 0 THEN '0' ELSE '42' END, '42')}
473
360
  end
474
361
 
475
- it 'should be possible to desc and asc on functions' do
362
+ it "should be possible to desc and asc on functions" do
476
363
  c = @table[:name]
477
- _(compile(c.asc))
364
+ compile(c.asc)
478
365
  .must_be_like %{"users"."name" ASC}
479
- _(compile(c.substring(2).asc))
366
+ compile(c.substring(2).asc)
480
367
  .must_be_like %{SUBSTRING("users"."name", 2) ASC}
481
- _(compile(c.substring(2).desc))
368
+ compile(c.substring(2).desc)
482
369
  .must_be_like %{SUBSTRING("users"."name", 2) DESC}
483
- _(compile((c.locate('test') + 1).asc))
370
+ compile((c.locate('test')+1).asc)
484
371
  .must_be_like %{(LOCATE('test', "users"."name") + 1) ASC}
485
372
  end
486
373
 
487
- it 'should be possible to call Table function on TableAlias' do
488
- t = @table
489
- a = t.alias('aliased_users')
490
- _(compile(a.join(t).join_sources))
491
- .must_be_like %{INNER JOIN \"users\"}
492
- end
493
-
494
- describe 'logical functions' do
495
- it 'should know about truth' do
496
- _(compile(Arel.false))
497
- .must_be_like %{1 = 0}
498
-
499
- _(compile(Arel::true))
500
- .must_be_like %{1 = 1}
501
- end
502
-
503
- it 'boolean nodes should be variadic' do
504
- c = @table[:id]
505
-
506
- _(compile(Arel::Nodes::And.new))
507
- .must_be_like %{1 = 1}
508
- _(compile(Arel::Nodes::And.new(c == 1)))
509
- .must_be_like %{"users"."id" = 1}
510
- _(compile(Arel::Nodes::And.new(c == 1, c == 2)))
511
- .must_be_like %{("users"."id" = 1) AND ("users"."id" = 2)}
512
- _(compile(Arel::Nodes::And.new [c == 1, c == 2, c == 3]))
513
- .must_be_like %{("users"."id" = 1) AND ("users"."id" = 2) AND ("users"."id" = 3)}
514
-
515
-
516
- _(compile(Arel::Nodes::Or.new))
517
- .must_be_like %{1 = 0}
518
- _(compile(Arel::Nodes::Or.new(c == 1)))
519
- .must_be_like %{"users"."id" = 1}
520
- _(compile(Arel::Nodes::Or.new(c == 1, c == 2)))
521
- .must_be_like %{("users"."id" = 1) OR ("users"."id" = 2)}
522
- _(compile(Arel::Nodes::Or.new(c == 1, c == 2, c == 3)))
523
- .must_be_like %{("users"."id" = 1) OR ("users"."id" = 2) OR ("users"."id" = 3)}
524
- _(compile(Arel::Nodes::Or.new [c == 1, c == 2, c == 3]))
525
- .must_be_like %{("users"."id" = 1) OR ("users"."id" = 2) OR ("users"."id" = 3)}
526
- end
527
-
528
- it 'should know trivial identities' do
529
- skip 'For future optimization'
530
- c = @table[:id]
531
- _(compile(Arel::Nodes::And.new(Arel.true, c == 1)))
532
- .must_be_like %{"users"."id" = 1}
533
- _(compile(Arel::Nodes::And.new(Arel.false, c == 1)))
534
- .must_be_like %{1 = 0}
535
- _(compile(Arel::Nodes::And.new(c == 1, c == 1)))
536
- .must_be_like %{"users"."id" = 1}
537
-
538
- _(compile(Arel::Nodes::Or.new(Arel.true, c == 1)))
539
- .must_be_like %{1 = 1}
540
- _(compile(Arel::Nodes::Or.new(Arel.false, c == 1)))
541
- .must_be_like %{"users"."id" = 1}
542
- _(compile(Arel::Nodes::Or.new(c == 1, c == 1)))
543
- .must_be_like %{"users"."id" = 1}
544
- end
545
-
546
- it 'should be possible to have multiple arguments on an OR or an AND node' do
547
- c = @table[:id]
548
- _(compile((c == 1).and))
549
- .must_be_like %{"users"."id" = 1}
550
-
551
- _(compile((c == 1).and(c == 2, c == 3)))
552
- .must_be_like %{("users"."id" = 1) AND ("users"."id" = 2) AND ("users"."id" = 3)}
553
- _(compile((c == 1).and([c == 2, c == 3])))
554
- .must_be_like %{("users"."id" = 1) AND ("users"."id" = 2) AND ("users"."id" = 3)}
555
-
556
- _(compile((c == 1).or))
557
- .must_be_like %{"users"."id" = 1}
558
-
559
- _(compile((c == 1).or(c == 2, c == 3)))
560
- .must_be_like %{("users"."id" = 1) OR ("users"."id" = 2) OR ("users"."id" = 3)}
561
- _(compile((c == 1).or([c == 2, c == 3])))
562
- .must_be_like %{("users"."id" = 1) OR ("users"."id" = 2) OR ("users"."id" = 3)}
563
- end
564
-
565
- it 'should avoid useless nesting' do
566
- c = @table[:id]
567
- _(compile(((c == 1).and(c == 2)).and ((c == 3).and(c == 4))))
568
- .must_be_like %{("users"."id" = 1) AND ("users"."id" = 2) AND ("users"."id" = 3) AND ("users"."id" = 4)}
569
- _(compile(((c == 1).or(c == 2)).or ((c == 3).or(c == 4))))
570
- .must_be_like %{("users"."id" = 1) OR ("users"."id" = 2) OR ("users"."id" = 3) OR ("users"."id" = 4)}
571
-
572
- _(compile(((c == 1).or(c == 2)).and ((c == 3).or(c == 4))))
573
- .must_be_like %{(("users"."id" = 1) OR ("users"."id" = 2)) AND (("users"."id" = 3) OR ("users"."id" = 4))}
574
- _(compile(((c == 1).and(c == 2)).or ((c == 3).and(c == 4))))
575
- .must_be_like %{(("users"."id" = 1) AND ("users"."id" = 2)) OR (("users"."id" = 3) AND ("users"."id" = 4))}
576
- end
374
+ it "should be possible to have multiple arguments on an OR or an AND node" do
375
+ c = @table[:id]
376
+ compile((c == 1).and(c == 2, c == 3)).
377
+ must_be_like %{("users"."id" = 1) AND ("users"."id" = 2) AND ("users"."id" = 3)}
378
+ compile((c == 1).and([c == 2, c == 3])).
379
+ must_be_like %{("users"."id" = 1) AND ("users"."id" = 2) AND ("users"."id" = 3)}
380
+ compile((c == 1).or(c == 2, c == 3)).
381
+ must_be_like %{("users"."id" = 1) OR ("users"."id" = 2) OR ("users"."id" = 3)}
382
+ compile((c == 1).or([c == 2, c == 3])).
383
+ must_be_like %{("users"."id" = 1) OR ("users"."id" = 2) OR ("users"."id" = 3)}
577
384
  end
578
385
 
579
- puts "AREL VERSION: #{Arel::VERSION}"
386
+ puts "AREL VERSION : " + Arel::VERSION.to_s
580
387
  end
581
388
  end
582
389
  end