rasti-db 4.1.0 → 4.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![Gem Version](https://badge.fury.io/rb/rasti-db.svg)](https://rubygems.org/gems/rasti-db)
|
4
|
-
[![
|
4
|
+
[![CI](https://github.com/gabynaiman/rasti-db/actions/workflows/ci.yml/badge.svg)](https://github.com/gabynaiman/rasti-db/actions/workflows/ci.yml)
|
5
5
|
[![Coverage Status](https://coveralls.io/repos/github/gabynaiman/rasti-db/badge.svg?branch=master)](https://coveralls.io/github/gabynaiman/rasti-db?branch=master)
|
6
6
|
[![Code Climate](https://codeclimate.com/github/gabynaiman/rasti-db.svg)](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
|