rasti-db 1.5.0 → 2.3.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 +52 -19
- data/lib/rasti/db.rb +11 -2
- data/lib/rasti/db/collection.rb +67 -36
- data/lib/rasti/db/computed_attribute.rb +22 -0
- data/lib/rasti/db/data_source.rb +18 -0
- data/lib/rasti/db/environment.rb +32 -0
- data/lib/rasti/db/nql/filter_condition_strategies/base.rb +17 -0
- data/lib/rasti/db/nql/filter_condition_strategies/postgres.rb +21 -0
- data/lib/rasti/db/nql/filter_condition_strategies/sqlite.rb +21 -0
- data/lib/rasti/db/nql/filter_condition_strategies/types/generic.rb +49 -0
- data/lib/rasti/db/nql/filter_condition_strategies/types/pg_array.rb +32 -0
- data/lib/rasti/db/nql/filter_condition_strategies/types/sqlite_array.rb +34 -0
- data/lib/rasti/db/nql/filter_condition_strategies/unsupported_type_comparison.rb +22 -0
- data/lib/rasti/db/nql/nodes/array_content.rb +21 -0
- data/lib/rasti/db/nql/nodes/attribute.rb +37 -0
- data/lib/rasti/db/nql/nodes/binary_node.rb +4 -0
- data/lib/rasti/db/nql/nodes/comparisons/base.rb +15 -1
- data/lib/rasti/db/nql/nodes/comparisons/equal.rb +0 -4
- data/lib/rasti/db/nql/nodes/comparisons/greater_than.rb +0 -4
- data/lib/rasti/db/nql/nodes/comparisons/greater_than_or_equal.rb +0 -4
- data/lib/rasti/db/nql/nodes/comparisons/include.rb +0 -4
- data/lib/rasti/db/nql/nodes/comparisons/less_than.rb +0 -4
- data/lib/rasti/db/nql/nodes/comparisons/less_than_or_equal.rb +0 -4
- data/lib/rasti/db/nql/nodes/comparisons/like.rb +0 -4
- data/lib/rasti/db/nql/nodes/comparisons/not_equal.rb +0 -4
- data/lib/rasti/db/nql/nodes/comparisons/not_include.rb +0 -4
- data/lib/rasti/db/nql/nodes/conjunction.rb +2 -2
- data/lib/rasti/db/nql/nodes/constants/array.rb +17 -0
- data/lib/rasti/db/nql/nodes/constants/base.rb +17 -0
- data/lib/rasti/db/nql/nodes/constants/false.rb +1 -1
- data/lib/rasti/db/nql/nodes/constants/float.rb +1 -1
- data/lib/rasti/db/nql/nodes/constants/integer.rb +1 -1
- data/lib/rasti/db/nql/nodes/constants/literal_string.rb +1 -1
- data/lib/rasti/db/nql/nodes/constants/string.rb +1 -1
- data/lib/rasti/db/nql/nodes/constants/time.rb +1 -1
- data/lib/rasti/db/nql/nodes/constants/true.rb +1 -1
- data/lib/rasti/db/nql/nodes/disjunction.rb +2 -2
- data/lib/rasti/db/nql/nodes/parenthesis_sentence.rb +6 -2
- data/lib/rasti/db/nql/nodes/sentence.rb +6 -2
- data/lib/rasti/db/nql/syntax.rb +262 -44
- data/lib/rasti/db/nql/syntax.treetop +27 -14
- data/lib/rasti/db/query.rb +55 -23
- data/lib/rasti/db/relations/base.rb +22 -8
- data/lib/rasti/db/relations/graph.rb +10 -16
- data/lib/rasti/db/relations/many_to_many.rb +57 -23
- data/lib/rasti/db/relations/many_to_one.rb +9 -7
- data/lib/rasti/db/relations/one_to_many.rb +21 -13
- data/lib/rasti/db/type_converters/sqlite.rb +62 -0
- data/lib/rasti/db/type_converters/sqlite_types/array.rb +34 -0
- data/lib/rasti/db/version.rb +1 -1
- data/rasti-db.gemspec +1 -0
- data/spec/collection_spec.rb +210 -50
- data/spec/computed_attribute_spec.rb +32 -0
- data/spec/minitest_helper.rb +77 -15
- data/spec/model_spec.rb +4 -2
- data/spec/nql/computed_attributes_spec.rb +29 -0
- data/spec/nql/filter_condition_spec.rb +23 -4
- data/spec/nql/filter_condition_strategies_spec.rb +112 -0
- data/spec/nql/syntax_parser_spec.rb +36 -5
- data/spec/query_spec.rb +340 -54
- data/spec/relations_spec.rb +27 -7
- data/spec/type_converters/sqlite_spec.rb +66 -0
- metadata +40 -4
- data/lib/rasti/db/helpers.rb +0 -16
- data/lib/rasti/db/nql/nodes/field.rb +0 -23
@@ -42,44 +42,49 @@ module Rasti
|
|
42
42
|
comparison_equal
|
43
43
|
end
|
44
44
|
|
45
|
-
rule
|
46
|
-
_tables:(table:
|
45
|
+
rule attribute
|
46
|
+
_tables:(table:attribute_name '.')* _column:attribute_name <Nodes::Attribute>
|
47
47
|
end
|
48
48
|
|
49
49
|
rule comparison_include
|
50
|
-
|
50
|
+
attribute:attribute space* comparator:':' space* argument:argument <Nodes::Comparisons::Include>
|
51
51
|
end
|
52
52
|
|
53
53
|
rule comparison_not_include
|
54
|
-
|
54
|
+
attribute:attribute space* comparator:'!:' space* argument:argument <Nodes::Comparisons::NotInclude>
|
55
55
|
end
|
56
56
|
|
57
57
|
rule comparison_like
|
58
|
-
|
58
|
+
attribute:attribute space* comparator:'~' space* argument:argument <Nodes::Comparisons::Like>
|
59
59
|
end
|
60
60
|
|
61
61
|
rule comparison_greater_than
|
62
|
-
|
62
|
+
attribute:attribute space* comparator:'>' space* argument:argument <Nodes::Comparisons::GreaterThan>
|
63
63
|
end
|
64
64
|
|
65
65
|
rule comparison_greater_than_or_equal
|
66
|
-
|
66
|
+
attribute:attribute space* comparator:'>=' space* argument:argument <Nodes::Comparisons::GreaterThanOrEqual>
|
67
67
|
end
|
68
68
|
|
69
69
|
rule comparison_less_than
|
70
|
-
|
70
|
+
attribute:attribute space* comparator:'<' space* argument:argument <Nodes::Comparisons::LessThan>
|
71
71
|
end
|
72
72
|
|
73
73
|
rule comparison_less_than_or_equal
|
74
|
-
|
74
|
+
attribute:attribute space* comparator:'<=' space* argument:argument <Nodes::Comparisons::LessThanOrEqual>
|
75
75
|
end
|
76
76
|
|
77
77
|
rule comparison_not_equal
|
78
|
-
|
78
|
+
attribute:attribute space* comparator:'!=' space* argument:argument <Nodes::Comparisons::NotEqual>
|
79
79
|
end
|
80
80
|
|
81
81
|
rule comparison_equal
|
82
|
-
|
82
|
+
attribute:attribute space* comparator:'=' space* argument:argument <Nodes::Comparisons::Equal>
|
83
|
+
end
|
84
|
+
|
85
|
+
rule argument
|
86
|
+
array /
|
87
|
+
basic
|
83
88
|
end
|
84
89
|
|
85
90
|
rule basic
|
@@ -91,11 +96,19 @@ module Rasti
|
|
91
96
|
string
|
92
97
|
end
|
93
98
|
|
99
|
+
rule array
|
100
|
+
open:'[' space* contents:(array_content / basic) space* close:']' <Nodes::Constants::Array>
|
101
|
+
end
|
102
|
+
|
103
|
+
rule array_content
|
104
|
+
left:basic space* ',' space* right:(array_content / basic) <Nodes::ArrayContent>
|
105
|
+
end
|
106
|
+
|
94
107
|
rule space
|
95
108
|
[\s\t\n]
|
96
109
|
end
|
97
110
|
|
98
|
-
rule
|
111
|
+
rule attribute_name
|
99
112
|
[a-z_]+
|
100
113
|
end
|
101
114
|
|
@@ -130,7 +143,7 @@ module Rasti
|
|
130
143
|
end
|
131
144
|
|
132
145
|
rule valid_character
|
133
|
-
[0-9a-zA-Z
|
146
|
+
[0-9a-zA-ZÁÀÄÂÃÅĀĂǍáàäâãåāăǎÉÈËÊĒĔĖĚéèëêēĕėěÍÌÏÎĨĬǏíìïîĩĭǐÓÒÖÔÕŌŎŐǑóòöôõōŏőǒÚÙÜÛŨŪŬŮŰǓúùüûũūŭůűǔÑñçÇ%@#+\--Z\\^_'?!$*/\s]
|
134
147
|
end
|
135
148
|
|
136
149
|
rule boolean
|
@@ -159,7 +172,7 @@ module Rasti
|
|
159
172
|
end
|
160
173
|
|
161
174
|
rule reserved_character
|
162
|
-
[&|.()
|
175
|
+
[&|.():!=<>~,\]\[]
|
163
176
|
end
|
164
177
|
|
165
178
|
end
|
data/lib/rasti/db/query.rb
CHANGED
@@ -5,13 +5,12 @@ module Rasti
|
|
5
5
|
DATASET_CHAINED_METHODS = [:where, :exclude, :or, :order, :reverse_order, :limit, :offset].freeze
|
6
6
|
|
7
7
|
include Enumerable
|
8
|
-
include Helpers::WithSchema
|
9
8
|
|
10
|
-
def initialize(collection_class:, dataset:, relations_graph:nil
|
9
|
+
def initialize(environment:, collection_class:, dataset:, relations_graph:nil)
|
10
|
+
@environment = environment
|
11
11
|
@collection_class = collection_class
|
12
|
-
@dataset = dataset
|
13
|
-
@relations_graph = relations_graph || Relations::Graph.new(
|
14
|
-
@schema = schema
|
12
|
+
@dataset = dataset.qualify collection_class.collection_name
|
13
|
+
@relations_graph = relations_graph || Relations::Graph.new(environment, collection_class)
|
15
14
|
end
|
16
15
|
|
17
16
|
DATASET_CHAINED_METHODS.each do |method|
|
@@ -58,15 +57,36 @@ module Rasti
|
|
58
57
|
build_query relations_graph: relations_graph.with_all_attributes_for(relations)
|
59
58
|
end
|
60
59
|
|
60
|
+
def select_computed_attributes(*computed_attributes)
|
61
|
+
ds = computed_attributes.inject(dataset) do |ds, name|
|
62
|
+
computed_attribute = collection_class.computed_attributes[name]
|
63
|
+
computed_attribute.apply_join(ds).select_append(computed_attribute.identifier.as(name))
|
64
|
+
end
|
65
|
+
build_query dataset: ds
|
66
|
+
end
|
67
|
+
|
61
68
|
def all
|
62
|
-
with_graph(dataset.all).map do |row|
|
69
|
+
with_graph(dataset.all).map do |row|
|
63
70
|
collection_class.model.new row
|
64
71
|
end
|
65
72
|
end
|
66
73
|
alias_method :to_a, :all
|
67
74
|
|
68
|
-
def each(&block)
|
69
|
-
|
75
|
+
def each(batch_size:nil, &block)
|
76
|
+
if batch_size.nil?
|
77
|
+
all.each(&block)
|
78
|
+
else
|
79
|
+
each_batch(size: batch_size) do |models|
|
80
|
+
models.each { |model| block.call model }
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def each_batch(size:, &block)
|
86
|
+
primary_keys.each_slice(size) do |pks|
|
87
|
+
query = where(collection_class.primary_key => pks)
|
88
|
+
block.call query.all
|
89
|
+
end
|
70
90
|
end
|
71
91
|
|
72
92
|
def graph(*relations)
|
@@ -74,12 +94,10 @@ module Rasti
|
|
74
94
|
end
|
75
95
|
|
76
96
|
def join(*relations)
|
77
|
-
graph = Relations::Graph.new
|
78
|
-
|
79
|
-
ds = graph.add_joins(dataset)
|
80
|
-
|
81
|
-
.select_all(collection_class.collection_name)
|
82
|
-
|
97
|
+
graph = Relations::Graph.new environment, collection_class, relations
|
98
|
+
|
99
|
+
ds = graph.add_joins(dataset).distinct
|
100
|
+
|
83
101
|
build_query dataset: ds
|
84
102
|
end
|
85
103
|
|
@@ -97,12 +115,12 @@ module Rasti
|
|
97
115
|
|
98
116
|
def first
|
99
117
|
row = dataset.first
|
100
|
-
row ?
|
118
|
+
row ? build_model(row) : nil
|
101
119
|
end
|
102
120
|
|
103
121
|
def last
|
104
122
|
row = dataset.last
|
105
|
-
row ?
|
123
|
+
row ? build_model(row) : nil
|
106
124
|
end
|
107
125
|
|
108
126
|
def detect(*args, &block)
|
@@ -119,33 +137,42 @@ module Rasti
|
|
119
137
|
|
120
138
|
raise NQL::InvalidExpressionError.new(filter_expression) if sentence.nil?
|
121
139
|
|
140
|
+
ds = sentence.computed_attributes(collection_class).inject(dataset) do |ds, name|
|
141
|
+
collection_class.computed_attributes[name].apply_join ds
|
142
|
+
end
|
143
|
+
query = build_query dataset: ds
|
144
|
+
|
122
145
|
dependency_tables = sentence.dependency_tables
|
123
|
-
query =
|
124
|
-
|
125
|
-
query.where sentence.filter_condition
|
146
|
+
query = query.join(*dependency_tables) unless dependency_tables.empty?
|
147
|
+
|
148
|
+
query.where sentence.filter_condition(collection_class)
|
126
149
|
end
|
127
150
|
|
128
151
|
private
|
129
152
|
|
130
|
-
attr_reader :collection_class, :dataset, :relations_graph
|
153
|
+
attr_reader :environment, :collection_class, :dataset, :relations_graph
|
131
154
|
|
132
155
|
def build_query(**args)
|
133
156
|
current_args = {
|
157
|
+
environment: environment,
|
134
158
|
collection_class: collection_class,
|
135
159
|
dataset: dataset,
|
136
|
-
relations_graph: relations_graph
|
137
|
-
schema: schema
|
160
|
+
relations_graph: relations_graph
|
138
161
|
}
|
139
162
|
|
140
163
|
Query.new(**current_args.merge(args))
|
141
164
|
end
|
142
165
|
|
166
|
+
def build_model(row)
|
167
|
+
collection_class.model.new with_graph(row)
|
168
|
+
end
|
169
|
+
|
143
170
|
def chainable(&block)
|
144
171
|
build_query dataset: instance_eval(&block)
|
145
172
|
end
|
146
173
|
|
147
174
|
def with_related(relation_name, primary_keys)
|
148
|
-
ds = collection_class.relations[relation_name].apply_filter
|
175
|
+
ds = collection_class.relations[relation_name].apply_filter environment, dataset, primary_keys
|
149
176
|
build_query dataset: ds
|
150
177
|
end
|
151
178
|
|
@@ -155,6 +182,11 @@ module Rasti
|
|
155
182
|
data
|
156
183
|
end
|
157
184
|
|
185
|
+
def qualify(collection_name, data_source_name: nil)
|
186
|
+
data_source_name ||= collection_class.data_source_name
|
187
|
+
environment.qualify data_source_name, collection_name
|
188
|
+
end
|
189
|
+
|
158
190
|
def nql_parser
|
159
191
|
NQL::SyntaxParser.new
|
160
192
|
end
|
@@ -33,25 +33,39 @@ module Rasti
|
|
33
33
|
self.class == OneToOne
|
34
34
|
end
|
35
35
|
|
36
|
-
def
|
37
|
-
|
36
|
+
def from_one?
|
37
|
+
one_to_one? || one_to_many?
|
38
38
|
end
|
39
39
|
|
40
|
-
|
40
|
+
def from_many?
|
41
|
+
many_to_one? || many_to_many?
|
42
|
+
end
|
41
43
|
|
42
|
-
|
44
|
+
def to_one?
|
45
|
+
one_to_one? || many_to_one?
|
46
|
+
end
|
43
47
|
|
44
|
-
def
|
45
|
-
|
48
|
+
def to_many?
|
49
|
+
one_to_many? || many_to_many?
|
46
50
|
end
|
47
51
|
|
48
|
-
def
|
49
|
-
|
52
|
+
def join_relation_name(prefix)
|
53
|
+
with_prefix prefix, name
|
50
54
|
end
|
51
55
|
|
56
|
+
private
|
57
|
+
|
58
|
+
attr_reader :options
|
59
|
+
|
52
60
|
def with_prefix(prefix, name)
|
53
61
|
[prefix, name].compact.join('__').to_sym
|
54
62
|
end
|
63
|
+
|
64
|
+
def validate_join!
|
65
|
+
if source_collection_class.data_source_name != target_collection_class.data_source_name
|
66
|
+
raise "Invalid join of multiple data sources: #{source_collection_class.data_source_name}.#{source_collection_class.collection_name} > #{target_collection_class.data_source_name}.#{target_collection_class.collection_name}"
|
67
|
+
end
|
68
|
+
end
|
55
69
|
|
56
70
|
end
|
57
71
|
end
|
@@ -3,9 +3,8 @@ module Rasti
|
|
3
3
|
module Relations
|
4
4
|
class Graph
|
5
5
|
|
6
|
-
def initialize(
|
7
|
-
@
|
8
|
-
@schema = schema
|
6
|
+
def initialize(environment, collection_class, relations=[], selected_attributes={}, excluded_attributes={})
|
7
|
+
@environment = environment
|
9
8
|
@collection_class = collection_class
|
10
9
|
@graph = build_graph relations,
|
11
10
|
Hash::Indifferent.new(selected_attributes),
|
@@ -13,8 +12,7 @@ module Rasti
|
|
13
12
|
end
|
14
13
|
|
15
14
|
def merge(relations:[], selected_attributes:{}, excluded_attributes:{})
|
16
|
-
Graph.new
|
17
|
-
schema,
|
15
|
+
Graph.new environment,
|
18
16
|
collection_class,
|
19
17
|
(flat_relations | relations),
|
20
18
|
flat_selected_attributes.merge(selected_attributes),
|
@@ -38,9 +36,8 @@ module Rasti
|
|
38
36
|
return if rows.empty?
|
39
37
|
|
40
38
|
graph.roots.each do |node|
|
41
|
-
relation_of(node).fetch_graph
|
42
|
-
|
43
|
-
schema,
|
39
|
+
relation_of(node).fetch_graph environment,
|
40
|
+
rows,
|
44
41
|
node[:selected_attributes],
|
45
42
|
node[:excluded_attributes] ,
|
46
43
|
subgraph_of(node)
|
@@ -48,18 +45,16 @@ module Rasti
|
|
48
45
|
end
|
49
46
|
|
50
47
|
def add_joins(dataset, prefix=nil)
|
51
|
-
graph.roots.
|
48
|
+
graph.roots.inject(dataset) do |ds, node|
|
52
49
|
relation = relation_of node
|
53
|
-
|
54
|
-
|
50
|
+
dataset_with_relation = relation.add_join environment, ds, prefix
|
51
|
+
subgraph_of(node).add_joins dataset_with_relation, relation.join_relation_name(prefix)
|
55
52
|
end
|
56
|
-
|
57
|
-
dataset
|
58
53
|
end
|
59
54
|
|
60
55
|
private
|
61
56
|
|
62
|
-
attr_reader :
|
57
|
+
attr_reader :environment, :collection_class, :graph
|
63
58
|
|
64
59
|
def relation_of(node)
|
65
60
|
collection_class.relations.fetch(node[:name])
|
@@ -93,8 +88,7 @@ module Rasti
|
|
93
88
|
excluded[id] = descendant[:excluded_attributes]
|
94
89
|
end
|
95
90
|
|
96
|
-
Graph.new
|
97
|
-
schema,
|
91
|
+
Graph.new environment,
|
98
92
|
relation_of(node).target_collection_class,
|
99
93
|
relations,
|
100
94
|
selected,
|
@@ -15,23 +15,42 @@ module Rasti
|
|
15
15
|
@relation_collection_name ||= options[:relation_collection_name] || [source_collection_class.collection_name, target_collection_class.collection_name].sort.join('_').to_sym
|
16
16
|
end
|
17
17
|
|
18
|
-
def
|
19
|
-
|
18
|
+
def relation_data_source_name
|
19
|
+
@relation_data_source_name ||= options[:relation_data_source_name] || source_collection_class.data_source_name
|
20
20
|
end
|
21
21
|
|
22
|
-
def fetch_graph(
|
22
|
+
def fetch_graph(environment, rows, selected_attributes=nil, excluded_attributes=nil, relations_graph=nil)
|
23
23
|
pks = rows.map { |row| row[source_collection_class.primary_key] }
|
24
24
|
|
25
|
-
|
25
|
+
if target_collection_class.data_source_name == relation_data_source_name
|
26
|
+
target_data_source = environment.data_source_of target_collection_class
|
26
27
|
|
27
|
-
|
28
|
+
dataset = target_data_source.db.from(environment.qualify_collection(target_collection_class))
|
29
|
+
.join(qualified_relation_collection_name(environment), target_foreign_key => target_collection_class.primary_key)
|
30
|
+
.where(Sequel[relation_collection_name][source_foreign_key] => pks)
|
31
|
+
.select_all(target_collection_class.collection_name)
|
28
32
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
33
|
+
selected_attributes ||= target_collection_class.collection_attributes - excluded_attributes if excluded_attributes
|
34
|
+
dataset = dataset.select(*selected_attributes.map { |a| Sequel[target_collection_class.collection_name][a] }) if selected_attributes
|
35
|
+
|
36
|
+
join_rows = dataset.select_append(Sequel[relation_collection_name][source_foreign_key].as(:source_foreign_key)).all
|
37
|
+
else
|
38
|
+
relation_data_source = environment.data_source relation_data_source_name
|
39
|
+
|
40
|
+
relation_index = relation_data_source.db.from(relation_data_source.qualify(relation_collection_name))
|
41
|
+
.where(source_foreign_key => pks)
|
42
|
+
.select_hash_groups(target_foreign_key, source_foreign_key)
|
43
|
+
|
44
|
+
query = target_collection_class.new environment
|
45
|
+
query = query.exclude_attributes(*excluded_attributes) if excluded_attributes
|
46
|
+
query = query.select_attributes(*selected_attributes) if selected_attributes
|
47
|
+
|
48
|
+
join_rows = query.where(target_collection_class.primary_key => relation_index.keys).raw.flat_map do |row|
|
49
|
+
relation_index[row[target_collection_class.primary_key]].map do |source_primary_key|
|
50
|
+
row.merge(source_foreign_key: source_primary_key)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
35
54
|
|
36
55
|
relations_graph.fetch_graph join_rows if relations_graph
|
37
56
|
|
@@ -41,17 +60,19 @@ module Rasti
|
|
41
60
|
end
|
42
61
|
|
43
62
|
rows.each do |row|
|
44
|
-
row[name] = relation_rows.fetch row[
|
63
|
+
row[name] = relation_rows.fetch row[source_collection_class.primary_key], []
|
45
64
|
end
|
46
65
|
end
|
47
66
|
|
48
|
-
def add_join(
|
67
|
+
def add_join(environment, dataset, prefix=nil)
|
68
|
+
validate_join!
|
69
|
+
|
49
70
|
many_to_many_relation_alias = with_prefix prefix, "#{relation_collection_name}_#{SecureRandom.base64}"
|
50
71
|
|
51
|
-
|
72
|
+
relation_name = prefix ? Sequel[prefix] : Sequel[source_collection_class.collection_name]
|
52
73
|
|
53
74
|
many_to_many_condition = {
|
54
|
-
Sequel[many_to_many_relation_alias][source_foreign_key] =>
|
75
|
+
Sequel[many_to_many_relation_alias][source_foreign_key] => relation_name[source_collection_class.primary_key]
|
55
76
|
}
|
56
77
|
|
57
78
|
relation_alias = join_relation_name prefix
|
@@ -60,17 +81,30 @@ module Rasti
|
|
60
81
|
Sequel[relation_alias][target_collection_class.primary_key] => Sequel[many_to_many_relation_alias][target_foreign_key]
|
61
82
|
}
|
62
83
|
|
63
|
-
dataset.join(qualified_relation_collection_name(
|
64
|
-
.join(
|
84
|
+
dataset.join(qualified_relation_collection_name(environment).as(many_to_many_relation_alias), many_to_many_condition)
|
85
|
+
.join(environment.qualify_collection(target_collection_class).as(relation_alias), relation_condition)
|
86
|
+
end
|
87
|
+
|
88
|
+
def apply_filter(environment, dataset, primary_keys)
|
89
|
+
if source_collection_class.data_source_name == relation_data_source_name
|
90
|
+
dataset.join(qualified_relation_collection_name(environment), source_foreign_key => source_collection_class.primary_key)
|
91
|
+
.where(Sequel[relation_collection_name][target_foreign_key] => primary_keys)
|
92
|
+
.select_all(source_collection_class.collection_name)
|
93
|
+
.distinct
|
94
|
+
else
|
95
|
+
data_source = environment.data_source relation_data_source_name
|
96
|
+
fks = data_source.db.from(data_source.qualify(relation_collection_name))
|
97
|
+
.where(target_collection_class.foreign_key => primary_keys)
|
98
|
+
.select_map(source_collection_class.foreign_key)
|
99
|
+
.uniq
|
100
|
+
dataset.where(source_collection_class.primary_key => fks)
|
101
|
+
end
|
65
102
|
end
|
66
103
|
|
67
|
-
|
68
|
-
relation_name = qualified_relation_collection_name schema
|
104
|
+
private
|
69
105
|
|
70
|
-
|
71
|
-
|
72
|
-
.select_all(source_collection_class.collection_name)
|
73
|
-
.distinct
|
106
|
+
def qualified_relation_collection_name(environment)
|
107
|
+
environment.qualify relation_data_source_name, relation_collection_name
|
74
108
|
end
|
75
109
|
|
76
110
|
end
|