rasti-db 4.1.0 → 4.2.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/.github/workflows/ci.yml +26 -0
- data/README.md +1 -1
- data/lib/rasti/db/query.rb +27 -13
- data/lib/rasti/db/relations/graph.rb +23 -10
- data/lib/rasti/db/relations/many_to_many.rb +14 -8
- data/lib/rasti/db/relations/many_to_one.rb +8 -4
- data/lib/rasti/db/relations/one_to_many.rb +7 -4
- data/lib/rasti/db/version.rb +1 -1
- data/spec/minitest_helper.rb +44 -9
- data/spec/query_spec.rb +79 -1
- metadata +3 -3
- data/.travis.yml +0 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fa10d65e8a9fbd3c311384e8806addd5c04b803405444717d6904282dbf9207c
|
4
|
+
data.tar.gz: 24f1e8801906634288e62ef7337da1179392e75203b08ae6f034b5f25256228e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 04a6c1deb6afa47fae66203bec39d81926ac5e6435844593c321279423d6a8a5651178fc5769e58868f88286ae819ecfd7aa77785b2e6df82cd63096d12ee34f
|
7
|
+
data.tar.gz: 28ec23866d539f20163bff9449586060d1f943d022f10f72d2d4b4ff5f3fc8b9db97acbefa2482fcc262d0e51625bad603ea3861fbea7f47fe36382ce9da5821
|
@@ -0,0 +1,26 @@
|
|
1
|
+
name: CI
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [ '**' ]
|
6
|
+
pull_request:
|
7
|
+
branches: [ '**' ]
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
test:
|
11
|
+
|
12
|
+
name: Tests
|
13
|
+
runs-on: ubuntu-latest
|
14
|
+
strategy:
|
15
|
+
matrix:
|
16
|
+
ruby-version: ['2.3', '2.4', '2.5', '2.6', '2.7', '3.0', 'jruby-9.2.9.0']
|
17
|
+
|
18
|
+
steps:
|
19
|
+
- uses: actions/checkout@v3
|
20
|
+
- name: Set up Ruby
|
21
|
+
uses: ruby/setup-ruby@v1
|
22
|
+
with:
|
23
|
+
ruby-version: ${{ matrix.ruby-version }}
|
24
|
+
bundler-cache: true
|
25
|
+
- name: Run tests
|
26
|
+
run: bundle exec rake
|
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# Rasti::DB
|
2
2
|
|
3
3
|
[](https://rubygems.org/gems/rasti-db)
|
4
|
-
[](https://github.com/gabynaiman/rasti-db/actions/workflows/ci.yml)
|
5
5
|
[](https://coveralls.io/github/gabynaiman/rasti-db?branch=master)
|
6
6
|
[](https://codeclimate.com/github/gabynaiman/rasti-db)
|
7
7
|
|
data/lib/rasti/db/query.rb
CHANGED
@@ -53,22 +53,24 @@ module Rasti
|
|
53
53
|
build_query relations_graph: relations_graph.merge(excluded_attributes: excluded_attributes)
|
54
54
|
end
|
55
55
|
|
56
|
+
def graph_queries(queries)
|
57
|
+
build_query relations_graph: relations_graph.merge(queries: queries)
|
58
|
+
end
|
59
|
+
|
56
60
|
def all_graph_attributes(*relations)
|
57
61
|
build_query relations_graph: relations_graph.with_all_attributes_for(relations)
|
58
62
|
end
|
59
63
|
|
60
64
|
def select_computed_attributes(*computed_attributes)
|
61
|
-
ds = computed_attributes.inject(dataset) do |
|
65
|
+
ds = computed_attributes.inject(dataset) do |inner_ds, name|
|
62
66
|
computed_attribute = collection_class.computed_attributes[name]
|
63
|
-
computed_attribute.apply_join(
|
67
|
+
computed_attribute.apply_join(inner_ds, environment).select_append(computed_attribute.identifier.as(name))
|
64
68
|
end
|
65
69
|
build_query dataset: ds
|
66
70
|
end
|
67
71
|
|
68
72
|
def all
|
69
|
-
|
70
|
-
collection_class.model.new row
|
71
|
-
end
|
73
|
+
build_models dataset.all
|
72
74
|
end
|
73
75
|
alias_method :to_a, :all
|
74
76
|
|
@@ -114,13 +116,11 @@ module Rasti
|
|
114
116
|
end
|
115
117
|
|
116
118
|
def first
|
117
|
-
|
118
|
-
row ? build_model(row) : nil
|
119
|
+
build_model dataset.first
|
119
120
|
end
|
120
121
|
|
121
122
|
def last
|
122
|
-
|
123
|
-
row ? build_model(row) : nil
|
123
|
+
build_model dataset.last
|
124
124
|
end
|
125
125
|
|
126
126
|
def detect(*args, &block)
|
@@ -137,8 +137,8 @@ module Rasti
|
|
137
137
|
|
138
138
|
raise NQL::InvalidExpressionError.new(filter_expression) if sentence.nil?
|
139
139
|
|
140
|
-
ds = sentence.computed_attributes(collection_class).inject(dataset) do |
|
141
|
-
collection_class.computed_attributes[name].apply_join
|
140
|
+
ds = sentence.computed_attributes(collection_class).inject(dataset) do |inner_ds, name|
|
141
|
+
collection_class.computed_attributes[name].apply_join inner_ds, environment
|
142
142
|
end
|
143
143
|
query = build_query dataset: ds
|
144
144
|
|
@@ -164,7 +164,21 @@ module Rasti
|
|
164
164
|
end
|
165
165
|
|
166
166
|
def build_model(row)
|
167
|
-
|
167
|
+
row ? build_models([row]).first : nil
|
168
|
+
end
|
169
|
+
|
170
|
+
def build_models(rows)
|
171
|
+
with_graph(rows).map do |row|
|
172
|
+
collection_class.model.new slice_defined_attributes(row)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
def slice_defined_attributes(row)
|
177
|
+
row.select { |k,_| defined_attributes.include? k }
|
178
|
+
end
|
179
|
+
|
180
|
+
def defined_attributes
|
181
|
+
@defined_attributes ||= collection_class.model.attribute_names.to_set
|
168
182
|
end
|
169
183
|
|
170
184
|
def chainable(&block)
|
@@ -205,4 +219,4 @@ module Rasti
|
|
205
219
|
|
206
220
|
end
|
207
221
|
end
|
208
|
-
end
|
222
|
+
end
|
@@ -3,20 +3,22 @@ module Rasti
|
|
3
3
|
module Relations
|
4
4
|
class Graph
|
5
5
|
|
6
|
-
def initialize(environment, collection_class, relations=[], selected_attributes={}, excluded_attributes={})
|
6
|
+
def initialize(environment, collection_class, relations=[], selected_attributes={}, excluded_attributes={}, queries={})
|
7
7
|
@environment = environment
|
8
8
|
@collection_class = collection_class
|
9
9
|
@graph = build_graph relations,
|
10
10
|
Hash::Indifferent.new(selected_attributes),
|
11
|
-
Hash::Indifferent.new(excluded_attributes)
|
11
|
+
Hash::Indifferent.new(excluded_attributes),
|
12
|
+
Hash::Indifferent.new(queries)
|
12
13
|
end
|
13
14
|
|
14
|
-
def merge(relations:[], selected_attributes:{}, excluded_attributes:{})
|
15
|
+
def merge(relations:[], selected_attributes:{}, excluded_attributes:{}, queries: {})
|
15
16
|
Graph.new environment,
|
16
17
|
collection_class,
|
17
18
|
(flat_relations | relations),
|
18
19
|
flat_selected_attributes.merge(selected_attributes),
|
19
|
-
flat_excluded_attributes.merge(excluded_attributes)
|
20
|
+
flat_excluded_attributes.merge(excluded_attributes),
|
21
|
+
flat_queries.merge(queries)
|
20
22
|
end
|
21
23
|
|
22
24
|
def with_all_attributes_for(relations)
|
@@ -30,16 +32,17 @@ module Rasti
|
|
30
32
|
query.graph(*flat_relations)
|
31
33
|
.select_graph_attributes(flat_selected_attributes)
|
32
34
|
.exclude_graph_attributes(flat_excluded_attributes)
|
35
|
+
.graph_queries(flat_queries)
|
33
36
|
end
|
34
37
|
|
35
38
|
def fetch_graph(rows)
|
36
39
|
return if rows.empty?
|
37
|
-
|
38
40
|
graph.roots.each do |node|
|
39
41
|
relation_of(node).fetch_graph environment,
|
40
42
|
rows,
|
41
43
|
node[:selected_attributes],
|
42
|
-
node[:excluded_attributes]
|
44
|
+
node[:excluded_attributes],
|
45
|
+
node[:queries] ,
|
43
46
|
subgraph_of(node)
|
44
47
|
end
|
45
48
|
end
|
@@ -76,33 +79,43 @@ module Rasti
|
|
76
79
|
end
|
77
80
|
end
|
78
81
|
|
82
|
+
def flat_queries
|
83
|
+
graph.each_with_object(Hash::Indifferent.new) do |node, hash|
|
84
|
+
hash[node.id] = node[:queries]
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
79
88
|
def subgraph_of(node)
|
80
89
|
relations = []
|
81
90
|
selected = Hash::Indifferent.new
|
82
91
|
excluded = Hash::Indifferent.new
|
92
|
+
queries = Hash::Indifferent.new
|
83
93
|
|
84
94
|
node.descendants.each do |descendant|
|
85
95
|
id = descendant.id[node[:name].length+1..-1]
|
86
96
|
relations << id
|
87
97
|
selected[id] = descendant[:selected_attributes]
|
88
98
|
excluded[id] = descendant[:excluded_attributes]
|
99
|
+
queries[id] = descendant[:queries]
|
89
100
|
end
|
90
101
|
|
91
102
|
Graph.new environment,
|
92
103
|
relation_of(node).target_collection_class,
|
93
104
|
relations,
|
94
105
|
selected,
|
95
|
-
excluded
|
106
|
+
excluded,
|
107
|
+
queries
|
96
108
|
end
|
97
109
|
|
98
|
-
def build_graph(relations, selected_attributes, excluded_attributes)
|
110
|
+
def build_graph(relations, selected_attributes, excluded_attributes, queries)
|
99
111
|
HierarchicalGraph.new.tap do |graph|
|
100
112
|
flatten(relations).each do |relation|
|
101
113
|
sections = relation.split('.')
|
102
114
|
|
103
115
|
graph.add_node relation, name: sections.last.to_sym,
|
104
116
|
selected_attributes: selected_attributes[relation],
|
105
|
-
excluded_attributes: excluded_attributes[relation]
|
117
|
+
excluded_attributes: excluded_attributes[relation],
|
118
|
+
queries: queries[relation]
|
106
119
|
|
107
120
|
if sections.count > 1
|
108
121
|
parent_id = sections[0..-2].join('.')
|
@@ -126,4 +139,4 @@ module Rasti
|
|
126
139
|
end
|
127
140
|
end
|
128
141
|
end
|
129
|
-
end
|
142
|
+
end
|
@@ -19,9 +19,9 @@ module Rasti
|
|
19
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(environment, rows, selected_attributes=nil, excluded_attributes=nil, relations_graph=nil)
|
22
|
+
def fetch_graph(environment, rows, selected_attributes=nil, excluded_attributes=nil, queries=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
26
|
target_data_source = environment.data_source_of target_collection_class
|
27
27
|
|
@@ -30,10 +30,14 @@ module Rasti
|
|
30
30
|
.where(Sequel[relation_collection_name][source_foreign_key] => pks)
|
31
31
|
.select_all(target_collection_class.collection_name)
|
32
32
|
|
33
|
-
selected_attributes ||= target_collection_class.collection_attributes - excluded_attributes
|
34
|
-
dataset = dataset.select(*selected_attributes.map { |a| Sequel[target_collection_class.collection_name][a] })
|
33
|
+
selected_attributes ||= target_collection_class.collection_attributes - excluded_attributes unless excluded_attributes.nil?
|
34
|
+
dataset = dataset.select(*selected_attributes.map { |a| Sequel[target_collection_class.collection_name][a] }) unless selected_attributes.nil?
|
35
|
+
|
36
|
+
query = Query.new collection_class: target_collection_class, dataset: dataset, environment: environment
|
37
|
+
query = queries.inject(query) { |new_query, sub_query| new_query.send(sub_query) } unless queries.nil?
|
38
|
+
|
39
|
+
join_rows = query.send(:dataset).select_append(Sequel[relation_collection_name][source_foreign_key].as(:source_foreign_key)).all
|
35
40
|
|
36
|
-
join_rows = dataset.select_append(Sequel[relation_collection_name][source_foreign_key].as(:source_foreign_key)).all
|
37
41
|
else
|
38
42
|
relation_data_source = environment.data_source relation_data_source_name
|
39
43
|
|
@@ -42,8 +46,10 @@ module Rasti
|
|
42
46
|
.select_hash_groups(target_foreign_key, source_foreign_key)
|
43
47
|
|
44
48
|
query = target_collection_class.new environment
|
45
|
-
query = query.exclude_attributes(*excluded_attributes)
|
46
|
-
query = query.select_attributes(*selected_attributes)
|
49
|
+
query = query.exclude_attributes(*excluded_attributes) unless excluded_attributes.nil?
|
50
|
+
query = query.select_attributes(*selected_attributes) unless selected_attributes.nil?
|
51
|
+
|
52
|
+
query = queries.inject(query) { |new_query, sub_query| new_query.send(sub_query) } unless queries.nil?
|
47
53
|
|
48
54
|
join_rows = query.where(target_collection_class.primary_key => relation_index.keys).raw.flat_map do |row|
|
49
55
|
relation_index[row[target_collection_class.primary_key]].map do |source_primary_key|
|
@@ -110,4 +116,4 @@ module Rasti
|
|
110
116
|
end
|
111
117
|
end
|
112
118
|
end
|
113
|
-
end
|
119
|
+
end
|
@@ -7,14 +7,18 @@ module Rasti
|
|
7
7
|
@foreign_key ||= options[:foreign_key] || target_collection_class.foreign_key
|
8
8
|
end
|
9
9
|
|
10
|
-
def fetch_graph(environment, rows, selected_attributes=nil, excluded_attributes=nil, relations_graph=nil)
|
10
|
+
def fetch_graph(environment, rows, selected_attributes=nil, excluded_attributes=nil, queries=nil, relations_graph=nil)
|
11
11
|
fks = rows.map { |row| row[foreign_key] }.uniq
|
12
12
|
|
13
13
|
target_collection = target_collection_class.new environment
|
14
14
|
|
15
15
|
query = target_collection.where(source_collection_class.primary_key => fks)
|
16
|
-
|
17
|
-
query = query.
|
16
|
+
|
17
|
+
query = query.exclude_attributes(*excluded_attributes) unless excluded_attributes.nil?
|
18
|
+
query = query.select_attributes(*selected_attributes) unless selected_attributes.nil?
|
19
|
+
|
20
|
+
query = queries.inject(query) { |new_query, sub_query| new_query.send(sub_query) } unless queries.nil?
|
21
|
+
|
18
22
|
query = relations_graph.apply_to query if relations_graph
|
19
23
|
|
20
24
|
relation_rows = query.each_with_object({}) do |row, hash|
|
@@ -47,4 +51,4 @@ module Rasti
|
|
47
51
|
end
|
48
52
|
end
|
49
53
|
end
|
50
|
-
end
|
54
|
+
end
|
@@ -7,14 +7,17 @@ module Rasti
|
|
7
7
|
@foreign_key ||= options[:foreign_key] || source_collection_class.foreign_key
|
8
8
|
end
|
9
9
|
|
10
|
-
def fetch_graph(environment, rows, selected_attributes=nil, excluded_attributes=nil, relations_graph=nil)
|
10
|
+
def fetch_graph(environment, rows, selected_attributes=nil, excluded_attributes=nil, queries=nil, relations_graph=nil)
|
11
11
|
pks = rows.map { |row| row[source_collection_class.primary_key] }.uniq
|
12
12
|
|
13
13
|
target_collection = target_collection_class.new environment
|
14
14
|
|
15
15
|
query = target_collection.where(foreign_key => pks)
|
16
|
-
query = query.exclude_attributes(*excluded_attributes)
|
17
|
-
query = query.select_attributes(*selected_attributes)
|
16
|
+
query = query.exclude_attributes(*excluded_attributes) unless excluded_attributes.nil?
|
17
|
+
query = query.select_attributes(*selected_attributes) unless selected_attributes.nil?
|
18
|
+
|
19
|
+
query = queries.inject(query) { |new_query, sub_query| new_query.send(sub_query) } unless queries.nil?
|
20
|
+
|
18
21
|
query = relations_graph.apply_to query if relations_graph
|
19
22
|
|
20
23
|
relation_rows = query.group_by(&foreign_key)
|
@@ -62,4 +65,4 @@ module Rasti
|
|
62
65
|
end
|
63
66
|
end
|
64
67
|
end
|
65
|
-
end
|
68
|
+
end
|
data/lib/rasti/db/version.rb
CHANGED
data/spec/minitest_helper.rb
CHANGED
@@ -19,10 +19,12 @@ Post = Rasti::DB::Model[:id, :title, :body, :user_id, :user, :comments, :cat
|
|
19
19
|
Comment = Rasti::DB::Model[:id, :text, :user_id, :user, :post_id, :post, :tags]
|
20
20
|
Category = Rasti::DB::Model[:id, :name, :posts]
|
21
21
|
Person = Rasti::DB::Model[:document_number, :first_name, :last_name, :birth_date, :user_id, :user, :languages, :full_name]
|
22
|
-
Language = Rasti::DB::Model[:id, :name, :people]
|
22
|
+
Language = Rasti::DB::Model[:id, :name, :people, :countries]
|
23
|
+
Country = Rasti::DB::Model[:id, :name, :population, :language_id]
|
23
24
|
|
24
25
|
|
25
26
|
class Users < Rasti::DB::Collection
|
27
|
+
|
26
28
|
one_to_many :posts
|
27
29
|
one_to_many :comments
|
28
30
|
one_to_one :person
|
@@ -41,14 +43,15 @@ class Users < Rasti::DB::Collection
|
|
41
43
|
end
|
42
44
|
|
43
45
|
class Posts < Rasti::DB::Collection
|
46
|
+
|
44
47
|
many_to_one :user
|
45
48
|
many_to_one :language
|
46
49
|
many_to_many :categories
|
47
50
|
one_to_many :comments
|
48
51
|
|
49
52
|
query :created_by, ->(user_id) { where user_id: user_id }
|
50
|
-
|
51
|
-
query :entitled do |title|
|
53
|
+
|
54
|
+
query :entitled do |title|
|
52
55
|
where title: title
|
53
56
|
end
|
54
57
|
|
@@ -61,6 +64,18 @@ class Posts < Rasti::DB::Collection
|
|
61
64
|
end
|
62
65
|
end
|
63
66
|
|
67
|
+
query :only_title do
|
68
|
+
chainable do
|
69
|
+
dataset.select(:title).select_append(:id, :user_id)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
query :append_body do
|
74
|
+
chainable do
|
75
|
+
dataset.select_append(:body)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
64
79
|
computed_attribute :notice do
|
65
80
|
Rasti::DB::ComputedAttribute.new Sequel.join([:title, ': ', :body])
|
66
81
|
end
|
@@ -72,6 +87,7 @@ class Posts < Rasti::DB::Collection
|
|
72
87
|
end
|
73
88
|
|
74
89
|
class Comments < Rasti::DB::Collection
|
90
|
+
|
75
91
|
many_to_one :user
|
76
92
|
many_to_one :post
|
77
93
|
|
@@ -81,13 +97,17 @@ class Comments < Rasti::DB::Collection
|
|
81
97
|
.select_all(:posts)
|
82
98
|
.map { |row| Post.new row }
|
83
99
|
end
|
100
|
+
|
84
101
|
end
|
85
102
|
|
86
103
|
class Categories < Rasti::DB::Collection
|
104
|
+
|
87
105
|
many_to_many :posts
|
106
|
+
|
88
107
|
end
|
89
108
|
|
90
109
|
class People < Rasti::DB::Collection
|
110
|
+
|
91
111
|
set_collection_name :people
|
92
112
|
set_primary_key :document_number
|
93
113
|
set_foreign_key :document_number
|
@@ -99,13 +119,23 @@ class People < Rasti::DB::Collection
|
|
99
119
|
computed_attribute :full_name do |db|
|
100
120
|
Rasti::DB::ComputedAttribute.new Sequel.join([:first_name, ' ', :last_name])
|
101
121
|
end
|
122
|
+
|
102
123
|
end
|
103
124
|
|
104
125
|
class Languages < Rasti::DB::Collection
|
126
|
+
|
105
127
|
set_data_source_name :custom
|
106
128
|
|
107
129
|
many_to_many :people, collection: People, relation_data_source_name: :default
|
108
130
|
one_to_many :posts
|
131
|
+
one_to_many :countries
|
132
|
+
|
133
|
+
end
|
134
|
+
|
135
|
+
class Countries < Rasti::DB::Collection
|
136
|
+
|
137
|
+
many_to_one :language
|
138
|
+
|
109
139
|
end
|
110
140
|
|
111
141
|
|
@@ -114,7 +144,7 @@ class Minitest::Spec
|
|
114
144
|
let(:users) { Users.new environment }
|
115
145
|
|
116
146
|
let(:posts) { Posts.new environment }
|
117
|
-
|
147
|
+
|
118
148
|
let(:comments) { Comments.new environment }
|
119
149
|
|
120
150
|
let(:categories) { Categories.new environment }
|
@@ -123,16 +153,17 @@ class Minitest::Spec
|
|
123
153
|
|
124
154
|
let(:languages) { Languages.new environment }
|
125
155
|
|
156
|
+
let(:countries) { Countries.new environment }
|
157
|
+
|
126
158
|
let(:driver) { (RUBY_ENGINE == 'jruby') ? 'jdbc:sqlite::memory:' : {adapter: :sqlite} }
|
127
159
|
|
128
|
-
let :environment do
|
160
|
+
let :environment do
|
129
161
|
Rasti::DB::Environment.new default: Rasti::DB::DataSource.new(db),
|
130
162
|
custom: Rasti::DB::DataSource.new(custom_db)
|
131
163
|
end
|
132
164
|
|
133
165
|
let :db do
|
134
166
|
Sequel.connect(driver).tap do |db|
|
135
|
-
|
136
167
|
db.create_table :users do
|
137
168
|
primary_key :id
|
138
169
|
String :name, null: false, unique: true
|
@@ -179,18 +210,22 @@ class Minitest::Spec
|
|
179
210
|
primary_key [:language_id, :document_number]
|
180
211
|
end
|
181
212
|
|
213
|
+
db.create_table :countries do
|
214
|
+
primary_key :id
|
215
|
+
String :name, null: false, unique: true
|
216
|
+
Integer :population, null: false
|
217
|
+
Integer :language_id, null: false, index: true
|
218
|
+
end
|
182
219
|
end
|
183
220
|
end
|
184
221
|
|
185
222
|
let :custom_db do
|
186
223
|
Sequel.connect(driver).tap do |db|
|
187
|
-
|
188
224
|
db.create_table :languages do
|
189
225
|
primary_key :id
|
190
226
|
String :name, null: false, unique: true
|
191
227
|
end
|
192
|
-
|
193
228
|
end
|
194
229
|
end
|
195
230
|
|
196
|
-
end
|
231
|
+
end
|
data/spec/query_spec.rb
CHANGED
@@ -32,6 +32,8 @@ describe 'Query' do
|
|
32
32
|
db[:categories_posts].insert post_id: 2, category_id: 2
|
33
33
|
db[:categories_posts].insert post_id: 2, category_id: 3
|
34
34
|
db[:categories_posts].insert post_id: 3, category_id: 3
|
35
|
+
|
36
|
+
db[:countries].insert name: 'Argentina', population: 40000000, language_id: 1
|
35
37
|
end
|
36
38
|
|
37
39
|
let(:users_query) { Rasti::DB::Query.new collection_class: Users, dataset: db[:users], environment: environment }
|
@@ -44,6 +46,10 @@ describe 'Query' do
|
|
44
46
|
|
45
47
|
let(:languages_query) { Rasti::DB::Query.new collection_class: Languages, dataset: custom_db[:languages], environment: environment }
|
46
48
|
|
49
|
+
let(:countries_query) { Rasti::DB::Query.new collection_class: Countries, dataset: db[:countries], environment: environment }
|
50
|
+
|
51
|
+
let(:categories_query) { Rasti::DB::Query.new collection_class: Categories, dataset: db[:categories], environment: environment }
|
52
|
+
|
47
53
|
it 'Count' do
|
48
54
|
users_query.count.must_equal 10
|
49
55
|
end
|
@@ -142,6 +148,59 @@ describe 'Query' do
|
|
142
148
|
.must_equal [post]
|
143
149
|
end
|
144
150
|
|
151
|
+
it 'Graph with query many to one' do
|
152
|
+
comments_query.graph('post')
|
153
|
+
.graph_queries('post' => [:only_title])
|
154
|
+
.where(id: 1)
|
155
|
+
.all
|
156
|
+
.must_equal [
|
157
|
+
Comment.new(id: 1, text: 'Comment 1', user_id: 5, post_id: 1, post: Post.new(id: 1, user_id: 2, title: 'Sample post'), tags: [])
|
158
|
+
]
|
159
|
+
end
|
160
|
+
|
161
|
+
it 'Graph with query one to many' do
|
162
|
+
users_query.graph('posts')
|
163
|
+
.graph_queries('posts' => [:only_title])
|
164
|
+
.where(id: 1)
|
165
|
+
.all
|
166
|
+
.must_equal [
|
167
|
+
User.new(id: 1, name: 'User 1', posts: [Post.new(user_id: 1, id: 2, title: 'Another post')])
|
168
|
+
]
|
169
|
+
end
|
170
|
+
|
171
|
+
it 'Graph with query many to many' do
|
172
|
+
categories_query.graph('posts')
|
173
|
+
.graph_queries('posts' => [:only_title])
|
174
|
+
.where(id: 1)
|
175
|
+
.all
|
176
|
+
.must_equal [
|
177
|
+
Category.new(id: 1, name: 'Category 1', posts: [Post.new(user_id: 2, id: 1, title: 'Sample post')])
|
178
|
+
]
|
179
|
+
end
|
180
|
+
|
181
|
+
it 'Graph with n queries' do
|
182
|
+
comments_query.graph('post')
|
183
|
+
.graph_queries('post' => [:only_title, :append_body])
|
184
|
+
.where(id: 1)
|
185
|
+
.all
|
186
|
+
.must_equal [
|
187
|
+
Comment.new(id: 1, text: 'Comment 1', user_id: 5, post_id: 1, post: Post.new(id: 1, user_id: 2, title: 'Sample post', body: '...'), tags: [])
|
188
|
+
]
|
189
|
+
|
190
|
+
end
|
191
|
+
|
192
|
+
it 'Graph query missing must raise error' do
|
193
|
+
proc { posts_query.graph('comments.user')
|
194
|
+
.graph_queries('comments.user' => [:with_not_exists_query])
|
195
|
+
.all }.must_raise NoMethodError
|
196
|
+
end
|
197
|
+
|
198
|
+
it 'Graph with query params must raise error' do
|
199
|
+
proc { users_query.graph('posts')
|
200
|
+
.graph_queries('posts' => [:created_by])
|
201
|
+
.all }.must_raise ArgumentError
|
202
|
+
end
|
203
|
+
|
145
204
|
describe 'Select computed attributes' do
|
146
205
|
it 'With join' do
|
147
206
|
db[:comments].insert post_id: 1, user_id: 5, text: 'Comment 4'
|
@@ -166,6 +225,25 @@ describe 'Query' do
|
|
166
225
|
end
|
167
226
|
end
|
168
227
|
|
228
|
+
describe 'Ignore undefined attributes' do
|
229
|
+
|
230
|
+
it 'First level' do
|
231
|
+
countries_query.raw.first.must_equal id: 1,
|
232
|
+
name: 'Argentina',
|
233
|
+
population: 40000000,
|
234
|
+
language_id: 1
|
235
|
+
|
236
|
+
[countries_query.detect(id: 1), countries_query.where(id: 1).order(:name).last, countries_query.all.first].each do |country|
|
237
|
+
country.must_equal Country.new(language_id: 1, id: 1, name: 'Argentina', population: 40000000)
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
it 'Graph nested' do
|
242
|
+
languages_query.graph(:countries).first.countries.must_equal [Country.new(language_id: 1, id: 1, name: 'Argentina', population: 40000000)]
|
243
|
+
end
|
244
|
+
|
245
|
+
end
|
246
|
+
|
169
247
|
it 'Map' do
|
170
248
|
users_query.map(&:name).must_equal db[:users].map(:name)
|
171
249
|
end
|
@@ -553,4 +631,4 @@ describe 'Query' do
|
|
553
631
|
|
554
632
|
end
|
555
633
|
|
556
|
-
end
|
634
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rasti-db
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gabriel Naiman
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-02-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sequel
|
@@ -294,10 +294,10 @@ extensions: []
|
|
294
294
|
extra_rdoc_files: []
|
295
295
|
files:
|
296
296
|
- ".coveralls.yml"
|
297
|
+
- ".github/workflows/ci.yml"
|
297
298
|
- ".gitignore"
|
298
299
|
- ".ruby-gemset"
|
299
300
|
- ".ruby-version"
|
300
|
-
- ".travis.yml"
|
301
301
|
- Gemfile
|
302
302
|
- LICENSE.txt
|
303
303
|
- README.md
|
data/.travis.yml
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
language: ruby
|
2
|
-
|
3
|
-
rvm:
|
4
|
-
- 2.1
|
5
|
-
- 2.2
|
6
|
-
- 2.3
|
7
|
-
- 2.4
|
8
|
-
- 2.5
|
9
|
-
- 2.6
|
10
|
-
- 2.7
|
11
|
-
- 3.0
|
12
|
-
- jruby-9.2.9.0
|
13
|
-
- ruby-head
|
14
|
-
- jruby-head
|
15
|
-
|
16
|
-
matrix:
|
17
|
-
fast_finish: true
|
18
|
-
allow_failures:
|
19
|
-
- rvm: ruby-head
|
20
|
-
- rvm: jruby-head
|
21
|
-
|
22
|
-
jdk:
|
23
|
-
- openjdk8
|