dbee-active_record 2.0.3 → 2.1.2
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/.rubocop.yml +13 -12
- data/.ruby-version +1 -1
- data/.travis.yml +3 -10
- data/CHANGELOG.md +24 -1
- data/README.md +1 -1
- data/dbee-active_record.gemspec +17 -8
- data/exe/.gitkeep +0 -0
- data/lib/dbee/providers/active_record_provider/expression_builder.rb +55 -24
- data/lib/dbee/providers/active_record_provider/maker.rb +37 -0
- data/lib/dbee/providers/active_record_provider/{expression_builder/constraint_maker.rb → makers/constraint.rb} +12 -12
- data/lib/dbee/providers/active_record_provider/{expression_builder/order_maker.rb → makers/order.rb} +9 -9
- data/lib/dbee/providers/active_record_provider/makers/select.rb +81 -0
- data/lib/dbee/providers/active_record_provider/makers/where.rb +111 -0
- data/lib/dbee/providers/active_record_provider/version.rb +1 -1
- data/spec/db_helper.rb +134 -14
- data/spec/dbee/providers/active_record_provider/expression_builder_spec.rb +117 -0
- data/spec/dbee/providers/active_record_provider/makers/where_spec.rb +260 -0
- data/spec/dbee/providers/active_record_provider_spec.rb +101 -3
- data/spec/fixtures/active_record_snapshots/one_table_empty_query.yaml +10 -0
- data/spec/fixtures/active_record_snapshots/one_table_query_with_filters.yaml +24 -16
- data/spec/fixtures/active_record_snapshots/two_table_query_with_aggregation.yaml +71 -0
- data/spec/fixtures/active_record_snapshots/two_table_query_with_pivoting.yaml +88 -0
- data/spec/fixtures/models.yaml +20 -0
- data/spec/spec_helper.rb +5 -1
- metadata +51 -19
- data/lib/dbee/providers/active_record_provider/expression_builder/select_maker.rb +0 -33
- data/lib/dbee/providers/active_record_provider/expression_builder/where_maker.rb +0 -56
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8ec480363c33c49f4dd4cd5de9023b6ddad2f3d8b39ee90b4a67bc282a2b35f3
|
4
|
+
data.tar.gz: 6db9e48a3bb04e73ae91f01c63640b36db530f04a06245462b4e4d72e2f083c0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 694720a4ff3a557ebdf03cf94bb38010e9c52eacbf188c26f4b3e6e6c7adbd08353e31aae214797bbc79e7493f9d53f178b866b017e4c5feba13a23d253b1449
|
7
|
+
data.tar.gz: 7ba4120f8e7ddc71b2f7d2783c854f9f6ac5b1935260fb7c769d96f1e0ac900ffa8cbb2b3233dd7ccd4d3e7b38d4c702dc9a142a29fd45a2258b0e27ad69ad42
|
data/.rubocop.yml
CHANGED
@@ -1,6 +1,15 @@
|
|
1
|
-
|
1
|
+
AllCops:
|
2
|
+
TargetRubyVersion: 2.5
|
3
|
+
NewCops: enable
|
4
|
+
|
5
|
+
Layout/LineLength:
|
2
6
|
Max: 100
|
3
7
|
|
8
|
+
Metrics/AbcSize:
|
9
|
+
Max: 17
|
10
|
+
Exclude:
|
11
|
+
- spec/db_helper.rb
|
12
|
+
|
4
13
|
Metrics/BlockLength:
|
5
14
|
ExcludedMethods:
|
6
15
|
- let
|
@@ -13,18 +22,10 @@ Metrics/BlockLength:
|
|
13
22
|
- spec/dbee/**/*
|
14
23
|
- dbee-active_record.gemspec
|
15
24
|
|
25
|
+
Metrics/ClassLength:
|
26
|
+
Max: 140
|
27
|
+
|
16
28
|
Metrics/MethodLength:
|
17
29
|
Max: 25
|
18
30
|
Exclude:
|
19
31
|
- spec/db_helper.rb
|
20
|
-
|
21
|
-
AllCops:
|
22
|
-
TargetRubyVersion: 2.3
|
23
|
-
|
24
|
-
Metrics/AbcSize:
|
25
|
-
Max: 16
|
26
|
-
Exclude:
|
27
|
-
- spec/db_helper.rb
|
28
|
-
|
29
|
-
Metrics/ClassLength:
|
30
|
-
Max: 125
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.6.
|
1
|
+
2.6.6
|
data/.travis.yml
CHANGED
@@ -6,19 +6,12 @@ services:
|
|
6
6
|
- mysql
|
7
7
|
rvm:
|
8
8
|
# Build on the latest stable of all supported Rubies (https://www.ruby-lang.org/en/downloads/):
|
9
|
-
- 2.
|
10
|
-
- 2.
|
11
|
-
- 2.
|
12
|
-
- 2.6.5
|
9
|
+
- 2.5.8
|
10
|
+
- 2.6.6
|
11
|
+
- 2.7.1
|
13
12
|
env:
|
14
13
|
- AR_VERSION=5
|
15
14
|
- AR_VERSION=6
|
16
|
-
matrix:
|
17
|
-
exclude:
|
18
|
-
- rvm: 2.3.8
|
19
|
-
env: AR_VERSION=6
|
20
|
-
- rvm: 2.4.6
|
21
|
-
env: AR_VERSION=6
|
22
15
|
cache: bundler
|
23
16
|
before_script:
|
24
17
|
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,27 @@
|
|
1
|
-
# 2.
|
1
|
+
# 2.1.2 (October 15th, 2020)
|
2
|
+
|
3
|
+
* Improved test coverage for Where maker
|
4
|
+
* Fixed bug in Where maker which resulted in only IS NULL predicates being generated, even in cases
|
5
|
+
of when IS NOT NULL intended.
|
6
|
+
|
7
|
+
# 2.1.1 (July 15th, 2020)
|
8
|
+
|
9
|
+
### Additions:
|
10
|
+
|
11
|
+
* Implemented Dbee::Query::Field#aggregator
|
12
|
+
* Implemented Dbee::Query::Field#filters
|
13
|
+
* Implemented base case when a Dbee::Query contains no fields
|
14
|
+
|
15
|
+
### Changes:
|
16
|
+
|
17
|
+
* Bumped minimum Ruby version to 2.5
|
18
|
+
|
19
|
+
# 2.0.4 (February 13th, 2020)
|
20
|
+
|
21
|
+
* use Arel#in for Equal filters when there is more than one value
|
22
|
+
* use Arel#not_in for NotEqual filters when there are is than one value
|
23
|
+
|
24
|
+
# 2.0.3 (January 7th, 2020)
|
2
25
|
|
3
26
|
* Added/tested support for Dbee 2.0.3
|
4
27
|
* Added support for Ruby 2.6.5
|
data/README.md
CHANGED
data/dbee-active_record.gemspec
CHANGED
@@ -11,15 +11,23 @@ Gem::Specification.new do |s|
|
|
11
11
|
By default Dbee ships with no underlying SQL generator. This library will plug in ActiveRecord into Dbee and Dbee will use it for SQL generation.
|
12
12
|
DESCRIPTION
|
13
13
|
|
14
|
-
s.authors = ['Matthew Ruggio']
|
15
|
-
s.email = ['mruggio@bluemarblepayroll.com']
|
14
|
+
s.authors = ['Matthew Ruggio', 'Craig Kattner']
|
15
|
+
s.email = ['mruggio@bluemarblepayroll.com', 'ckattner@bluemarblepayroll.com']
|
16
16
|
s.files = `git ls-files`.split("\n")
|
17
17
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
-
s.
|
18
|
+
s.bindir = 'exe'
|
19
|
+
s.executables = []
|
19
20
|
s.homepage = 'https://github.com/bluemarblepayroll/dbee-active_record'
|
20
21
|
s.license = 'MIT'
|
22
|
+
s.metadata = {
|
23
|
+
'bug_tracker_uri' => 'https://github.com/bluemarblepayroll/dbee-active_record/issues',
|
24
|
+
'changelog_uri' => 'https://github.com/bluemarblepayroll/dbee-active_record/blob/master/CHANGELOG.md',
|
25
|
+
'documentation_uri' => 'https://www.rubydoc.info/gems/dbee-active_record',
|
26
|
+
'homepage_uri' => s.homepage,
|
27
|
+
'source_code_uri' => s.homepage
|
28
|
+
}
|
21
29
|
|
22
|
-
s.required_ruby_version = '>= 2.
|
30
|
+
s.required_ruby_version = '>= 2.5'
|
23
31
|
|
24
32
|
ar_version = ENV['AR_VERSION'] || ''
|
25
33
|
|
@@ -34,15 +42,16 @@ Gem::Specification.new do |s|
|
|
34
42
|
end
|
35
43
|
|
36
44
|
s.add_dependency('activerecord', activerecord_version)
|
37
|
-
s.add_dependency('dbee', '~>2', '>=2.
|
45
|
+
s.add_dependency('dbee', '~>2', '>=2.1.1')
|
38
46
|
|
39
47
|
s.add_development_dependency('guard-rspec', '~>4.7')
|
40
48
|
s.add_development_dependency('mysql2', '~>0.5')
|
41
49
|
s.add_development_dependency('pry', '~>0')
|
50
|
+
s.add_development_dependency('pry-byebug')
|
42
51
|
s.add_development_dependency('rake', '~> 13')
|
43
52
|
s.add_development_dependency('rspec', '~> 3.8')
|
44
|
-
s.add_development_dependency('rubocop', '~>0.
|
45
|
-
s.add_development_dependency('simplecov', '~>0.
|
46
|
-
s.add_development_dependency('simplecov-console', '~>0.
|
53
|
+
s.add_development_dependency('rubocop', '~>0.90.0')
|
54
|
+
s.add_development_dependency('simplecov', '~>0.19.0')
|
55
|
+
s.add_development_dependency('simplecov-console', '~>0.7.0')
|
47
56
|
s.add_development_dependency('sqlite3', '~>1')
|
48
57
|
end
|
data/exe/.gitkeep
ADDED
File without changes
|
@@ -7,32 +7,29 @@
|
|
7
7
|
# LICENSE file in the root directory of this source tree.
|
8
8
|
#
|
9
9
|
|
10
|
-
require_relative '
|
11
|
-
require_relative 'expression_builder/order_maker'
|
12
|
-
require_relative 'expression_builder/select_maker'
|
13
|
-
require_relative 'expression_builder/where_maker'
|
10
|
+
require_relative 'maker'
|
14
11
|
|
15
12
|
module Dbee
|
16
13
|
module Providers
|
17
14
|
class ActiveRecordProvider
|
18
15
|
# This class can generate an Arel expression tree.
|
19
|
-
class ExpressionBuilder
|
20
|
-
extend Forwardable
|
21
|
-
|
16
|
+
class ExpressionBuilder < Maker # :nodoc: all
|
22
17
|
class MissingConstraintError < StandardError; end
|
23
18
|
|
24
|
-
def_delegators :statement, :to_sql
|
25
|
-
|
26
19
|
def initialize(model, table_alias_maker, column_alias_maker)
|
27
|
-
|
28
|
-
|
29
|
-
@
|
20
|
+
super(column_alias_maker)
|
21
|
+
|
22
|
+
@model = model
|
23
|
+
@table_alias_maker = table_alias_maker
|
30
24
|
|
31
25
|
clear
|
32
26
|
end
|
33
27
|
|
34
28
|
def clear
|
35
|
-
@
|
29
|
+
@requires_group_by = false
|
30
|
+
@group_by_columns = []
|
31
|
+
@base_table = make_table(model.table, model.name)
|
32
|
+
@select_all = true
|
36
33
|
|
37
34
|
build(base_table)
|
38
35
|
|
@@ -40,6 +37,8 @@ module Dbee
|
|
40
37
|
end
|
41
38
|
|
42
39
|
def add(query)
|
40
|
+
return self unless query
|
41
|
+
|
43
42
|
query.fields.each { |field| add_field(field) }
|
44
43
|
query.sorters.each { |sorter| add_sorter(sorter) }
|
45
44
|
query.filters.each { |filter| add_filter(filter) }
|
@@ -49,13 +48,27 @@ module Dbee
|
|
49
48
|
self
|
50
49
|
end
|
51
50
|
|
51
|
+
def to_sql
|
52
|
+
if requires_group_by
|
53
|
+
@requires_group_by = false
|
54
|
+
statement.group(group_by_columns) unless group_by_columns.empty?
|
55
|
+
@group_by_columns = []
|
56
|
+
end
|
57
|
+
|
58
|
+
return statement.project(select_maker.star(base_table)).to_sql if select_all
|
59
|
+
|
60
|
+
statement.to_sql
|
61
|
+
end
|
62
|
+
|
52
63
|
private
|
53
64
|
|
54
65
|
attr_reader :base_table,
|
55
66
|
:statement,
|
56
67
|
:model,
|
57
68
|
:table_alias_maker,
|
58
|
-
:
|
69
|
+
:requires_group_by,
|
70
|
+
:group_by_columns,
|
71
|
+
:select_all
|
59
72
|
|
60
73
|
def tables
|
61
74
|
@tables ||= {}
|
@@ -70,7 +83,7 @@ module Dbee
|
|
70
83
|
|
71
84
|
key_path = filter.key_path
|
72
85
|
arel_column = key_paths_to_arel_columns[key_path]
|
73
|
-
predicate =
|
86
|
+
predicate = where_maker.make(filter, arel_column)
|
74
87
|
|
75
88
|
build(statement.where(predicate))
|
76
89
|
|
@@ -82,22 +95,40 @@ module Dbee
|
|
82
95
|
|
83
96
|
key_path = sorter.key_path
|
84
97
|
arel_column = key_paths_to_arel_columns[key_path]
|
85
|
-
predicate =
|
98
|
+
predicate = order_maker.make(sorter, arel_column)
|
86
99
|
|
87
100
|
build(statement.order(predicate))
|
88
101
|
|
89
102
|
self
|
90
103
|
end
|
91
104
|
|
105
|
+
def add_filter_key_paths(filters)
|
106
|
+
filters.each_with_object({}) do |filter, memo|
|
107
|
+
arel_key_column = add_key_path(filter.key_path)
|
108
|
+
|
109
|
+
memo[arel_key_column] = filter
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
92
113
|
def add_field(field)
|
93
|
-
|
114
|
+
@select_all = false
|
115
|
+
arel_value_column = add_key_path(field.key_path)
|
116
|
+
arel_key_columns_to_filters = add_filter_key_paths(field.filters)
|
94
117
|
|
95
|
-
|
96
|
-
|
97
|
-
|
118
|
+
predicate = select_maker.make(
|
119
|
+
field,
|
120
|
+
arel_key_columns_to_filters,
|
121
|
+
arel_value_column
|
122
|
+
)
|
98
123
|
|
99
124
|
build(statement.project(predicate))
|
100
125
|
|
126
|
+
if field.aggregator?
|
127
|
+
@requires_group_by = true
|
128
|
+
else
|
129
|
+
group_by_columns << arel_value_column
|
130
|
+
end
|
131
|
+
|
101
132
|
self
|
102
133
|
end
|
103
134
|
|
@@ -123,7 +154,7 @@ module Dbee
|
|
123
154
|
def table(name, model, previous_table)
|
124
155
|
table = make_table(model.table, name)
|
125
156
|
|
126
|
-
on =
|
157
|
+
on = constraint_maker.make(model.constraints, table, previous_table)
|
127
158
|
|
128
159
|
raise MissingConstraintError, "for: #{name}" unless on
|
129
160
|
|
@@ -142,16 +173,16 @@ module Dbee
|
|
142
173
|
end
|
143
174
|
|
144
175
|
def add_key_path(key_path)
|
145
|
-
return if key_paths_to_arel_columns.key?(key_path)
|
176
|
+
return key_paths_to_arel_columns[key_path] if key_paths_to_arel_columns.key?(key_path)
|
146
177
|
|
147
178
|
ancestors = model.ancestors!(key_path.ancestor_names)
|
148
179
|
|
149
180
|
table = traverse_ancestors(ancestors)
|
150
181
|
|
151
182
|
arel_column = table[key_path.column_name]
|
152
|
-
key_paths_to_arel_columns[key_path] = arel_column
|
153
183
|
|
154
|
-
|
184
|
+
# Note that this returns arel_column
|
185
|
+
key_paths_to_arel_columns[key_path] = arel_column
|
155
186
|
end
|
156
187
|
|
157
188
|
def build(new_expression)
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# Copyright (c) 2019-present, Blue Marble Payroll, LLC
|
5
|
+
#
|
6
|
+
# This source code is licensed under the MIT license found in the
|
7
|
+
# LICENSE file in the root directory of this source tree.
|
8
|
+
#
|
9
|
+
|
10
|
+
require_relative 'makers/constraint'
|
11
|
+
require_relative 'makers/order'
|
12
|
+
require_relative 'makers/select'
|
13
|
+
require_relative 'makers/where'
|
14
|
+
|
15
|
+
module Dbee
|
16
|
+
module Providers
|
17
|
+
class ActiveRecordProvider
|
18
|
+
# This class composes all the maker instances into one for use together.
|
19
|
+
class Maker # :nodoc: all
|
20
|
+
def initialize(column_alias_maker)
|
21
|
+
@column_alias_maker = column_alias_maker
|
22
|
+
@constraint_maker = Makers::Constraint.instance
|
23
|
+
@order_maker = Makers::Order.instance
|
24
|
+
@select_maker = Makers::Select.new(column_alias_maker)
|
25
|
+
@where_maker = Makers::Where.instance
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
attr_reader :constraint_maker,
|
31
|
+
:order_maker,
|
32
|
+
:select_maker,
|
33
|
+
:where_maker
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -10,11 +10,21 @@
|
|
10
10
|
module Dbee
|
11
11
|
module Providers
|
12
12
|
class ActiveRecordProvider
|
13
|
-
|
13
|
+
module Makers # :nodoc: all
|
14
14
|
# Can derive constraints for Arel table JOIN statements.
|
15
|
-
class
|
15
|
+
class Constraint
|
16
16
|
include Singleton
|
17
17
|
|
18
|
+
def make(constraints, table, previous_table)
|
19
|
+
constraints.inject(nil) do |memo, constraint|
|
20
|
+
method = CONSTRAINT_RESOLVERS[constraint.class]
|
21
|
+
|
22
|
+
raise ArgumentError, "constraint unhandled: #{constraint.class.name}" unless method
|
23
|
+
|
24
|
+
method.call(constraint, memo, table, previous_table)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
18
28
|
CONCAT_METHOD = lambda do |on, arel_column, value|
|
19
29
|
on ? on.and(arel_column.eq(value)) : arel_column.eq(value)
|
20
30
|
end
|
@@ -44,16 +54,6 @@ module Dbee
|
|
44
54
|
}.freeze
|
45
55
|
|
46
56
|
private_constant :CONSTRAINT_RESOLVERS
|
47
|
-
|
48
|
-
def make(constraints, table, previous_table)
|
49
|
-
constraints.inject(nil) do |memo, constraint|
|
50
|
-
method = CONSTRAINT_RESOLVERS[constraint.class]
|
51
|
-
|
52
|
-
raise ArgumentError, "constraint unhandled: #{constraint.class.name}" unless method
|
53
|
-
|
54
|
-
method.call(constraint, memo, table, previous_table)
|
55
|
-
end
|
56
|
-
end
|
57
57
|
end
|
58
58
|
end
|
59
59
|
end
|
data/lib/dbee/providers/active_record_provider/{expression_builder/order_maker.rb → makers/order.rb}
RENAMED
@@ -10,18 +10,11 @@
|
|
10
10
|
module Dbee
|
11
11
|
module Providers
|
12
12
|
class ActiveRecordProvider
|
13
|
-
|
13
|
+
module Makers # :nodoc: all
|
14
14
|
# Derives Arel#order predicates.
|
15
|
-
class
|
15
|
+
class Order
|
16
16
|
include Singleton
|
17
17
|
|
18
|
-
SORTER_EVALUATORS = {
|
19
|
-
Query::Sorters::Ascending => ->(column) { column },
|
20
|
-
Query::Sorters::Descending => ->(column) { column.desc }
|
21
|
-
}.freeze
|
22
|
-
|
23
|
-
private_constant :SORTER_EVALUATORS
|
24
|
-
|
25
18
|
def make(sorter, arel_column)
|
26
19
|
method = SORTER_EVALUATORS[sorter.class]
|
27
20
|
|
@@ -29,6 +22,13 @@ module Dbee
|
|
29
22
|
|
30
23
|
method.call(arel_column)
|
31
24
|
end
|
25
|
+
|
26
|
+
SORTER_EVALUATORS = {
|
27
|
+
Query::Sorters::Ascending => ->(column) { column },
|
28
|
+
Query::Sorters::Descending => ->(column) { column.desc }
|
29
|
+
}.freeze
|
30
|
+
|
31
|
+
private_constant :SORTER_EVALUATORS
|
32
32
|
end
|
33
33
|
end
|
34
34
|
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# Copyright (c) 2019-present, Blue Marble Payroll, LLC
|
5
|
+
#
|
6
|
+
# This source code is licensed under the MIT license found in the
|
7
|
+
# LICENSE file in the root directory of this source tree.
|
8
|
+
#
|
9
|
+
|
10
|
+
module Dbee
|
11
|
+
module Providers
|
12
|
+
class ActiveRecordProvider
|
13
|
+
module Makers # :nodoc: all
|
14
|
+
# Derives Arel#project predicates.
|
15
|
+
class Select
|
16
|
+
attr_reader :alias_maker
|
17
|
+
|
18
|
+
def initialize(alias_maker)
|
19
|
+
@alias_maker = alias_maker
|
20
|
+
|
21
|
+
freeze
|
22
|
+
end
|
23
|
+
|
24
|
+
def star(arel_table)
|
25
|
+
arel_table[Arel.star]
|
26
|
+
end
|
27
|
+
|
28
|
+
def make(field, arel_key_nodes_to_filters, arel_value_node)
|
29
|
+
column_alias = quote(alias_maker.make(field.display))
|
30
|
+
predicate = expression(field, arel_key_nodes_to_filters, arel_value_node)
|
31
|
+
predicate = aggregate(field, predicate)
|
32
|
+
|
33
|
+
predicate.as(column_alias)
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
AGGREGRATOR_EVALUATORS = {
|
39
|
+
nil => ->(arel_node) { arel_node },
|
40
|
+
Query::Field::Aggregator::AVE => ->(node) { Arel::Nodes::Avg.new([node]) },
|
41
|
+
Query::Field::Aggregator::COUNT => ->(node) { Arel::Nodes::Count.new([node]) },
|
42
|
+
Query::Field::Aggregator::MAX => ->(node) { Arel::Nodes::Max.new([node]) },
|
43
|
+
Query::Field::Aggregator::MIN => ->(node) { Arel::Nodes::Min.new([node]) },
|
44
|
+
Query::Field::Aggregator::SUM => ->(node) { Arel::Nodes::Sum.new([node]) }
|
45
|
+
}.freeze
|
46
|
+
|
47
|
+
private_constant :AGGREGRATOR_EVALUATORS
|
48
|
+
|
49
|
+
def quote(value)
|
50
|
+
ActiveRecord::Base.connection.quote(value)
|
51
|
+
end
|
52
|
+
|
53
|
+
def aggregate(field, predicate)
|
54
|
+
AGGREGRATOR_EVALUATORS[field.aggregator].call(predicate)
|
55
|
+
end
|
56
|
+
|
57
|
+
def expression(field, arel_key_nodes_to_filters, arel_value_node)
|
58
|
+
if field.filters?
|
59
|
+
case_statement = Arel::Nodes::Case.new
|
60
|
+
filter_predicate = make_filter_predicate(arel_key_nodes_to_filters)
|
61
|
+
|
62
|
+
case_statement.when(filter_predicate).then(arel_value_node)
|
63
|
+
else
|
64
|
+
arel_value_node
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def make_filter_predicate(arel_key_nodes_to_filters)
|
69
|
+
predicates = arel_key_nodes_to_filters.map do |arel_key_node, filter|
|
70
|
+
Where.instance.make(filter, arel_key_node)
|
71
|
+
end
|
72
|
+
|
73
|
+
predicates.inject(predicates.shift) do |memo, predicate|
|
74
|
+
memo.and(predicate)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|