active_record_extended 2.2.0 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +134 -71
- data/lib/active_record_extended/arel/{sql_literal.rb → sql_literal_patch.rb} +2 -2
- data/lib/active_record_extended/arel.rb +1 -1
- data/lib/active_record_extended/patch/array_handler_patch.rb +22 -0
- data/lib/active_record_extended/patch/relation_patch.rb +82 -0
- data/lib/active_record_extended/patch/where_clause_patch.rb +13 -0
- data/lib/active_record_extended/query_methods/either.rb +3 -7
- data/lib/active_record_extended/query_methods/{select.rb → foster_select.rb} +4 -4
- data/lib/active_record_extended/query_methods/json.rb +2 -2
- data/lib/active_record_extended/query_methods/unionize.rb +2 -2
- data/lib/active_record_extended/query_methods/where_chain.rb +94 -92
- data/lib/active_record_extended/query_methods/window.rb +3 -3
- data/lib/active_record_extended/query_methods/with_cte.rb +59 -2
- data/lib/active_record_extended/utilities/order_by.rb +1 -1
- data/lib/active_record_extended/utilities/support.rb +1 -1
- data/lib/active_record_extended/version.rb +1 -1
- data/lib/active_record_extended.rb +55 -4
- metadata +12 -27
- data/lib/active_record_extended/active_record/relation_patch.rb +0 -62
- data/lib/active_record_extended/active_record.rb +0 -25
- data/lib/active_record_extended/patch/5_2/where_clause.rb +0 -11
- data/lib/active_record_extended/predicate_builder/array_handler_decorator.rb +0 -20
@@ -1,119 +1,121 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module ActiveRecordExtended
|
4
|
-
module
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
# Finds Records that contain an element in an array column
|
14
|
-
# User.where.any(tags: 3)
|
15
|
-
# # SELECT user.* FROM user WHERE 3 = ANY(user.tags)
|
16
|
-
def any(opts, *rest)
|
17
|
-
equality_to_function("ANY", opts, rest)
|
18
|
-
end
|
4
|
+
module QueryMethods
|
5
|
+
module WhereChain
|
6
|
+
# Finds Records that have an array column that contain any a set of values
|
7
|
+
# User.where.overlap(tags: [1,2])
|
8
|
+
# # SELECT * FROM users WHERE tags && {1,2}
|
9
|
+
def overlaps(opts, *rest)
|
10
|
+
substitute_comparisons(opts, rest, Arel::Nodes::Overlaps, "overlap")
|
11
|
+
end
|
12
|
+
alias overlap overlaps
|
19
13
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
14
|
+
# Finds Records that contain an element in an array column
|
15
|
+
# User.where.any(tags: 3)
|
16
|
+
# # SELECT user.* FROM user WHERE 3 = ANY(user.tags)
|
17
|
+
def any(opts, *rest)
|
18
|
+
equality_to_function("ANY", opts, rest)
|
19
|
+
end
|
26
20
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
#
|
33
|
-
# HStore Column Type:
|
34
|
-
# User.where.contains(data: { nickname: 'chainer' })
|
35
|
-
# # SELECT user.* FROM user WHERE user.data @> 'nickname' => 'chainer'
|
36
|
-
#
|
37
|
-
# JSONB Column Type:
|
38
|
-
# User.where.contains(data: { nickname: 'chainer' })
|
39
|
-
# # SELECT user.* FROM user WHERE user.data @> {'nickname': 'chainer'}
|
40
|
-
#
|
41
|
-
# This can also be used along side joined tables
|
42
|
-
#
|
43
|
-
# JSONB Column Type Example:
|
44
|
-
# Tag.joins(:user).where.contains(user: { data: { nickname: 'chainer' } })
|
45
|
-
# # SELECT tags.* FROM tags INNER JOIN user on user.id = tags.user_id WHERE user.data @> { nickname: 'chainer' }
|
46
|
-
#
|
47
|
-
def contains(opts, *rest)
|
48
|
-
if ActiveRecordExtended::AR_VERSION_GTE_6_1
|
49
|
-
return substitute_comparisons(opts, rest, Arel::Nodes::Contains, "contains")
|
21
|
+
# Finds Records that contain a single matchable array element
|
22
|
+
# User.where.all(tags: 3)
|
23
|
+
# # SELECT user.* FROM user WHERE 3 = ALL(user.tags)
|
24
|
+
def all(opts, *rest)
|
25
|
+
equality_to_function("ALL", opts, rest)
|
50
26
|
end
|
51
27
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
28
|
+
# Finds Records that contains a nested set elements
|
29
|
+
#
|
30
|
+
# Array Column Type:
|
31
|
+
# User.where.contains(tags: [1, 3])
|
32
|
+
# # SELECT user.* FROM user WHERE user.tags @> {1,3}
|
33
|
+
#
|
34
|
+
# HStore Column Type:
|
35
|
+
# User.where.contains(data: { nickname: 'chainer' })
|
36
|
+
# # SELECT user.* FROM user WHERE user.data @> 'nickname' => 'chainer'
|
37
|
+
#
|
38
|
+
# JSONB Column Type:
|
39
|
+
# User.where.contains(data: { nickname: 'chainer' })
|
40
|
+
# # SELECT user.* FROM user WHERE user.data @> {'nickname': 'chainer'}
|
41
|
+
#
|
42
|
+
# This can also be used along side joined tables
|
43
|
+
#
|
44
|
+
# JSONB Column Type Example:
|
45
|
+
# Tag.joins(:user).where.contains(user: { data: { nickname: 'chainer' } })
|
46
|
+
# # SELECT tags.* FROM tags INNER JOIN user on user.id = tags.user_id WHERE user.data @> { nickname: 'chainer' }
|
47
|
+
#
|
48
|
+
def contains(opts, *rest)
|
49
|
+
if ActiveRecordExtended::AR_VERSION_GTE_6_1
|
50
|
+
return substitute_comparisons(opts, rest, Arel::Nodes::Contains, "contains")
|
51
|
+
end
|
56
52
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
53
|
+
build_where_chain(opts, rest) do |arel|
|
54
|
+
case arel
|
55
|
+
when Arel::Nodes::In, Arel::Nodes::Equality
|
56
|
+
column = left_column(arel) || column_from_association(arel)
|
57
|
+
|
58
|
+
if [:hstore, :jsonb].include?(column.type)
|
59
|
+
Arel::Nodes::ContainsHStore.new(arel.left, arel.right)
|
60
|
+
elsif column.try(:array)
|
61
|
+
Arel::Nodes::ContainsArray.new(arel.left, arel.right)
|
62
|
+
else
|
63
|
+
raise ArgumentError.new("Invalid argument for .where.contains(), got #{arel.class}")
|
64
|
+
end
|
61
65
|
else
|
62
66
|
raise ArgumentError.new("Invalid argument for .where.contains(), got #{arel.class}")
|
63
67
|
end
|
64
|
-
else
|
65
|
-
raise ArgumentError.new("Invalid argument for .where.contains(), got #{arel.class}")
|
66
68
|
end
|
67
69
|
end
|
68
|
-
end
|
69
70
|
|
70
|
-
|
71
|
+
private
|
71
72
|
|
72
|
-
|
73
|
-
|
74
|
-
|
73
|
+
def matchable_column?(col, arel)
|
74
|
+
col.name == arel.left.name.to_s || col.name == arel.left.relation.name.to_s
|
75
|
+
end
|
75
76
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
77
|
+
def column_from_association(arel)
|
78
|
+
assoc = assoc_from_related_table(arel)
|
79
|
+
assoc.klass.columns.detect { |col| matchable_column?(col, arel) } if assoc
|
80
|
+
end
|
80
81
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
82
|
+
def assoc_from_related_table(arel)
|
83
|
+
@scope.klass.reflect_on_association(arel.left.relation.name.to_sym) ||
|
84
|
+
@scope.klass.reflect_on_association(arel.left.relation.name.singularize.to_sym)
|
85
|
+
end
|
85
86
|
|
86
|
-
|
87
|
-
|
88
|
-
|
87
|
+
def left_column(arel)
|
88
|
+
@scope.klass.columns_hash[arel.left.name] || @scope.klass.columns_hash[arel.left.relation.name]
|
89
|
+
end
|
89
90
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
91
|
+
def equality_to_function(function_name, opts, rest)
|
92
|
+
build_where_chain(opts, rest) do |arel|
|
93
|
+
case arel
|
94
|
+
when Arel::Nodes::Equality
|
95
|
+
Arel::Nodes::Equality.new(arel.right, Arel::Nodes::NamedFunction.new(function_name, [arel.left]))
|
96
|
+
else
|
97
|
+
raise ArgumentError.new("Invalid argument for .where.#{function_name.downcase}(), got #{arel.class}")
|
98
|
+
end
|
97
99
|
end
|
98
100
|
end
|
99
|
-
end
|
100
101
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
102
|
+
def substitute_comparisons(opts, rest, arel_node_class, method)
|
103
|
+
build_where_chain(opts, rest) do |arel|
|
104
|
+
case arel
|
105
|
+
when Arel::Nodes::In, Arel::Nodes::Equality
|
106
|
+
arel_node_class.new(arel.left, arel.right)
|
107
|
+
else
|
108
|
+
raise ArgumentError.new("Invalid argument for .where.#{method}(), got #{arel.class}")
|
109
|
+
end
|
108
110
|
end
|
109
111
|
end
|
110
|
-
end
|
111
112
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
113
|
+
def build_where_clause_for(scope, opts, rest)
|
114
|
+
if ActiveRecordExtended::AR_VERSION_GTE_6_1
|
115
|
+
scope.send(:build_where_clause, opts, rest)
|
116
|
+
else
|
117
|
+
scope.send(:where_clause_factory).build(opts, rest)
|
118
|
+
end
|
117
119
|
end
|
118
120
|
end
|
119
121
|
end
|
@@ -122,7 +124,7 @@ end
|
|
122
124
|
module ActiveRecord
|
123
125
|
module QueryMethods
|
124
126
|
class WhereChain
|
125
|
-
prepend ActiveRecordExtended::WhereChain
|
127
|
+
prepend ActiveRecordExtended::QueryMethods::WhereChain
|
126
128
|
|
127
129
|
def build_where_chain(opts, rest, &block)
|
128
130
|
where_clause = build_where_clause_for(@scope, opts, rest)
|
@@ -4,8 +4,8 @@ module ActiveRecordExtended
|
|
4
4
|
module QueryMethods
|
5
5
|
module Window
|
6
6
|
class DefineWindowChain
|
7
|
-
include
|
8
|
-
include
|
7
|
+
include ActiveRecordExtended::Utilities::Support
|
8
|
+
include ActiveRecordExtended::Utilities::OrderBy
|
9
9
|
|
10
10
|
def initialize(scope, window_name)
|
11
11
|
@scope = scope
|
@@ -24,7 +24,7 @@ module ActiveRecordExtended
|
|
24
24
|
end
|
25
25
|
|
26
26
|
class WindowSelectBuilder
|
27
|
-
include
|
27
|
+
include ActiveRecordExtended::Utilities::Support
|
28
28
|
|
29
29
|
def initialize(window_function, args, window_name)
|
30
30
|
@window_function = window_function
|
@@ -4,12 +4,12 @@ module ActiveRecordExtended
|
|
4
4
|
module QueryMethods
|
5
5
|
module WithCTE
|
6
6
|
class WithCTE
|
7
|
-
include
|
7
|
+
include ActiveRecordExtended::Utilities::Support
|
8
8
|
include Enumerable
|
9
9
|
extend Forwardable
|
10
10
|
|
11
11
|
def_delegators :@with_values, :empty?, :blank?, :present?
|
12
|
-
attr_reader :with_values, :with_keys
|
12
|
+
attr_reader :with_values, :with_keys, :materialized_keys, :not_materialized_keys
|
13
13
|
|
14
14
|
# @param [ActiveRecord::Relation] scope
|
15
15
|
def initialize(scope)
|
@@ -33,6 +33,16 @@ module ActiveRecordExtended
|
|
33
33
|
pipe_cte_with!(value)
|
34
34
|
end
|
35
35
|
|
36
|
+
# @return [Boolean]
|
37
|
+
def materialized_key?(key)
|
38
|
+
materialized_keys.include?(key.to_sym)
|
39
|
+
end
|
40
|
+
|
41
|
+
# @return [Boolean]
|
42
|
+
def not_materialized_key?(key)
|
43
|
+
not_materialized_keys.include?(key.to_sym)
|
44
|
+
end
|
45
|
+
|
36
46
|
# @param [Hash, WithCTE] value
|
37
47
|
def pipe_cte_with!(value)
|
38
48
|
return if value.nil? || value.empty?
|
@@ -44,6 +54,10 @@ module ActiveRecordExtended
|
|
44
54
|
# Ensure we follow FIFO pattern.
|
45
55
|
# If the parent has similar CTE alias keys, we want to favor the parent's expressions over its children's.
|
46
56
|
if expression.is_a?(ActiveRecord::Relation) && expression.with_values?
|
57
|
+
# Add child's materialized keys to the parent
|
58
|
+
@materialized_keys += expression.cte.materialized_keys
|
59
|
+
@not_materialized_keys += expression.cte.not_materialized_keys
|
60
|
+
|
47
61
|
pipe_cte_with!(expression.cte)
|
48
62
|
expression.cte.reset!
|
49
63
|
end
|
@@ -58,6 +72,8 @@ module ActiveRecordExtended
|
|
58
72
|
def reset!
|
59
73
|
@with_keys = []
|
60
74
|
@with_values = {}
|
75
|
+
@materialized_keys = Set.new
|
76
|
+
@not_materialized_keys = Set.new
|
61
77
|
end
|
62
78
|
end
|
63
79
|
|
@@ -75,6 +91,32 @@ module ActiveRecordExtended
|
|
75
91
|
scope.cte.pipe_cte_with!(args)
|
76
92
|
end
|
77
93
|
end
|
94
|
+
|
95
|
+
# @param [Hash, WithCTE] args
|
96
|
+
def materialized(args)
|
97
|
+
@scope.tap do |scope|
|
98
|
+
args.each_pair do |name, _expression|
|
99
|
+
sym_name = name.to_sym
|
100
|
+
raise ArgumentError.new("CTE already set as not_materialized") if scope.cte.not_materialized_key?(sym_name)
|
101
|
+
|
102
|
+
scope.cte.materialized_keys << sym_name
|
103
|
+
end
|
104
|
+
scope.cte.pipe_cte_with!(args)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
# @param [Hash, WithCTE] args
|
109
|
+
def not_materialized(args)
|
110
|
+
@scope.tap do |scope|
|
111
|
+
args.each_pair do |name, _expression|
|
112
|
+
sym_name = name.to_sym
|
113
|
+
raise ArgumentError.new("CTE already set as materialized") if scope.cte.materialized_key?(sym_name)
|
114
|
+
|
115
|
+
scope.cte.not_materialized_keys << sym_name
|
116
|
+
end
|
117
|
+
scope.cte.pipe_cte_with!(args)
|
118
|
+
end
|
119
|
+
end
|
78
120
|
end
|
79
121
|
|
80
122
|
# @return [WithCTE]
|
@@ -134,6 +176,9 @@ module ActiveRecordExtended
|
|
134
176
|
cte_statements = cte.map do |name, expression|
|
135
177
|
grouped_expression = cte.generate_grouping(expression)
|
136
178
|
cte_name = cte.to_arel_sql(cte.double_quote(name.to_s))
|
179
|
+
|
180
|
+
grouped_expression = add_materialized_modifier(grouped_expression, cte, name)
|
181
|
+
|
137
182
|
Arel::Nodes::As.new(cte_name, grouped_expression)
|
138
183
|
end
|
139
184
|
|
@@ -143,6 +188,18 @@ module ActiveRecordExtended
|
|
143
188
|
arel.with(cte_statements)
|
144
189
|
end
|
145
190
|
end
|
191
|
+
|
192
|
+
private
|
193
|
+
|
194
|
+
def add_materialized_modifier(expression, cte, name)
|
195
|
+
if cte.materialized_key?(name)
|
196
|
+
Arel::Nodes::SqlLiteral.new("MATERIALIZED #{expression.to_sql}")
|
197
|
+
elsif cte.not_materialized_key?(name)
|
198
|
+
Arel::Nodes::SqlLiteral.new("NOT MATERIALIZED #{expression.to_sql}")
|
199
|
+
else
|
200
|
+
expression
|
201
|
+
end
|
202
|
+
end
|
146
203
|
end
|
147
204
|
end
|
148
205
|
end
|
@@ -49,7 +49,7 @@ module ActiveRecordExtended
|
|
49
49
|
obj.each_pair do |o_key, o_value|
|
50
50
|
new_hash["#{tbl_or_col}.#{o_key}"] = o_value
|
51
51
|
end
|
52
|
-
elsif
|
52
|
+
elsif ActiveRecord::QueryMethods::VALID_DIRECTIONS.include?(obj)
|
53
53
|
new_hash[tbl_or_col] = obj
|
54
54
|
elsif obj.nil?
|
55
55
|
new_hash[tbl_or_col.to_s] = :asc
|
@@ -113,7 +113,7 @@ module ActiveRecordExtended
|
|
113
113
|
case value.to_s
|
114
114
|
# Ignore keys that contain double quotes or a Arel.star (*)[all columns]
|
115
115
|
# or if a table has already been explicitly declared (ex: users.id)
|
116
|
-
when "*", /((^".+"$)|(^[[:alpha:]]+\.[[:alnum:]]+))/
|
116
|
+
when "*", /((^".+"$)|(^[[:alpha:]]+\.[[:alnum:]]+)|\(.+\))/
|
117
117
|
value
|
118
118
|
else
|
119
119
|
PG::Connection.quote_ident(value.to_s)
|
@@ -1,10 +1,61 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "active_record_extended/version"
|
4
|
-
|
5
|
-
require "
|
6
|
-
require "
|
7
|
-
require "
|
4
|
+
|
5
|
+
require "active_record"
|
6
|
+
require "active_record/relation"
|
7
|
+
require "active_record/relation/merger"
|
8
|
+
require "active_record/relation/query_methods"
|
8
9
|
|
9
10
|
module ActiveRecordExtended
|
11
|
+
extend ActiveSupport::Autoload
|
12
|
+
|
13
|
+
AR_VERSION_GTE_6_1 = Gem::Requirement.new(">= 6.1").satisfied_by?(ActiveRecord.gem_version)
|
14
|
+
|
15
|
+
module Utilities
|
16
|
+
extend ActiveSupport::Autoload
|
17
|
+
|
18
|
+
eager_autoload do
|
19
|
+
autoload :OrderBy
|
20
|
+
autoload :Support
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
module Patch
|
25
|
+
extend ActiveSupport::Autoload
|
26
|
+
|
27
|
+
eager_autoload do
|
28
|
+
autoload :ArrayHandlerPatch
|
29
|
+
autoload :RelationPatch
|
30
|
+
autoload :WhereClausePatch
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
module QueryMethods
|
35
|
+
extend ActiveSupport::Autoload
|
36
|
+
|
37
|
+
eager_autoload do
|
38
|
+
autoload :AnyOf
|
39
|
+
autoload :Either
|
40
|
+
autoload :FosterSelect
|
41
|
+
autoload :Inet
|
42
|
+
autoload :Json
|
43
|
+
autoload :Unionize
|
44
|
+
autoload :WhereChain
|
45
|
+
autoload :Window
|
46
|
+
autoload :WithCTE
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.eager_load!
|
51
|
+
super
|
52
|
+
ActiveRecordExtended::Utilities.eager_load!
|
53
|
+
ActiveRecordExtended::Patch.eager_load!
|
54
|
+
ActiveRecordExtended::QueryMethods.eager_load!
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
ActiveSupport.on_load(:active_record) do
|
59
|
+
require "active_record_extended/arel"
|
60
|
+
ActiveRecordExtended.eager_load!
|
10
61
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_record_extended
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- George Protacio-Karaszi
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2022-
|
13
|
+
date: 2022-12-01 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activerecord
|
@@ -32,20 +32,6 @@ dependencies:
|
|
32
32
|
- - "<"
|
33
33
|
- !ruby/object:Gem::Version
|
34
34
|
version: 7.1.0
|
35
|
-
- !ruby/object:Gem::Dependency
|
36
|
-
name: ar_outer_joins
|
37
|
-
requirement: !ruby/object:Gem::Requirement
|
38
|
-
requirements:
|
39
|
-
- - "~>"
|
40
|
-
- !ruby/object:Gem::Version
|
41
|
-
version: '0.2'
|
42
|
-
type: :runtime
|
43
|
-
prerelease: false
|
44
|
-
version_requirements: !ruby/object:Gem::Requirement
|
45
|
-
requirements:
|
46
|
-
- - "~>"
|
47
|
-
- !ruby/object:Gem::Version
|
48
|
-
version: '0.2'
|
49
35
|
- !ruby/object:Gem::Dependency
|
50
36
|
name: pg
|
51
37
|
requirement: !ruby/object:Gem::Requirement
|
@@ -66,7 +52,7 @@ dependencies:
|
|
66
52
|
requirements:
|
67
53
|
- - ">="
|
68
54
|
- !ruby/object:Gem::Version
|
69
|
-
version: '
|
55
|
+
version: '2.2'
|
70
56
|
- - "<"
|
71
57
|
- !ruby/object:Gem::Version
|
72
58
|
version: '3.0'
|
@@ -76,7 +62,7 @@ dependencies:
|
|
76
62
|
requirements:
|
77
63
|
- - ">="
|
78
64
|
- !ruby/object:Gem::Version
|
79
|
-
version: '
|
65
|
+
version: '2.2'
|
80
66
|
- - "<"
|
81
67
|
- !ruby/object:Gem::Version
|
82
68
|
version: '3.0'
|
@@ -86,14 +72,14 @@ dependencies:
|
|
86
72
|
requirements:
|
87
73
|
- - "~>"
|
88
74
|
- !ruby/object:Gem::Version
|
89
|
-
version: '
|
75
|
+
version: '2.0'
|
90
76
|
type: :development
|
91
77
|
prerelease: false
|
92
78
|
version_requirements: !ruby/object:Gem::Requirement
|
93
79
|
requirements:
|
94
80
|
- - "~>"
|
95
81
|
- !ruby/object:Gem::Version
|
96
|
-
version: '
|
82
|
+
version: '2.0'
|
97
83
|
- !ruby/object:Gem::Dependency
|
98
84
|
name: rake
|
99
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -147,21 +133,20 @@ extra_rdoc_files: []
|
|
147
133
|
files:
|
148
134
|
- README.md
|
149
135
|
- lib/active_record_extended.rb
|
150
|
-
- lib/active_record_extended/active_record.rb
|
151
|
-
- lib/active_record_extended/active_record/relation_patch.rb
|
152
136
|
- lib/active_record_extended/arel.rb
|
153
137
|
- lib/active_record_extended/arel/aggregate_function_name.rb
|
154
138
|
- lib/active_record_extended/arel/nodes.rb
|
155
139
|
- lib/active_record_extended/arel/predications.rb
|
156
|
-
- lib/active_record_extended/arel/
|
140
|
+
- lib/active_record_extended/arel/sql_literal_patch.rb
|
157
141
|
- lib/active_record_extended/arel/visitors/postgresql_decorator.rb
|
158
|
-
- lib/active_record_extended/patch/
|
159
|
-
- lib/active_record_extended/
|
142
|
+
- lib/active_record_extended/patch/array_handler_patch.rb
|
143
|
+
- lib/active_record_extended/patch/relation_patch.rb
|
144
|
+
- lib/active_record_extended/patch/where_clause_patch.rb
|
160
145
|
- lib/active_record_extended/query_methods/any_of.rb
|
161
146
|
- lib/active_record_extended/query_methods/either.rb
|
147
|
+
- lib/active_record_extended/query_methods/foster_select.rb
|
162
148
|
- lib/active_record_extended/query_methods/inet.rb
|
163
149
|
- lib/active_record_extended/query_methods/json.rb
|
164
|
-
- lib/active_record_extended/query_methods/select.rb
|
165
150
|
- lib/active_record_extended/query_methods/unionize.rb
|
166
151
|
- lib/active_record_extended/query_methods/where_chain.rb
|
167
152
|
- lib/active_record_extended/query_methods/window.rb
|
@@ -189,7 +174,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
189
174
|
- !ruby/object:Gem::Version
|
190
175
|
version: '0'
|
191
176
|
requirements: []
|
192
|
-
rubygems_version: 3.
|
177
|
+
rubygems_version: 3.3.19
|
193
178
|
signing_key:
|
194
179
|
specification_version: 4
|
195
180
|
summary: Adds extended functionality to Activerecord Postgres implementation
|
@@ -1,62 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "active_record_extended/query_methods/window"
|
4
|
-
require "active_record_extended/query_methods/unionize"
|
5
|
-
require "active_record_extended/query_methods/json"
|
6
|
-
|
7
|
-
module ActiveRecordExtended
|
8
|
-
module RelationPatch
|
9
|
-
module QueryDelegation
|
10
|
-
delegate :with, :define_window, :select_window, :foster_select, to: :all
|
11
|
-
delegate(*::ActiveRecordExtended::QueryMethods::Unionize::UNIONIZE_METHODS, to: :all)
|
12
|
-
delegate(*::ActiveRecordExtended::QueryMethods::Json::JSON_QUERY_METHODS, to: :all)
|
13
|
-
end
|
14
|
-
|
15
|
-
module Merger
|
16
|
-
def merge
|
17
|
-
merge_ctes!
|
18
|
-
merge_union!
|
19
|
-
merge_windows!
|
20
|
-
super
|
21
|
-
end
|
22
|
-
|
23
|
-
def merge_union!
|
24
|
-
return if other.unionize_storage.empty?
|
25
|
-
|
26
|
-
relation.union_values += other.union_values
|
27
|
-
relation.union_operations += other.union_operations
|
28
|
-
relation.union_ordering_values += other.union_ordering_values
|
29
|
-
end
|
30
|
-
|
31
|
-
def merge_windows!
|
32
|
-
return unless other.window_values?
|
33
|
-
|
34
|
-
relation.window_values |= other.window_values
|
35
|
-
end
|
36
|
-
|
37
|
-
def merge_ctes!
|
38
|
-
return unless other.with_values?
|
39
|
-
|
40
|
-
if other.recursive_value? && !relation.recursive_value?
|
41
|
-
relation.with!(:chain).recursive(other.cte)
|
42
|
-
else
|
43
|
-
relation.with!(other.cte)
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
module ArelBuildPatch
|
49
|
-
def build_arel(*aliases)
|
50
|
-
super.tap do |arel|
|
51
|
-
build_windows(arel) if window_values?
|
52
|
-
build_unions(arel) if union_values?
|
53
|
-
build_with(arel) if with_values?
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
ActiveRecord::Relation.prepend(ActiveRecordExtended::RelationPatch::ArelBuildPatch)
|
61
|
-
ActiveRecord::Relation::Merger.prepend(ActiveRecordExtended::RelationPatch::Merger)
|
62
|
-
ActiveRecord::Querying.prepend(ActiveRecordExtended::RelationPatch::QueryDelegation)
|
@@ -1,25 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "active_record"
|
4
|
-
require "active_record/relation"
|
5
|
-
require "active_record/relation/merger"
|
6
|
-
require "active_record/relation/query_methods"
|
7
|
-
|
8
|
-
module ActiveRecordExtended
|
9
|
-
# TODO: Deprecate <= AR 6.0 methods & routines
|
10
|
-
AR_VERSION_GTE_6_1 = Gem::Requirement.new(">= 6.1").satisfied_by?(ActiveRecord.gem_version)
|
11
|
-
end
|
12
|
-
|
13
|
-
require "active_record_extended/predicate_builder/array_handler_decorator"
|
14
|
-
|
15
|
-
require "active_record_extended/active_record/relation_patch"
|
16
|
-
|
17
|
-
require "active_record_extended/query_methods/where_chain"
|
18
|
-
require "active_record_extended/query_methods/with_cte"
|
19
|
-
require "active_record_extended/query_methods/unionize"
|
20
|
-
require "active_record_extended/query_methods/any_of"
|
21
|
-
require "active_record_extended/query_methods/either"
|
22
|
-
require "active_record_extended/query_methods/inet"
|
23
|
-
require "active_record_extended/query_methods/json"
|
24
|
-
require "active_record_extended/query_methods/select"
|
25
|
-
require "active_record_extended/patch/5_2/where_clause"
|
@@ -1,11 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module ActiveRecordExtended
|
4
|
-
module WhereClause
|
5
|
-
def modified_predicates(&block)
|
6
|
-
::ActiveRecord::Relation::WhereClause.new(predicates.map(&block))
|
7
|
-
end
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
ActiveRecord::Relation::WhereClause.prepend(ActiveRecordExtended::WhereClause)
|