arel_extensions 2.1.2 → 2.1.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.codeclimate.yml +1 -2
- data/.github/workflows/ruby.yml +43 -91
- data/.gitignore +7 -6
- data/.rubocop.yml +62 -1
- data/Gemfile +11 -11
- data/README.md +1 -1
- data/Rakefile +4 -4
- data/TODO +0 -1
- data/appveyor.yml +73 -0
- data/arel_extensions.gemspec +11 -11
- data/gemfiles/rails3.gemfile +10 -10
- data/gemfiles/rails4.gemfile +14 -14
- data/gemfiles/rails5_0.gemfile +13 -13
- data/gemfiles/rails5_1_4.gemfile +13 -13
- data/gemfiles/rails5_2.gemfile +15 -14
- data/gemfiles/rails6.gemfile +13 -12
- data/gemfiles/rails6_1.gemfile +13 -12
- data/gemfiles/rails7.gemfile +9 -8
- data/gemspecs/arel_extensions-v1.gemspec +12 -12
- data/gemspecs/arel_extensions-v2.gemspec +11 -11
- data/init/mssql.sql +0 -0
- data/init/mysql.sql +0 -0
- data/init/oracle.sql +0 -0
- data/init/postgresql.sql +0 -0
- data/init/sqlite.sql +0 -0
- data/lib/arel_extensions/attributes.rb +2 -2
- data/lib/arel_extensions/boolean_functions.rb +2 -4
- data/lib/arel_extensions/common_sql_functions.rb +12 -12
- data/lib/arel_extensions/comparators.rb +14 -14
- data/lib/arel_extensions/date_duration.rb +7 -7
- data/lib/arel_extensions/helpers.rb +19 -16
- data/lib/arel_extensions/insert_manager.rb +1 -1
- data/lib/arel_extensions/math.rb +44 -31
- data/lib/arel_extensions/math_functions.rb +18 -18
- data/lib/arel_extensions/nodes/abs.rb +0 -0
- data/lib/arel_extensions/nodes/aggregate_function.rb +0 -0
- data/lib/arel_extensions/nodes/blank.rb +1 -1
- data/lib/arel_extensions/nodes/case.rb +4 -6
- data/lib/arel_extensions/nodes/cast.rb +5 -5
- data/lib/arel_extensions/nodes/ceil.rb +0 -0
- data/lib/arel_extensions/nodes/change_case.rb +0 -0
- data/lib/arel_extensions/nodes/coalesce.rb +1 -1
- data/lib/arel_extensions/nodes/collate.rb +9 -9
- data/lib/arel_extensions/nodes/concat.rb +2 -2
- data/lib/arel_extensions/nodes/date_diff.rb +10 -10
- data/lib/arel_extensions/nodes/duration.rb +0 -0
- data/lib/arel_extensions/nodes/find_in_set.rb +0 -0
- data/lib/arel_extensions/nodes/floor.rb +0 -0
- data/lib/arel_extensions/nodes/format.rb +0 -0
- data/lib/arel_extensions/nodes/formatted_number.rb +2 -2
- data/lib/arel_extensions/nodes/function.rb +21 -21
- data/lib/arel_extensions/nodes/is_null.rb +0 -0
- data/lib/arel_extensions/nodes/json.rb +7 -7
- data/lib/arel_extensions/nodes/length.rb +0 -0
- data/lib/arel_extensions/nodes/levenshtein_distance.rb +1 -1
- data/lib/arel_extensions/nodes/locate.rb +1 -1
- data/lib/arel_extensions/nodes/log10.rb +0 -0
- data/lib/arel_extensions/nodes/matches.rb +1 -1
- data/lib/arel_extensions/nodes/md5.rb +0 -0
- data/lib/arel_extensions/nodes/power.rb +0 -0
- data/lib/arel_extensions/nodes/rand.rb +0 -0
- data/lib/arel_extensions/nodes/repeat.rb +2 -2
- data/lib/arel_extensions/nodes/replace.rb +2 -2
- data/lib/arel_extensions/nodes/round.rb +0 -0
- data/lib/arel_extensions/nodes/soundex.rb +2 -2
- data/lib/arel_extensions/nodes/std.rb +0 -0
- data/lib/arel_extensions/nodes/substring.rb +1 -1
- data/lib/arel_extensions/nodes/sum.rb +0 -0
- data/lib/arel_extensions/nodes/then.rb +1 -1
- data/lib/arel_extensions/nodes/trim.rb +2 -2
- data/lib/arel_extensions/nodes/union.rb +4 -4
- data/lib/arel_extensions/nodes/union_all.rb +3 -3
- data/lib/arel_extensions/nodes/wday.rb +0 -0
- data/lib/arel_extensions/nodes.rb +0 -0
- data/lib/arel_extensions/null_functions.rb +0 -0
- data/lib/arel_extensions/predications.rb +10 -10
- data/lib/arel_extensions/railtie.rb +1 -1
- data/lib/arel_extensions/set_functions.rb +3 -3
- data/lib/arel_extensions/string_functions.rb +8 -8
- data/lib/arel_extensions/tasks.rb +2 -2
- data/lib/arel_extensions/version.rb +1 -1
- data/lib/arel_extensions/visitors/convert_format.rb +0 -0
- data/lib/arel_extensions/visitors/ibm_db.rb +20 -20
- data/lib/arel_extensions/visitors/mssql.rb +150 -130
- data/lib/arel_extensions/visitors/mysql.rb +147 -149
- data/lib/arel_extensions/visitors/oracle.rb +141 -135
- data/lib/arel_extensions/visitors/oracle12.rb +16 -16
- data/lib/arel_extensions/visitors/postgresql.rb +147 -139
- data/lib/arel_extensions/visitors/sqlite.rb +85 -87
- data/lib/arel_extensions/visitors/to_sql.rb +146 -148
- data/lib/arel_extensions/visitors.rb +7 -7
- data/lib/arel_extensions.rb +56 -32
- data/test/arelx_test_helper.rb +14 -13
- data/test/database.yml +5 -5
- data/test/real_db_test.rb +81 -81
- data/test/support/fake_record.rb +2 -2
- data/test/test_comparators.rb +5 -5
- data/test/visitors/test_bulk_insert_oracle.rb +5 -5
- data/test/visitors/test_bulk_insert_sqlite.rb +5 -5
- data/test/visitors/test_bulk_insert_to_sql.rb +5 -5
- data/test/visitors/test_oracle.rb +14 -14
- data/test/visitors/test_to_sql.rb +87 -87
- data/test/with_ar/all_agnostic_test.rb +411 -306
- data/test/with_ar/insert_agnostic_test.rb +19 -16
- data/test/with_ar/test_bulk_sqlite.rb +5 -5
- data/test/with_ar/test_math_sqlite.rb +12 -12
- data/test/with_ar/test_string_mysql.rb +20 -20
- data/test/with_ar/test_string_sqlite.rb +20 -20
- data/version_v1.rb +1 -1
- data/version_v2.rb +1 -1
- metadata +3 -9
- data/.travis/oracle/download.js +0 -152
- data/.travis/oracle/download.sh +0 -30
- data/.travis/oracle/download_ojdbc.js +0 -116
- data/.travis/oracle/install.sh +0 -34
- data/.travis/setup_accounts.sh +0 -9
- data/.travis/sqlite3/extension-functions.sh +0 -6
- data/.travis.yml +0 -193
@@ -7,10 +7,10 @@ module ArelExtensions
|
|
7
7
|
@conn = FakeRecord::Base.new
|
8
8
|
@visitor = Arel::Visitors::Oracle.new @conn.connection
|
9
9
|
@table = Arel::Table.new(:users)
|
10
|
-
@cols = [
|
10
|
+
@cols = %w[name comments created_at]
|
11
11
|
@data = [
|
12
|
-
[
|
13
|
-
[
|
12
|
+
%w[nom1 sdfdsfdsfsdf 2016-01-01],
|
13
|
+
%w[nom2 sdfdsfdsfsdf 2016-01-01]
|
14
14
|
]
|
15
15
|
end
|
16
16
|
|
@@ -22,8 +22,8 @@ module ArelExtensions
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
it
|
26
|
-
insert_manager = Arel::VERSION.to_i > 6 ? Arel::InsertManager.new
|
25
|
+
it 'should import large set of data in Oracle' do
|
26
|
+
insert_manager = Arel::VERSION.to_i > 6 ? Arel::InsertManager.new.into(@table) : Arel::InsertManager.new(@conn).into(@table)
|
27
27
|
insert_manager.bulk_insert(@cols, @data)
|
28
28
|
_(compile(insert_manager.ast))
|
29
29
|
.must_be_like %Q[INSERT INTO "users" ("name", "comments", "created_at")
|
@@ -8,10 +8,10 @@ module ArelExtensions
|
|
8
8
|
@visitor = Arel::Visitors::SQLite.new @conn.connection
|
9
9
|
@table = Arel::Table.new(:users)
|
10
10
|
Arel::Table.engine = @conn
|
11
|
-
@cols = [
|
11
|
+
@cols = %w[id name comments created_at]
|
12
12
|
@data = [
|
13
|
-
[23, 'nom1',
|
14
|
-
[25, 'nom2',
|
13
|
+
[23, 'nom1', 'sdfdsfdsfsdf', '2016-01-01'],
|
14
|
+
[25, 'nom2', 'sdfdsfdsfsdf', '2016-01-01']
|
15
15
|
]
|
16
16
|
end
|
17
17
|
|
@@ -23,8 +23,8 @@ module ArelExtensions
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
-
it
|
27
|
-
insert_manager = Arel::VERSION.to_i > 6 ? Arel::InsertManager.new
|
26
|
+
it 'should import large set of data' do
|
27
|
+
insert_manager = Arel::VERSION.to_i > 6 ? Arel::InsertManager.new.into(@table) : Arel::InsertManager.new(@conn).into(@table)
|
28
28
|
insert_manager.bulk_insert(@cols, @data)
|
29
29
|
_(compile(insert_manager.ast))
|
30
30
|
.must_be_like %Q[INSERT INTO "users" ("id", "name", "comments", "created_at")
|
@@ -8,10 +8,10 @@ module ArelExtensions
|
|
8
8
|
Arel::Table.engine = @conn
|
9
9
|
@visitor = Arel::Visitors::ToSql.new @conn.connection
|
10
10
|
@table = Arel::Table.new(:users)
|
11
|
-
@cols = [
|
11
|
+
@cols = %w[id name comments created_at]
|
12
12
|
@data = [
|
13
|
-
[23, 'nom1',
|
14
|
-
[25, 'nom2',
|
13
|
+
[23, 'nom1', 'sdfdsfdsfsdf', '2016-01-01'],
|
14
|
+
[25, 'nom2', 'sdfdsfdsfsdf', '2016-01-01']
|
15
15
|
]
|
16
16
|
end
|
17
17
|
|
@@ -24,8 +24,8 @@ module ArelExtensions
|
|
24
24
|
end
|
25
25
|
|
26
26
|
|
27
|
-
it
|
28
|
-
insert_manager = Arel::VERSION.to_i > 6 ? Arel::InsertManager.new
|
27
|
+
it 'should import large set of data using ToSql' do
|
28
|
+
insert_manager = Arel::VERSION.to_i > 6 ? Arel::InsertManager.new.into(@table) : Arel::InsertManager.new(@conn).into(@table)
|
29
29
|
insert_manager.bulk_insert(@cols, @data)
|
30
30
|
_(compile(insert_manager.ast))
|
31
31
|
.must_be_like %Q[INSERT INTO "users" ("id", "name", "comments", "created_at") VALUES (23, 'nom1', 'sdfdsfdsfsdf', '2016-01-01'), (25, 'nom2', 'sdfdsfdsfsdf', '2016-01-01')]
|
@@ -22,7 +22,7 @@ module ArelExtensions
|
|
22
22
|
|
23
23
|
# Comparators
|
24
24
|
|
25
|
-
it
|
25
|
+
it 'should accept comparators on integers' do
|
26
26
|
_(compile(@table[:id] == 42)).must_match %{"users"."id" = 42}
|
27
27
|
_(compile(@table[:id] == @table[:id])).must_be_like %{"users"."id" = "users"."id"}
|
28
28
|
_(compile(@table[:id] != 42)).must_match %{"users"."id" != 42}
|
@@ -34,7 +34,7 @@ module ArelExtensions
|
|
34
34
|
_(compile((@table[:id] <= 42).as('new_name'))).must_match %{("users"."id" <= 42) AS new_name}
|
35
35
|
end
|
36
36
|
|
37
|
-
it
|
37
|
+
it 'should accept comparators on dates' do
|
38
38
|
c = @table[:created_at]
|
39
39
|
u = @table[:updated_at]
|
40
40
|
_(compile(c > @date)).must_be_like %{"users"."created_at" > '2016-03-31'}
|
@@ -42,7 +42,7 @@ module ArelExtensions
|
|
42
42
|
_(compile(c < u)).must_be_like %{"users"."created_at" < "users"."updated_at"}
|
43
43
|
end
|
44
44
|
|
45
|
-
it
|
45
|
+
it 'should accept comparators on strings' do
|
46
46
|
c = @table[:name]
|
47
47
|
_(compile(c == 'test')).must_be_like %{"users"."name" = 'test'}
|
48
48
|
_(compile(c != 'test')).must_be_like %{"users"."name" != 'test'}
|
@@ -60,41 +60,41 @@ module ArelExtensions
|
|
60
60
|
|
61
61
|
# Maths
|
62
62
|
# DateDiff
|
63
|
-
it
|
63
|
+
it 'should diff date col and date' do
|
64
64
|
_(compile(@table[:created_at] - Date.new(2016, 3, 31))).must_match %{"users"."created_at" - TO_DATE('2016-03-31')}
|
65
65
|
end
|
66
66
|
|
67
|
-
it
|
67
|
+
it 'should diff date col and datetime col' do
|
68
68
|
_(compile(@table[:created_at] - @table[:updated_at])).must_match %{"users"."created_at" - "users"."updated_at"}
|
69
69
|
end
|
70
70
|
|
71
|
-
it
|
71
|
+
it 'should diff date col and datetime col with AS' do
|
72
72
|
sql = compile((@table[:updated_at] - @table[:created_at]).as('new_name'))
|
73
73
|
# sql.must_be_like %{(TO_DATE("users"."updated_at") - "users"."created_at") * 86400 AS new_name}
|
74
74
|
_(sql).must_be_like %{("users"."updated_at" - "users"."created_at") * (CASE WHEN (TRUNC("users"."updated_at", 'DDD') = "users"."updated_at") THEN 1 ELSE 86400 END) AS new_name}
|
75
75
|
end
|
76
76
|
|
77
|
-
it
|
78
|
-
d2 = Time.new(2015,6,1)
|
79
|
-
d1 = DateTime.new(2015,6,2)
|
80
|
-
_(compile(ArelExtensions::Nodes::DateDiff.new([d1,d2])))
|
77
|
+
it 'should diff between time values' do
|
78
|
+
d2 = Time.new(2015, 6, 1)
|
79
|
+
d1 = DateTime.new(2015, 6, 2)
|
80
|
+
_(compile(ArelExtensions::Nodes::DateDiff.new([d1, d2])))
|
81
81
|
.must_match("TO_DATE('2015-06-02') - TO_DATE('2015-06-01')")
|
82
82
|
end
|
83
83
|
|
84
|
-
it
|
85
|
-
d1 = DateTime.new(2015,6,2)
|
84
|
+
it 'should diff between time values and time col' do
|
85
|
+
d1 = DateTime.new(2015, 6, 2)
|
86
86
|
_(compile(ArelExtensions::Nodes::DateDiff.new([d1, @table[:updated_at]])))
|
87
87
|
.must_match %{TO_DATE('2015-06-02') - "users"."updated_at"}
|
88
88
|
end
|
89
89
|
|
90
|
-
it
|
90
|
+
it 'should accept operators on dates with numbers' do
|
91
91
|
c = @table[:created_at]
|
92
92
|
_(compile(c - 42)).must_be_like %{DATE_SUB("users"."created_at", 42)}
|
93
93
|
_(compile(c - @table[:id])).must_be_like %{DATE_SUB("users"."created_at", "users"."id")}
|
94
94
|
end
|
95
95
|
|
96
96
|
# Maths on sums
|
97
|
-
it
|
97
|
+
it 'should accept math operators on anything' do
|
98
98
|
c = @table[:name]
|
99
99
|
_((c == 'test').to_sql).must_be_like %{"users"."name" = 'test'}
|
100
100
|
_((c != 'test').to_sql).must_be_like %{"users"."name" != 'test'}
|
@@ -6,12 +6,12 @@ module ArelExtensions
|
|
6
6
|
describe 'the to_sql visitor' do
|
7
7
|
before do
|
8
8
|
if Arel::Table.engine.is_a?(ActiveRecord::Base)
|
9
|
-
puts
|
9
|
+
puts 'This is a hack.'
|
10
10
|
# As a matter of fact, if the whole if-block is removed, the to_sql
|
11
11
|
# test become flaky.
|
12
12
|
#
|
13
13
|
# The first time `Arel::Table.engine` is called
|
14
|
-
# from `
|
14
|
+
# from `ArelExtensions.column_of_via_arel_table(table_name, column_name)`
|
15
15
|
# in `lib/arel_extensions/helpers.rb`
|
16
16
|
# will almost always fail. It's important to note that when the test
|
17
17
|
# fails, it's always on 1 test case, and every subsequent test that
|
@@ -43,19 +43,19 @@ module ArelExtensions
|
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
|
-
describe
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
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
52
|
|
53
|
-
|
54
|
-
|
53
|
+
_([c == 1, c == 1].uniq).must_equal [c == 1]
|
54
|
+
end
|
55
55
|
end
|
56
56
|
|
57
57
|
# Math Functions
|
58
|
-
it
|
58
|
+
it 'should not break Arel functions' do
|
59
59
|
_(compile(@price + 42)).must_be_like %{("products"."price" + 42)}
|
60
60
|
_(compile(@table[:id] + @table[:pas_en_base]))
|
61
61
|
.must_be_like %{("users"."id" + "users"."pas_en_base")}
|
@@ -71,7 +71,7 @@ module ArelExtensions
|
|
71
71
|
.must_be_like %{"users"."pas_en_base" * "users"."id"}
|
72
72
|
end
|
73
73
|
|
74
|
-
it
|
74
|
+
it 'should return right calculations on numbers' do
|
75
75
|
# puts (@price.abs + 42).inspect
|
76
76
|
_(compile(@price.abs + 42)).must_be_like %{(ABS("products"."price") + 42)}
|
77
77
|
_(compile(@price.ceil + 42)).must_be_like %{(CEIL("products"."price") + 42)}
|
@@ -108,7 +108,7 @@ module ArelExtensions
|
|
108
108
|
end
|
109
109
|
|
110
110
|
# String Functions
|
111
|
-
it
|
111
|
+
it 'should accept functions on strings' do
|
112
112
|
c = @table[:name]
|
113
113
|
_(compile(c + 'test')).must_be_like %{CONCAT(\"users\".\"name\", 'test')}
|
114
114
|
_(compile(c.length)).must_be_like %{LENGTH("users"."name")}
|
@@ -135,7 +135,7 @@ module ArelExtensions
|
|
135
135
|
|
136
136
|
# some optimization on concat
|
137
137
|
_(compile(c + 'test' + ' chain')).must_be_like %{CONCAT(\"users\".\"name\", 'test chain')}
|
138
|
-
_(compile(Arel
|
138
|
+
_(compile(Arel.quoted('test') + ' chain')).must_be_like %{'test chain'}
|
139
139
|
_(compile(c + '' + c)).must_be_like %{CONCAT(\"users\".\"name\", \"users\".\"name\")}
|
140
140
|
|
141
141
|
_(compile(c.md5)).must_be_like %{MD5(\"users\".\"name\")}
|
@@ -143,7 +143,7 @@ module ArelExtensions
|
|
143
143
|
|
144
144
|
# Comparators
|
145
145
|
|
146
|
-
it
|
146
|
+
it 'should accept comparators on integers' do
|
147
147
|
_(compile(@table[:id] == 42)).must_match %{"users"."id" = 42}
|
148
148
|
_(compile(@table[:id] == @table[:id])).must_be_like %{"users"."id" = "users"."id"}
|
149
149
|
_(compile(@table[:id] != 42)).must_match %{"users"."id" != 42}
|
@@ -159,7 +159,7 @@ module ArelExtensions
|
|
159
159
|
# _(compile(@table[:id].count >= 42)).must_match %{COUNT("users"."id") >= 42}
|
160
160
|
end
|
161
161
|
|
162
|
-
it
|
162
|
+
it 'should accept comparators on dates' do
|
163
163
|
c = @table[:created_at]
|
164
164
|
u = @table[:updated_at]
|
165
165
|
_(compile(c > @date)).must_be_like %{"users"."created_at" > '2016-03-31'}
|
@@ -167,7 +167,7 @@ module ArelExtensions
|
|
167
167
|
_(compile(c < u)).must_be_like %{"users"."created_at" < "users"."updated_at"}
|
168
168
|
end
|
169
169
|
|
170
|
-
it
|
170
|
+
it 'should accept comparators on strings' do
|
171
171
|
c = @table[:name]
|
172
172
|
_(compile(c == 'test')).must_be_like %{"users"."name" = 'test'}
|
173
173
|
_(compile(c != 'test')).must_be_like %{"users"."name" != 'test'}
|
@@ -183,33 +183,33 @@ module ArelExtensions
|
|
183
183
|
|
184
184
|
# Maths
|
185
185
|
# DateDiff
|
186
|
-
it
|
186
|
+
it 'should diff date col and date' do
|
187
187
|
_(compile(@table[:created_at] - Date.new(2016, 3, 31))).must_match %{DATEDIFF("users"."created_at", '2016-03-31')}
|
188
188
|
end
|
189
189
|
|
190
|
-
it
|
190
|
+
it 'should diff date col and datetime col' do
|
191
191
|
_(compile(@table[:created_at] - @table[:updated_at])).must_match %{DATEDIFF("users"."created_at", "users"."updated_at")}
|
192
192
|
end
|
193
193
|
|
194
|
-
it
|
194
|
+
it 'should diff date col and datetime col with AS' do
|
195
195
|
_(compile((@table[:updated_at] - @table[:created_at]).as('new_name')))
|
196
196
|
.must_match %{TIMEDIFF("users"."updated_at", "users"."created_at") AS new_name}
|
197
197
|
end
|
198
198
|
|
199
|
-
it
|
200
|
-
d2 = Time.new(2015,6,1)
|
201
|
-
d1 = DateTime.new(2015,6,2)
|
199
|
+
it 'should diff between time values' do
|
200
|
+
d2 = Time.new(2015, 6, 1)
|
201
|
+
d1 = DateTime.new(2015, 6, 2)
|
202
202
|
_(compile(ArelExtensions::Nodes::DateDiff.new([d1, d2])))
|
203
203
|
.must_match("DATEDIFF('2015-06-02', '2015-06-01')")
|
204
204
|
end
|
205
205
|
|
206
|
-
it
|
207
|
-
d1 = DateTime.new(2015,6,2)
|
206
|
+
it 'should diff between time values and time col' do
|
207
|
+
d1 = DateTime.new(2015, 6, 2)
|
208
208
|
_(compile(ArelExtensions::Nodes::DateDiff.new([d1, @table[:updated_at]])))
|
209
209
|
.must_match %{DATEDIFF('2015-06-02', "users"."updated_at")}
|
210
210
|
end
|
211
211
|
|
212
|
-
it
|
212
|
+
it 'should diff between date col and duration' do
|
213
213
|
d1 = 10
|
214
214
|
d2 = -10
|
215
215
|
_(compile(@table[:created_at] - d1))
|
@@ -218,7 +218,7 @@ module ArelExtensions
|
|
218
218
|
.must_match %{DATE_SUB("users"."created_at", -10)}
|
219
219
|
end
|
220
220
|
|
221
|
-
it
|
221
|
+
it 'should accept operators on dates with numbers' do
|
222
222
|
c = @table[:created_at]
|
223
223
|
# u = @table[:updated_at]
|
224
224
|
_(compile(c - 42)).must_be_like %{DATE_SUB("users"."created_at", 42)}
|
@@ -226,7 +226,7 @@ module ArelExtensions
|
|
226
226
|
end
|
227
227
|
|
228
228
|
# Maths on sums
|
229
|
-
it
|
229
|
+
it 'should accept math operators on anything' do
|
230
230
|
c = @table[:name]
|
231
231
|
_((c == 'test').to_sql)
|
232
232
|
.must_be_like %{"users"."name" = 'test'}
|
@@ -240,7 +240,7 @@ module ArelExtensions
|
|
240
240
|
_(compile(c !~ /\Ate\Dst\Z/)).must_be_like %{"users"."name" NOT REGEXP '^te[^0-9]st$'}
|
241
241
|
end
|
242
242
|
|
243
|
-
it
|
243
|
+
it 'should manage complex formulas' do
|
244
244
|
c = @table[:name]
|
245
245
|
_(compile(
|
246
246
|
(c.length / 42).round(2).floor > (@table[:updated_at] - Date.new(2000, 3, 31)).abs.ceil
|
@@ -248,7 +248,7 @@ module ArelExtensions
|
|
248
248
|
.must_be_like %{FLOOR(ROUND(LENGTH("users"."name") / 42, 2)) > CEIL(ABS(TIMEDIFF("users"."updated_at", '2000-03-31 00:00:00 UTC')))}
|
249
249
|
end
|
250
250
|
|
251
|
-
it
|
251
|
+
it 'should accept aggregator like GROUP CONCAT' do
|
252
252
|
_(@table.project(@table[:first_name].group_concat).group(@table[:last_name]).to_sql)
|
253
253
|
.must_be_like %{SELECT GROUP_CONCAT("users"."first_name") FROM "users" GROUP BY "users"."last_name"}
|
254
254
|
_(@table.project(@table[:first_name].group_concat('++')).group(@table[:last_name]).to_sql)
|
@@ -256,7 +256,7 @@ module ArelExtensions
|
|
256
256
|
end
|
257
257
|
|
258
258
|
# Unions
|
259
|
-
it
|
259
|
+
it 'should accept union operators on queries and union nodes' do
|
260
260
|
c = @table.project(@table[:name])
|
261
261
|
_(compile(c + c))
|
262
262
|
.must_be_like %{(SELECT "users"."name" FROM "users") UNION (SELECT "users"."name" FROM "users")}
|
@@ -273,46 +273,46 @@ module ArelExtensions
|
|
273
273
|
c = @table.project(@table[:name])
|
274
274
|
_(compile(c.union_all(c)))
|
275
275
|
.must_be_like %{(SELECT "users"."name" FROM "users") UNION ALL (SELECT "users"."name" FROM "users")}
|
276
|
-
_(
|
276
|
+
_(c.union_all(c).to_sql)
|
277
277
|
.must_be_like %{(SELECT "users"."name" FROM "users") UNION ALL (SELECT "users"."name" FROM "users")}
|
278
|
-
_(
|
278
|
+
_(c.union_all(c.union_all(c)).to_sql)
|
279
279
|
.must_be_like %{(SELECT "users"."name" FROM "users") UNION ALL (SELECT "users"."name" FROM "users") UNION ALL (SELECT "users"."name" FROM "users")}
|
280
|
-
_((
|
280
|
+
_((c.union_all(c)).union_all(c).to_sql)
|
281
281
|
.must_be_like %{(SELECT "users"."name" FROM "users") UNION ALL (SELECT "users"."name" FROM "users") UNION ALL (SELECT "users"."name" FROM "users")}
|
282
|
-
_(
|
282
|
+
_(c.union_all(c).union_all(c).to_sql)
|
283
283
|
.must_be_like %{(SELECT "users"."name" FROM "users") UNION ALL (SELECT "users"."name" FROM "users") UNION ALL (SELECT "users"."name" FROM "users")}
|
284
284
|
_((c.union_all(c)).as('union_table').to_sql)
|
285
285
|
.must_be_like %{((SELECT "users"."name" FROM "users") UNION ALL (SELECT "users"."name" FROM "users")) union_table}
|
286
286
|
end
|
287
287
|
|
288
288
|
# Case
|
289
|
-
it
|
290
|
-
_(@table[:name].when(
|
289
|
+
it 'should accept case clause' do
|
290
|
+
_(@table[:name].when('smith').then('cool').when('doe').then('fine').else('uncool').to_sql)
|
291
291
|
.must_be_like %{CASE "users"."name" WHEN 'smith' THEN 'cool' WHEN 'doe' THEN 'fine' ELSE 'uncool' END}
|
292
|
-
_(@table[:name].when(
|
292
|
+
_(@table[:name].when('smith').then(1).when('doe').then(2).else(0).to_sql)
|
293
293
|
.must_be_like %{CASE "users"."name" WHEN 'smith' THEN 1 WHEN 'doe' THEN 2 ELSE 0 END}
|
294
|
-
_(
|
294
|
+
_(Arel.when(@table[:name] == 'smith').then(1).when(@table[:name] == 'doe').then(2).else(0).to_sql)
|
295
295
|
.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(
|
296
|
+
_(ArelExtensions::Nodes::Case.new(@table[:name]).when('smith').then(1).when('doe').then(2).else(0).to_sql)
|
297
297
|
.must_be_like %{CASE "users"."name" WHEN 'smith' THEN 1 WHEN 'doe' THEN 2 ELSE 0 END}
|
298
|
-
_(@table[:name].when(
|
298
|
+
_(@table[:name].when('smith').then(1).when('doe').then(2).else(0).sum.to_sql)
|
299
299
|
.must_be_like %{SUM(CASE "users"."name" WHEN 'smith' THEN 1 WHEN 'doe' THEN 2 ELSE 0 END)}
|
300
|
-
_(@table[:name].when(
|
300
|
+
_(@table[:name].when('smith').then('cool').else('uncool').matches('value', false).to_sql)
|
301
301
|
.must_be_like %{CASE "users"."name" WHEN 'smith' THEN 'cool' ELSE 'uncool' END LIKE 'value'}
|
302
|
-
_(@table[:name].when(
|
302
|
+
_(@table[:name].when('smith').then('cool').else('uncool').imatches('value', false).to_sql)
|
303
303
|
.must_be_like %{CASE "users"."name" WHEN 'smith' THEN 'cool' ELSE 'uncool' END ILIKE 'value'}
|
304
304
|
end
|
305
305
|
|
306
|
-
it
|
306
|
+
it 'should be possible to use as/xas on anything' do
|
307
307
|
{
|
308
308
|
@table[:name] => %{"users"."name" AS alias},
|
309
309
|
@table[:name].concat(' test') => %{CONCAT("users"."name", ' test') AS alias},
|
310
310
|
(@table[:name] + ' test') => %{CONCAT("users"."name", ' test') AS alias},
|
311
311
|
(@table[:age] + 42) => %{("users"."age" + 42) AS alias},
|
312
312
|
@table[:name].coalesce('') => %{COALESCE("users"."name", '') AS alias},
|
313
|
-
Arel
|
313
|
+
Arel.quoted('test') => %{'test' AS alias},
|
314
314
|
@table.project(@table[:name]) => %{(SELECT "users"."name" FROM "users") "alias"},
|
315
|
-
@table[:name].when(
|
315
|
+
@table[:name].when('smith').then('cool').else('uncool') => %{CASE "users"."name" WHEN 'smith' THEN 'cool' ELSE 'uncool' END AS alias},
|
316
316
|
}.each do |exp, res|
|
317
317
|
_(compile(exp.as('alias'))).must_be_like res
|
318
318
|
_(compile(exp.xas('alias'))).must_be_like res
|
@@ -322,24 +322,24 @@ module ArelExtensions
|
|
322
322
|
end
|
323
323
|
end
|
324
324
|
|
325
|
-
it
|
325
|
+
it 'should accept comparators on functions' do
|
326
326
|
c = @table[:name]
|
327
327
|
_(compile(c.soundex == 'test')).must_be_like %{SOUNDEX("users"."name") = 'test'}
|
328
328
|
_(compile(c.soundex != 'test')).must_be_like %{SOUNDEX("users"."name") != 'test'}
|
329
329
|
_(compile(c.length >= 0)).must_be_like %{LENGTH("users"."name") >= 0}
|
330
330
|
end
|
331
331
|
|
332
|
-
it
|
332
|
+
it 'should accept in on select statement' do
|
333
333
|
c = @table[:name]
|
334
334
|
_(compile(c.in(@table.project(@table[:name]))))
|
335
335
|
.must_be_like %{"users"."name" IN (SELECT "users"."name" FROM "users")}
|
336
336
|
end
|
337
337
|
|
338
|
-
it
|
338
|
+
it 'should accept coalesce function properly even on none actual tables and attributes' do
|
339
339
|
fake_at = Arel::Table.new('fake_table')
|
340
340
|
_(compile(fake_at['fake_attribute'].coalesce('other_value')))
|
341
341
|
.must_be_like %{COALESCE("fake_table"."fake_attribute", 'other_value')}
|
342
|
-
_(compile(fake_at['fake_attribute'].coalesce('other_value1','other_value2')))
|
342
|
+
_(compile(fake_at['fake_attribute'].coalesce('other_value1', 'other_value2')))
|
343
343
|
.must_be_like %{COALESCE("fake_table"."fake_attribute", 'other_value1', 'other_value2')}
|
344
344
|
_(compile(fake_at['fake_attribute'].coalesce('other_value1').coalesce('other_value2')))
|
345
345
|
.must_be_like %{COALESCE(COALESCE("fake_table"."fake_attribute", 'other_value1'), 'other_value2')}
|
@@ -349,7 +349,7 @@ module ArelExtensions
|
|
349
349
|
.must_be_like %{COALESCE("fake_table"."fake_attribute", 'other_value') ILIKE 'truc'}
|
350
350
|
end
|
351
351
|
|
352
|
-
it
|
352
|
+
it 'should be possible to cast nodes types' do
|
353
353
|
_(compile(@table[:id].cast('char')))
|
354
354
|
.must_be_like %{CAST("users"."id" AS char)}
|
355
355
|
_(compile(@table[:id].coalesce(' ').cast('char')))
|
@@ -364,34 +364,34 @@ module ArelExtensions
|
|
364
364
|
.must_be_like %{(CAST("users"."id" AS int) + 2)}
|
365
365
|
end
|
366
366
|
|
367
|
-
describe
|
368
|
-
it
|
367
|
+
describe 'the function in' do
|
368
|
+
it 'should be possible to have nil element in the function IN' do
|
369
369
|
_(compile(@table[:id].in(nil)))
|
370
370
|
.must_be_like %{ISNULL("users"."id")}
|
371
371
|
_(compile(@table[:id].in([nil])))
|
372
372
|
.must_be_like %{ISNULL("users"."id")}
|
373
|
-
_(compile(@table[:id].in([nil,1])))
|
373
|
+
_(compile(@table[:id].in([nil, 1])))
|
374
374
|
.must_be_like %{(ISNULL("users"."id")) OR ("users"."id" = 1)}
|
375
|
-
_(compile(@table[:id].in([nil,1,2])))
|
375
|
+
_(compile(@table[:id].in([nil, 1, 2])))
|
376
376
|
.must_be_like %{(ISNULL("users"."id")) OR ("users"."id" IN (1, 2))}
|
377
377
|
_(compile(@table[:id].in(1)))
|
378
378
|
.must_be_like %{"users"."id" IN (1)}
|
379
379
|
_(compile(@table[:id].in([1])))
|
380
380
|
.must_be_like %{"users"."id" = 1}
|
381
|
-
_(compile(@table[:id].in([1,2])))
|
381
|
+
_(compile(@table[:id].in([1, 2])))
|
382
382
|
.must_be_like %{"users"."id" IN (1, 2)}
|
383
383
|
_(compile(@table[:id].in([])))
|
384
384
|
.must_be_like %{1 = 0}
|
385
385
|
end
|
386
386
|
|
387
|
-
it
|
387
|
+
it 'should be possible to correctly use a Range on an IN' do
|
388
388
|
_(compile(@table[:id].in(1..4)))
|
389
389
|
.must_be_like %{"users"."id" BETWEEN (1) AND (4)}
|
390
390
|
_(compile(@table[:created_at].in(Date.new(2016, 3, 31)..Date.new(2017, 3, 31))))
|
391
391
|
.must_be_like %{"users"."created_at" BETWEEN ('2016-03-31') AND ('2017-03-31')}
|
392
392
|
end
|
393
393
|
|
394
|
-
it
|
394
|
+
it 'should be possible to use a list of values and ranges on an IN' do
|
395
395
|
_(compile(@table[:id].in [1..10, 20, 30, 40..50]))
|
396
396
|
.must_be_like %{("users"."id" IN (20, 30)) OR ("users"."id" BETWEEN (1) AND (10)) OR ("users"."id" BETWEEN (40) AND (50))}
|
397
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))))
|
@@ -400,7 +400,7 @@ module ArelExtensions
|
|
400
400
|
OR ("users"."created_at" BETWEEN ('2016-03-31') AND ('2017-03-31'))}
|
401
401
|
end
|
402
402
|
|
403
|
-
it
|
403
|
+
it 'should respecting Grouping' do
|
404
404
|
g = ->(*v) { Arel.grouping(v) }
|
405
405
|
_(compile(g[@table[:id], @table[:age]].in [g[1, 42]]))
|
406
406
|
.must_be_like %{("users"."id", "users"."age") IN ((1, 42))}
|
@@ -412,27 +412,27 @@ module ArelExtensions
|
|
412
412
|
end
|
413
413
|
end
|
414
414
|
|
415
|
-
describe
|
416
|
-
it
|
415
|
+
describe 'the function not_in' do
|
416
|
+
it 'should be possible to have nil element in the function IN' do
|
417
417
|
_(compile(@table[:id].not_in nil))
|
418
418
|
.must_be_like %{NOT ISNULL("users"."id")}
|
419
419
|
_(compile(@table[:id].not_in [nil]))
|
420
420
|
.must_be_like %{NOT ISNULL("users"."id")}
|
421
|
-
_(compile(@table[:id].not_in [nil,1]))
|
421
|
+
_(compile(@table[:id].not_in [nil, 1]))
|
422
422
|
.must_be_like %{(NOT ISNULL("users"."id")) AND ("users"."id" != 1)}
|
423
|
-
_(compile(@table[:id].not_in [nil,1,2]))
|
423
|
+
_(compile(@table[:id].not_in [nil, 1, 2]))
|
424
424
|
.must_be_like %{(NOT ISNULL("users"."id")) AND ("users"."id" NOT IN (1, 2))}
|
425
425
|
_(compile(@table[:id].not_in 1))
|
426
426
|
.must_be_like %{"users"."id" NOT IN (1)}
|
427
427
|
_(compile(@table[:id].not_in [1]))
|
428
428
|
.must_be_like %{"users"."id" != 1}
|
429
|
-
_(compile(@table[:id].not_in [1,2]))
|
429
|
+
_(compile(@table[:id].not_in [1, 2]))
|
430
430
|
.must_be_like %{"users"."id" NOT IN (1, 2)}
|
431
431
|
_(compile(@table[:id].not_in []))
|
432
432
|
.must_be_like %{1 = 1}
|
433
433
|
end
|
434
434
|
|
435
|
-
it
|
435
|
+
it 'should be possible to correctly use a Range on an IN' do
|
436
436
|
# FIXME: Should use NOT BETWEEN
|
437
437
|
_(compile(@table[:id].not_in 1..4))
|
438
438
|
.must_be_like %{NOT ("users"."id" BETWEEN (1) AND (4))}
|
@@ -441,7 +441,7 @@ module ArelExtensions
|
|
441
441
|
.must_be_like %{NOT ("users"."created_at" BETWEEN ('2016-03-31') AND ('2017-03-31'))}
|
442
442
|
end
|
443
443
|
|
444
|
-
it
|
444
|
+
it 'should be possible to use a list of values and ranges on an IN' do
|
445
445
|
_(compile(@table[:id].not_in [1..10, 20, 30, 40..50]))
|
446
446
|
.must_be_like %{ ("users"."id" NOT IN (20, 30))
|
447
447
|
AND (NOT ("users"."id" BETWEEN (1) AND (10)))
|
@@ -453,26 +453,26 @@ module ArelExtensions
|
|
453
453
|
end
|
454
454
|
end
|
455
455
|
|
456
|
-
it
|
456
|
+
it 'should be possible to add and substract as much as we want' do
|
457
457
|
c = @table[:name]
|
458
|
-
_(compile(c.locate('test')+1))
|
458
|
+
_(compile(c.locate('test') + 1))
|
459
459
|
.must_be_like %{(LOCATE('test', "users"."name") + 1)}
|
460
|
-
_(compile(c.locate('test')-1))
|
460
|
+
_(compile(c.locate('test') - 1))
|
461
461
|
.must_be_like %{(LOCATE('test', "users"."name") - 1)}
|
462
|
-
_(compile(c.locate('test')+c.locate('test')))
|
462
|
+
_(compile(c.locate('test') + c.locate('test')))
|
463
463
|
.must_be_like %{(LOCATE('test', "users"."name") + LOCATE('test', "users"."name"))}
|
464
|
-
_(compile(c.locate('test')+1+c.locate('test')-1 + 1))
|
464
|
+
_(compile(c.locate('test') + 1 + c.locate('test') - 1 + 1))
|
465
465
|
.must_be_like %{((((LOCATE('test', "users"."name") + 1) + LOCATE('test', "users"."name")) - 1) + 1)}
|
466
466
|
end
|
467
467
|
|
468
|
-
it
|
468
|
+
it 'should be possible to add and substract on some nodes' do
|
469
469
|
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,
|
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')}
|
473
473
|
end
|
474
474
|
|
475
|
-
it
|
475
|
+
it 'should be possible to desc and asc on functions' do
|
476
476
|
c = @table[:name]
|
477
477
|
_(compile(c.asc))
|
478
478
|
.must_be_like %{"users"."name" ASC}
|
@@ -480,19 +480,19 @@ module ArelExtensions
|
|
480
480
|
.must_be_like %{SUBSTRING("users"."name", 2) ASC}
|
481
481
|
_(compile(c.substring(2).desc))
|
482
482
|
.must_be_like %{SUBSTRING("users"."name", 2) DESC}
|
483
|
-
_(compile((c.locate('test')+1).asc))
|
483
|
+
_(compile((c.locate('test') + 1).asc))
|
484
484
|
.must_be_like %{(LOCATE('test', "users"."name") + 1) ASC}
|
485
485
|
end
|
486
486
|
|
487
|
-
it
|
487
|
+
it 'should be possible to call Table function on TableAlias' do
|
488
488
|
t = @table
|
489
|
-
a = t.alias(
|
489
|
+
a = t.alias('aliased_users')
|
490
490
|
_(compile(a.join(t).join_sources))
|
491
491
|
.must_be_like %{INNER JOIN \"users\"}
|
492
492
|
end
|
493
493
|
|
494
|
-
describe
|
495
|
-
it
|
494
|
+
describe 'logical functions' do
|
495
|
+
it 'should know about truth' do
|
496
496
|
_(compile(Arel.false))
|
497
497
|
.must_be_like %{1 = 0}
|
498
498
|
|
@@ -500,7 +500,7 @@ module ArelExtensions
|
|
500
500
|
.must_be_like %{1 = 1}
|
501
501
|
end
|
502
502
|
|
503
|
-
it
|
503
|
+
it 'boolean nodes should be variadic' do
|
504
504
|
c = @table[:id]
|
505
505
|
|
506
506
|
_(compile(Arel::Nodes::And.new))
|
@@ -525,8 +525,8 @@ module ArelExtensions
|
|
525
525
|
.must_be_like %{("users"."id" = 1) OR ("users"."id" = 2) OR ("users"."id" = 3)}
|
526
526
|
end
|
527
527
|
|
528
|
-
it
|
529
|
-
skip
|
528
|
+
it 'should know trivial identities' do
|
529
|
+
skip 'For future optimization'
|
530
530
|
c = @table[:id]
|
531
531
|
_(compile(Arel::Nodes::And.new(Arel.true, c == 1)))
|
532
532
|
.must_be_like %{"users"."id" = 1}
|
@@ -543,7 +543,7 @@ module ArelExtensions
|
|
543
543
|
.must_be_like %{"users"."id" = 1}
|
544
544
|
end
|
545
545
|
|
546
|
-
it
|
546
|
+
it 'should be possible to have multiple arguments on an OR or an AND node' do
|
547
547
|
c = @table[:id]
|
548
548
|
_(compile((c == 1).and))
|
549
549
|
.must_be_like %{"users"."id" = 1}
|
@@ -562,7 +562,7 @@ module ArelExtensions
|
|
562
562
|
.must_be_like %{("users"."id" = 1) OR ("users"."id" = 2) OR ("users"."id" = 3)}
|
563
563
|
end
|
564
564
|
|
565
|
-
it
|
565
|
+
it 'should avoid useless nesting' do
|
566
566
|
c = @table[:id]
|
567
567
|
_(compile(((c == 1).and(c == 2)).and ((c == 3).and(c == 4))))
|
568
568
|
.must_be_like %{("users"."id" = 1) AND ("users"."id" = 2) AND ("users"."id" = 3) AND ("users"."id" = 4)}
|
@@ -576,7 +576,7 @@ module ArelExtensions
|
|
576
576
|
end
|
577
577
|
end
|
578
578
|
|
579
|
-
puts "AREL VERSION
|
579
|
+
puts "AREL VERSION: #{Arel::VERSION}"
|
580
580
|
end
|
581
581
|
end
|
582
582
|
end
|