arel_extensions 2.1.5 → 2.1.6
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.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +141 -153
- data/NEWS.md +15 -0
- data/README.md +119 -76
- data/appveyor.yml +9 -0
- data/arel_extensions.gemspec +0 -1
- data/gemfiles/{rails4.gemfile → rails4_2.gemfile} +12 -3
- data/gemfiles/{rails5_0.gemfile → rails5.gemfile} +0 -0
- data/gemspecs/arel_extensions-v1.gemspec +0 -1
- data/gemspecs/arel_extensions-v2.gemspec +0 -1
- data/lib/arel_extensions/nodes/case.rb +4 -3
- data/lib/arel_extensions/nodes/rollup.rb +36 -0
- data/lib/arel_extensions/nodes/select.rb +10 -0
- data/lib/arel_extensions/null_functions.rb +16 -0
- data/lib/arel_extensions/string_functions.rb +1 -0
- data/lib/arel_extensions/version.rb +1 -1
- data/lib/arel_extensions/visitors/mssql.rb +93 -0
- data/lib/arel_extensions/visitors/mysql.rb +63 -1
- data/lib/arel_extensions/visitors/oracle.rb +17 -0
- data/lib/arel_extensions/visitors.rb +8 -0
- data/lib/arel_extensions.rb +16 -0
- data/test/with_ar/all_agnostic_test.rb +110 -10
- data/version_v1.rb +1 -1
- data/version_v2.rb +1 -1
- metadata +7 -18
@@ -14,6 +14,52 @@ module ArelExtensions
|
|
14
14
|
'%M' => '%i', '%S' => '%S', '%L' => '', '%N' => '%f', '%z' => ''
|
15
15
|
}.freeze
|
16
16
|
|
17
|
+
# This helper method did not exist in rails < 5.2
|
18
|
+
if !Arel::Visitors::MySQL.method_defined?(:collect_nodes_for)
|
19
|
+
def collect_nodes_for(nodes, collector, spacer, connector = ", ")
|
20
|
+
if nodes&.any?
|
21
|
+
collector << spacer
|
22
|
+
inject_join nodes, collector, connector
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# The whole purpose of this override is to fix the behavior of RollUp.
|
28
|
+
# All other databases treat RollUp sanely, execpt MySQL which requires
|
29
|
+
# that it figures as the last element of a GROUP BY.
|
30
|
+
def visit_Arel_Nodes_SelectCore(o, collector)
|
31
|
+
collector << "SELECT"
|
32
|
+
|
33
|
+
collector = collect_optimizer_hints(o, collector) if self.respond_to?(:collect_optimizer_hinsts)
|
34
|
+
collector = maybe_visit o.set_quantifier, collector
|
35
|
+
|
36
|
+
collect_nodes_for o.projections, collector, " "
|
37
|
+
|
38
|
+
if o.source && !o.source.empty?
|
39
|
+
collector << " FROM "
|
40
|
+
collector = visit o.source, collector
|
41
|
+
end
|
42
|
+
|
43
|
+
# The actual work
|
44
|
+
groups = o.groups
|
45
|
+
rollup = groups.select { |g| g.expr.class == Arel::Nodes::RollUp }.map { |r| r.expr.value }
|
46
|
+
if rollup && !rollup.empty?
|
47
|
+
groups = o.groups.reject { |g| g.expr.class == Arel::Nodes::RollUp }
|
48
|
+
groups << Arel::Nodes::RollUp.new(rollup)
|
49
|
+
end
|
50
|
+
# FIN
|
51
|
+
|
52
|
+
collect_nodes_for o.wheres, collector, " WHERE ", " AND "
|
53
|
+
collect_nodes_for groups, collector, " GROUP BY " # Look ma, I'm viring a group
|
54
|
+
collect_nodes_for o.havings, collector, " HAVING ", " AND "
|
55
|
+
collect_nodes_for o.windows, collector, " WINDOW "
|
56
|
+
|
57
|
+
if o.respond_to?(:comment)
|
58
|
+
maybe_visit o.comment, collector
|
59
|
+
else
|
60
|
+
collector
|
61
|
+
end
|
62
|
+
end
|
17
63
|
|
18
64
|
# Math functions
|
19
65
|
def visit_ArelExtensions_Nodes_Log10 o, collector
|
@@ -138,6 +184,11 @@ module ArelExtensions
|
|
138
184
|
collector
|
139
185
|
end
|
140
186
|
|
187
|
+
def visit_Arel_Nodes_RollUp(o, collector)
|
188
|
+
visit o.expr, collector
|
189
|
+
collector << " WITH ROLLUP"
|
190
|
+
end
|
191
|
+
|
141
192
|
def visit_ArelExtensions_Nodes_GroupConcat o, collector
|
142
193
|
collector << 'GROUP_CONCAT('
|
143
194
|
collector = visit o.left, collector
|
@@ -201,7 +252,18 @@ module ArelExtensions
|
|
201
252
|
end
|
202
253
|
|
203
254
|
def visit_ArelExtensions_Nodes_Format o, collector
|
204
|
-
case
|
255
|
+
# One use case we met is
|
256
|
+
# `case…when…then(valid_date).else(Arel.null).format(…)`.
|
257
|
+
#
|
258
|
+
# In this case, `o.col_type` is `nil` but we have a legitimate type in
|
259
|
+
# the expression to be formatted. The following is a best effort to
|
260
|
+
# infer the proper type.
|
261
|
+
type =
|
262
|
+
o.col_type.nil? && !o.expressions[0].return_type.nil? \
|
263
|
+
? o.expressions[0].return_type \
|
264
|
+
: o.col_type
|
265
|
+
|
266
|
+
case type
|
205
267
|
when :date, :datetime, :time
|
206
268
|
fmt = ArelExtensions::Visitors::strftime_to_format(o.iso_format, DATE_FORMAT_DIRECTIVES)
|
207
269
|
collector << 'DATE_FORMAT('
|
@@ -126,6 +126,11 @@ module ArelExtensions
|
|
126
126
|
collector
|
127
127
|
end
|
128
128
|
|
129
|
+
def visit_Arel_Nodes_RollUp(o, collector)
|
130
|
+
collector << "ROLLUP"
|
131
|
+
grouping_array_or_grouping_element o, collector
|
132
|
+
end
|
133
|
+
|
129
134
|
def visit_ArelExtensions_Nodes_GroupConcat o, collector
|
130
135
|
collector << '(LISTAGG('
|
131
136
|
collector = visit o.left, collector
|
@@ -705,6 +710,18 @@ module ArelExtensions
|
|
705
710
|
collector << ')'
|
706
711
|
collector
|
707
712
|
end
|
713
|
+
|
714
|
+
# Utilized by GroupingSet, Cube & RollUp visitors to
|
715
|
+
# handle grouping aggregation semantics
|
716
|
+
def grouping_array_or_grouping_element(o, collector)
|
717
|
+
if o.expr.is_a? Array
|
718
|
+
collector << "( "
|
719
|
+
visit o.expr, collector
|
720
|
+
collector << " )"
|
721
|
+
else
|
722
|
+
visit o.expr, collector
|
723
|
+
end
|
724
|
+
end
|
708
725
|
end
|
709
726
|
end
|
710
727
|
end
|
@@ -19,6 +19,14 @@ if defined?(Arel::Visitors::SQLServer)
|
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
+
if defined?(Arel::Visitors::DepthFirst)
|
23
|
+
class Arel::Visitors::DepthFirst
|
24
|
+
def visit_Arel_SelectManager o
|
25
|
+
visit o.ast
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
22
30
|
if defined?(Arel::Visitors::MSSQL)
|
23
31
|
class Arel::Visitors::MSSQL
|
24
32
|
include ArelExtensions::Visitors::MSSQL
|
data/lib/arel_extensions.rb
CHANGED
@@ -78,6 +78,8 @@ require 'arel_extensions/nodes/case'
|
|
78
78
|
require 'arel_extensions/nodes/soundex'
|
79
79
|
require 'arel_extensions/nodes/cast'
|
80
80
|
require 'arel_extensions/nodes/json'
|
81
|
+
require 'arel_extensions/nodes/rollup'
|
82
|
+
require 'arel_extensions/nodes/select'
|
81
83
|
|
82
84
|
# It seems like the code in lib/arel_extensions/visitors.rb that is supposed
|
83
85
|
# to inject ArelExtension is not enough. Different versions of the sqlserver
|
@@ -132,6 +134,10 @@ module Arel
|
|
132
134
|
ArelExtensions::Nodes::Rand.new
|
133
135
|
end
|
134
136
|
|
137
|
+
def self.rollup(*args)
|
138
|
+
Arel::Nodes::RollUp.new(args)
|
139
|
+
end
|
140
|
+
|
135
141
|
def self.shorten s
|
136
142
|
Base64.urlsafe_encode64(Digest::MD5.new.digest(s)).tr('=', '').tr('-', '_')
|
137
143
|
end
|
@@ -277,4 +283,14 @@ class Arel::Attributes::Attribute
|
|
277
283
|
collector = engine.connection.visitor.accept self, collector
|
278
284
|
collector.value
|
279
285
|
end
|
286
|
+
|
287
|
+
def rollup
|
288
|
+
Arel::Nodes::RollUp.new([self])
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
class Arel::Nodes::Node
|
293
|
+
def rollup
|
294
|
+
Arel::Nodes::RollUp.new([self])
|
295
|
+
end
|
280
296
|
end
|
@@ -73,6 +73,8 @@ module ArelExtensions
|
|
73
73
|
@neg = User.where(id: u.id)
|
74
74
|
u = User.create age: 15, name: 'Justin', created_at: d, score: 11.0
|
75
75
|
@justin = User.where(id: u.id)
|
76
|
+
u = User.create age: nil, name: 'nilly', created_at: nil, score: nil
|
77
|
+
@nilly = User.where(id: u.id)
|
76
78
|
|
77
79
|
@age = User.arel_table[:age]
|
78
80
|
@name = User.arel_table[:name]
|
@@ -149,7 +151,7 @@ module ArelExtensions
|
|
149
151
|
def test_rand
|
150
152
|
assert 42 != User.select(Arel.rand.as('res')).first.res
|
151
153
|
assert 0 <= User.select(Arel.rand.abs.as('res')).first.res
|
152
|
-
assert_equal
|
154
|
+
assert_equal 10, User.order(Arel.rand).limit(50).count
|
153
155
|
end
|
154
156
|
|
155
157
|
def test_round
|
@@ -186,6 +188,49 @@ module ArelExtensions
|
|
186
188
|
assert User.group(:score).count(:id).values.all?{|e| !e.nil?}
|
187
189
|
end
|
188
190
|
|
191
|
+
def test_rollup
|
192
|
+
skip "sqlite not supported" if $sqlite
|
193
|
+
at = User.arel_table
|
194
|
+
# single
|
195
|
+
q = User.select(at[:name], at[:age].sum).group(Arel::Nodes::RollUp.new([at[:name]]))
|
196
|
+
assert q.to_a.length > 0
|
197
|
+
|
198
|
+
# multi
|
199
|
+
q = User.select(at[:name], at[:score], at[:age].sum).group(Arel::Nodes::RollUp.new([at[:score], at[:name]]))
|
200
|
+
assert q.to_a.length > 0
|
201
|
+
|
202
|
+
# hybrid
|
203
|
+
q = User.select(at[:name], at[:score], at[:age].sum).group(at[:score], Arel::Nodes::RollUp.new([at[:name]]))
|
204
|
+
assert q.to_a.length > 0
|
205
|
+
|
206
|
+
## Using Arel.rollup which is less verbose than the original way
|
207
|
+
|
208
|
+
# simple
|
209
|
+
q = User.select(at[:name], at[:age].sum).group(Arel.rollup(at[:name]))
|
210
|
+
assert q.to_a.length > 0
|
211
|
+
|
212
|
+
# multi
|
213
|
+
q = User.select(at[:name], at[:score], at[:age].sum).group(Arel.rollup([at[:score], at[:name]]))
|
214
|
+
assert q.to_a.length > 0
|
215
|
+
|
216
|
+
# hybrid
|
217
|
+
q = User.select(at[:name], at[:score], at[:age].sum).group(at[:score], Arel.rollup([at[:name]]))
|
218
|
+
assert q.to_a.length > 0
|
219
|
+
|
220
|
+
## Using at[:col].rollup which is handy for single column rollups
|
221
|
+
|
222
|
+
# simple
|
223
|
+
q = User.select(at[:name], at[:age].sum).group(at[:name].rollup)
|
224
|
+
assert q.to_a.length > 0
|
225
|
+
|
226
|
+
q = User.select(at[:name], at[:score], at[:age].sum).group(at[:name].rollup, at[:score].rollup)
|
227
|
+
assert q.to_a.length > 0
|
228
|
+
|
229
|
+
# hybrid
|
230
|
+
q = User.select(at[:name], at[:score], at[:age].sum).group(at[:name], at[:score].rollup)
|
231
|
+
assert q.to_a.length > 0
|
232
|
+
end
|
233
|
+
|
189
234
|
# String Functions
|
190
235
|
def test_concat
|
191
236
|
assert_equal 'Camille Camille', t(@camille, @name + ' ' + @name)
|
@@ -294,16 +339,16 @@ module ArelExtensions
|
|
294
339
|
skip "Sqlite version can't load extension for regexp" if $sqlite && $load_extension_disabled
|
295
340
|
skip 'SQL Server does not know about REGEXP without extensions' if @env_db == 'mssql'
|
296
341
|
assert_equal 1, User.where(@name =~ '^M').count
|
297
|
-
assert_equal
|
342
|
+
assert_equal 8, User.where(@name !~ '^L').count
|
298
343
|
assert_equal 1, User.where(@name =~ /^M/).count
|
299
|
-
assert_equal
|
344
|
+
assert_equal 8, User.where(@name !~ /^L/).count
|
300
345
|
end
|
301
346
|
|
302
347
|
def test_imatches
|
303
348
|
# puts User.where(@name.imatches('m%')).to_sql
|
304
349
|
assert_equal 1, User.where(@name.imatches('m%')).count
|
305
350
|
assert_equal 4, User.where(@name.imatches_any(['L%', '%e'])).count
|
306
|
-
assert_equal
|
351
|
+
assert_equal 8, User.where(@name.idoes_not_match('L%')).count
|
307
352
|
end
|
308
353
|
|
309
354
|
def test_replace
|
@@ -328,8 +373,8 @@ module ArelExtensions
|
|
328
373
|
skip "Sqlite version can't load extension for soundex" if $sqlite && $load_extension_disabled
|
329
374
|
skip "PostgreSql version can't load extension for soundex" if @env_db == 'postgresql'
|
330
375
|
assert_equal 'C540', t(@camille, @name.soundex)
|
331
|
-
assert_equal
|
332
|
-
assert_equal
|
376
|
+
assert_equal 10, User.where(@name.soundex.eq(@name.soundex)).count
|
377
|
+
assert_equal 10, User.where(@name.soundex == @name.soundex).count
|
333
378
|
end
|
334
379
|
|
335
380
|
def test_change_case
|
@@ -374,6 +419,23 @@ module ArelExtensions
|
|
374
419
|
assert_equal 'true', t(@neg, @comments.not_blank.then('true', 'false'))
|
375
420
|
end
|
376
421
|
|
422
|
+
# This test repeats a lot of `test_blank` cases.
|
423
|
+
def test_present
|
424
|
+
if @env_db == 'postgresql'
|
425
|
+
assert_includes [true, 't'], t(@myung, @name.present) # depends of adapter
|
426
|
+
assert_includes [false, 'f'], t(@myung, @comments.present)
|
427
|
+
end
|
428
|
+
assert_equal 1, @myung.where(@name.present).count
|
429
|
+
assert_equal 0, @myung.where(@comments.present).count
|
430
|
+
assert_equal 0, @sophie.where(@comments.present).count
|
431
|
+
assert_equal 0, @camille.where(@comments.present).count
|
432
|
+
|
433
|
+
assert_equal 1, @neg.where(@comments.present).count
|
434
|
+
assert_equal 'true', t(@myung, @name.present.then('true', 'false'))
|
435
|
+
assert_equal 'false', t(@myung, @comments.present.then('true', 'false'))
|
436
|
+
assert_equal 'true', t(@neg, @comments.present.then('true', 'false'))
|
437
|
+
end
|
438
|
+
|
377
439
|
def test_format
|
378
440
|
assert_equal '2016-05-23', t(@lucas, @created_at.format('%Y-%m-%d'))
|
379
441
|
assert_equal '2014/03/03 12:42:00', t(@lucas, @updated_at.format('%Y/%m/%d %H:%M:%S'))
|
@@ -565,6 +627,24 @@ module ArelExtensions
|
|
565
627
|
assert_equal 'Laure10', t(@laure, @comments.coalesce('Laure') + 10)
|
566
628
|
end
|
567
629
|
|
630
|
+
def test_coalesce_blank
|
631
|
+
assert_equal 'Myung', t(@myung, @comments.coalesce_blank('Myung').coalesce_blank('ignored'))
|
632
|
+
assert_equal 'Myung', t(@myung, @comments.coalesce_blank('', ' ', ' ').coalesce_blank('Myung'))
|
633
|
+
assert_equal 'Myung', t(@myung, @comments.coalesce_blank('', ' ', ' ', 'Myung'))
|
634
|
+
assert_equal '2016-05-23', t(@myung, @created_at.coalesce_blank(Date.new(2022, 1, 1)).format('%Y-%m-%d'))
|
635
|
+
assert_equal 'Laure', t(@laure, @comments.coalesce_blank('Laure'))
|
636
|
+
assert_equal 100, t(@test, @age.coalesce_blank(100))
|
637
|
+
assert_equal 20, t(@test, @age.coalesce_blank(20))
|
638
|
+
assert_equal 20, t(@test, @age.coalesce_blank(10) + 10)
|
639
|
+
assert_equal 'Laure10', t(@laure, @comments.coalesce_blank('Laure') + 10)
|
640
|
+
|
641
|
+
skip 'mssql does not support null in case results' if @env_db == 'mssql'
|
642
|
+
|
643
|
+
assert_equal 'Camille concat', t(@camille, @name.coalesce_blank(Arel.null, 'default') + ' concat')
|
644
|
+
assert_equal 'Myung', t(@myung, @comments.coalesce_blank(Arel.null, 'Myung'))
|
645
|
+
assert_equal 'Camille', t(@camille, @name.coalesce_blank(Arel.null, 'default'))
|
646
|
+
end
|
647
|
+
|
568
648
|
# Comparators
|
569
649
|
def test_number_comparator
|
570
650
|
assert_equal 2, User.where(@age < 6).count
|
@@ -577,7 +657,7 @@ module ArelExtensions
|
|
577
657
|
def test_date_comparator
|
578
658
|
d = Date.new(2016, 5, 23)
|
579
659
|
assert_equal 0, User.where(@created_at < d).count
|
580
|
-
assert_equal
|
660
|
+
assert_equal 10, User.where(@created_at >= d).count
|
581
661
|
end
|
582
662
|
|
583
663
|
def test_date_duration
|
@@ -690,6 +770,26 @@ module ArelExtensions
|
|
690
770
|
end
|
691
771
|
end
|
692
772
|
|
773
|
+
def test_if_present
|
774
|
+
assert_nil t(@myung, @comments.if_present)
|
775
|
+
assert_equal 0, t(@myung, @comments.if_present.count)
|
776
|
+
assert_equal 20.16, t(@myung, @score.if_present)
|
777
|
+
assert_equal '2016-05-23', t(@myung, @created_at.if_present.format('%Y-%m-%d'))
|
778
|
+
assert_nil t(@laure, @comments.if_present)
|
779
|
+
|
780
|
+
assert_nil t(@nilly, @duration.if_present.format('%Y-%m-%d'))
|
781
|
+
|
782
|
+
# NOTE: here we're testing the capacity to format a nil value,
|
783
|
+
# however, @comments is a text field, and not a date/datetime field,
|
784
|
+
# so Postgres will rightfully complain when we format the text:
|
785
|
+
# we need to cast it first.
|
786
|
+
if @env_db == 'postgresql'
|
787
|
+
assert_nil t(@laure, @comments.cast(:date).if_present.format('%Y-%m-%d'))
|
788
|
+
else
|
789
|
+
assert_nil t(@laure, @comments.if_present.format('%Y-%m-%d'))
|
790
|
+
end
|
791
|
+
end
|
792
|
+
|
693
793
|
def test_is_null
|
694
794
|
# puts User.where(@age.is_null).select(@name).to_sql
|
695
795
|
# puts @age.is_null
|
@@ -725,7 +825,7 @@ module ArelExtensions
|
|
725
825
|
def test_math_minus
|
726
826
|
d = Date.new(2016, 5, 20)
|
727
827
|
# Datediff
|
728
|
-
assert_equal
|
828
|
+
assert_equal 10, User.where((@created_at - @created_at).eq(0)).count
|
729
829
|
assert_equal 3, @laure.select((@created_at - d).as('res')).first.res.abs.to_i
|
730
830
|
# Substraction
|
731
831
|
assert_equal 0, User.where((@age - 10).eq(50)).count
|
@@ -845,8 +945,8 @@ module ArelExtensions
|
|
845
945
|
|
846
946
|
def test_subquery_with_order
|
847
947
|
skip if ['mssql'].include?(@env_db) && Arel::VERSION.to_i < 10
|
848
|
-
assert_equal
|
849
|
-
assert_equal
|
948
|
+
assert_equal 10, User.where(name: User.select(:name).order(:name)).count
|
949
|
+
assert_equal 10, User.where(@ut[:name].in(@ut.project(@ut[:name]).order(@ut[:name]))).count
|
850
950
|
if !['mysql'].include?(@env_db) # MySql can't have limit in IN subquery
|
851
951
|
assert_equal 2, User.where(name: User.select(:name).order(:name).limit(2)).count
|
852
952
|
# assert_equal 6, User.where(name: User.select(:name).order(:name).offset(2)).count
|
data/version_v1.rb
CHANGED
data/version_v2.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: arel_extensions
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.1.
|
4
|
+
version: 2.1.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yann Azoury
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2022-
|
13
|
+
date: 2022-11-22 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activerecord
|
@@ -40,20 +40,6 @@ dependencies:
|
|
40
40
|
- - "~>"
|
41
41
|
- !ruby/object:Gem::Version
|
42
42
|
version: '5.9'
|
43
|
-
- !ruby/object:Gem::Dependency
|
44
|
-
name: rdoc
|
45
|
-
requirement: !ruby/object:Gem::Requirement
|
46
|
-
requirements:
|
47
|
-
- - ">="
|
48
|
-
- !ruby/object:Gem::Version
|
49
|
-
version: 6.3.1
|
50
|
-
type: :development
|
51
|
-
prerelease: false
|
52
|
-
version_requirements: !ruby/object:Gem::Requirement
|
53
|
-
requirements:
|
54
|
-
- - ">="
|
55
|
-
- !ruby/object:Gem::Version
|
56
|
-
version: 6.3.1
|
57
43
|
- !ruby/object:Gem::Dependency
|
58
44
|
name: rake
|
59
45
|
requirement: !ruby/object:Gem::Requirement
|
@@ -86,6 +72,7 @@ files:
|
|
86
72
|
- ".rubocop.yml"
|
87
73
|
- Gemfile
|
88
74
|
- MIT-LICENSE.txt
|
75
|
+
- NEWS.md
|
89
76
|
- README.md
|
90
77
|
- Rakefile
|
91
78
|
- SQL_Challenges.md
|
@@ -94,8 +81,8 @@ files:
|
|
94
81
|
- arel_extensions.gemspec
|
95
82
|
- functions.html
|
96
83
|
- gemfiles/rails3.gemfile
|
97
|
-
- gemfiles/
|
98
|
-
- gemfiles/
|
84
|
+
- gemfiles/rails4_2.gemfile
|
85
|
+
- gemfiles/rails5.gemfile
|
99
86
|
- gemfiles/rails5_1_4.gemfile
|
100
87
|
- gemfiles/rails5_2.gemfile
|
101
88
|
- gemfiles/rails6.gemfile
|
@@ -150,7 +137,9 @@ files:
|
|
150
137
|
- lib/arel_extensions/nodes/rand.rb
|
151
138
|
- lib/arel_extensions/nodes/repeat.rb
|
152
139
|
- lib/arel_extensions/nodes/replace.rb
|
140
|
+
- lib/arel_extensions/nodes/rollup.rb
|
153
141
|
- lib/arel_extensions/nodes/round.rb
|
142
|
+
- lib/arel_extensions/nodes/select.rb
|
154
143
|
- lib/arel_extensions/nodes/soundex.rb
|
155
144
|
- lib/arel_extensions/nodes/std.rb
|
156
145
|
- lib/arel_extensions/nodes/substring.rb
|