rasti-db 1.3.0 → 2.0.1
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/.travis.yml +7 -12
- data/README.md +77 -21
- data/lib/rasti/db.rb +2 -1
- data/lib/rasti/db/collection.rb +70 -46
- data/lib/rasti/db/data_source.rb +18 -0
- data/lib/rasti/db/environment.rb +32 -0
- data/lib/rasti/db/model.rb +4 -0
- data/lib/rasti/db/query.rb +71 -37
- data/lib/rasti/db/relations/base.rb +22 -8
- data/lib/rasti/db/relations/graph.rb +129 -0
- data/lib/rasti/db/relations/many_to_many.rb +59 -25
- data/lib/rasti/db/relations/many_to_one.rb +17 -12
- data/lib/rasti/db/relations/one_to_many.rb +27 -16
- data/lib/rasti/db/version.rb +1 -1
- data/rasti-db.gemspec +3 -8
- data/spec/collection_spec.rb +223 -52
- data/spec/minitest_helper.rb +50 -14
- data/spec/model_spec.rb +9 -1
- data/spec/query_spec.rb +199 -77
- data/spec/relations_spec.rb +27 -7
- metadata +25 -10
- data/lib/rasti/db/helpers.rb +0 -16
- data/lib/rasti/db/relations/graph_builder.rb +0 -60
data/spec/minitest_helper.rb
CHANGED
@@ -2,6 +2,7 @@ require 'coverage_helper'
|
|
2
2
|
require 'rasti-db'
|
3
3
|
require 'minitest/autorun'
|
4
4
|
require 'minitest/colorin'
|
5
|
+
require 'minitest/line/describe_track'
|
5
6
|
require 'pry-nav'
|
6
7
|
require 'logger'
|
7
8
|
require 'sequel/extensions/pg_hstore'
|
@@ -13,10 +14,11 @@ Rasti::DB.configure do |config|
|
|
13
14
|
end
|
14
15
|
|
15
16
|
User = Rasti::DB::Model[:id, :name, :posts, :comments, :person]
|
16
|
-
Post = Rasti::DB::Model[:id, :title, :body, :user_id, :user, :comments, :categories]
|
17
|
+
Post = Rasti::DB::Model[:id, :title, :body, :user_id, :user, :comments, :categories, :language_id, :language]
|
17
18
|
Comment = Rasti::DB::Model[:id, :text, :user_id, :user, :post_id, :post]
|
18
19
|
Category = Rasti::DB::Model[:id, :name, :posts]
|
19
|
-
Person = Rasti::DB::Model[:document_number, :first_name, :last_name, :birth_date, :user_id, :user]
|
20
|
+
Person = Rasti::DB::Model[:document_number, :first_name, :last_name, :birth_date, :user_id, :user, :languages]
|
21
|
+
Language = Rasti::DB::Model[:id, :name, :people]
|
20
22
|
|
21
23
|
|
22
24
|
class Users < Rasti::DB::Collection
|
@@ -27,6 +29,7 @@ end
|
|
27
29
|
|
28
30
|
class Posts < Rasti::DB::Collection
|
29
31
|
many_to_one :user
|
32
|
+
many_to_one :language
|
30
33
|
many_to_many :categories
|
31
34
|
one_to_many :comments
|
32
35
|
|
@@ -38,9 +41,9 @@ class Posts < Rasti::DB::Collection
|
|
38
41
|
|
39
42
|
query :commented_by do |user_id|
|
40
43
|
chainable do
|
41
|
-
dataset.join(
|
42
|
-
.where(
|
43
|
-
.select_all(
|
44
|
+
dataset.join(qualify(:comments), post_id: :id)
|
45
|
+
.where(Sequel[:comments][:user_id] => user_id)
|
46
|
+
.select_all(:posts)
|
44
47
|
.distinct
|
45
48
|
end
|
46
49
|
end
|
@@ -52,8 +55,8 @@ class Comments < Rasti::DB::Collection
|
|
52
55
|
|
53
56
|
def posts_commented_by(user_id)
|
54
57
|
dataset.where(Sequel[:comments][:user_id] => user_id)
|
55
|
-
.join(
|
56
|
-
.select_all(
|
58
|
+
.join(qualify(:posts, data_source_name: :default), id: :post_id)
|
59
|
+
.select_all(:posts)
|
57
60
|
.map { |row| Post.new row }
|
58
61
|
end
|
59
62
|
end
|
@@ -69,24 +72,39 @@ class People < Rasti::DB::Collection
|
|
69
72
|
set_model Person
|
70
73
|
|
71
74
|
many_to_one :user
|
75
|
+
many_to_many :languages
|
76
|
+
end
|
77
|
+
|
78
|
+
class Languages < Rasti::DB::Collection
|
79
|
+
set_data_source_name :custom
|
80
|
+
|
81
|
+
many_to_many :people, collection: People, relation_data_source_name: :default
|
82
|
+
one_to_many :posts
|
72
83
|
end
|
73
84
|
|
74
85
|
|
75
86
|
class Minitest::Spec
|
76
87
|
|
77
|
-
let(:users) { Users.new
|
88
|
+
let(:users) { Users.new environment }
|
78
89
|
|
79
|
-
let(:posts) { Posts.new
|
90
|
+
let(:posts) { Posts.new environment }
|
80
91
|
|
81
|
-
let(:comments) { Comments.new
|
92
|
+
let(:comments) { Comments.new environment }
|
82
93
|
|
83
|
-
let(:categories) { Categories.new
|
94
|
+
let(:categories) { Categories.new environment }
|
84
95
|
|
85
|
-
let(:people) { People.new
|
96
|
+
let(:people) { People.new environment }
|
86
97
|
|
87
|
-
let
|
88
|
-
driver = (RUBY_ENGINE == 'jruby') ? 'jdbc:sqlite::memory:' : {adapter: :sqlite}
|
98
|
+
let(:languages) { Languages.new environment }
|
89
99
|
|
100
|
+
let(:driver) { (RUBY_ENGINE == 'jruby') ? 'jdbc:sqlite::memory:' : {adapter: :sqlite} }
|
101
|
+
|
102
|
+
let :environment do
|
103
|
+
Rasti::DB::Environment.new default: Rasti::DB::DataSource.new(db),
|
104
|
+
custom: Rasti::DB::DataSource.new(custom_db)
|
105
|
+
end
|
106
|
+
|
107
|
+
let :db do
|
90
108
|
Sequel.connect(driver).tap do |db|
|
91
109
|
|
92
110
|
db.create_table :users do
|
@@ -98,6 +116,7 @@ class Minitest::Spec
|
|
98
116
|
primary_key :id
|
99
117
|
String :title, null: false, unique: true
|
100
118
|
String :body, null: false
|
119
|
+
Integer :language_id, null: false, index: true
|
101
120
|
foreign_key :user_id, :users, null: false, index: true
|
102
121
|
end
|
103
122
|
|
@@ -127,6 +146,23 @@ class Minitest::Spec
|
|
127
146
|
foreign_key :user_id, :users, null: false, unique: true
|
128
147
|
end
|
129
148
|
|
149
|
+
db.create_table :languages_people do
|
150
|
+
Integer :language_id, null: false, index: true
|
151
|
+
foreign_key :document_number, :people, type: String, null: false, index: true
|
152
|
+
primary_key [:language_id, :document_number]
|
153
|
+
end
|
154
|
+
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
let :custom_db do
|
159
|
+
Sequel.connect(driver).tap do |db|
|
160
|
+
|
161
|
+
db.create_table :languages do
|
162
|
+
primary_key :id
|
163
|
+
String :name, null: false, unique: true
|
164
|
+
end
|
165
|
+
|
130
166
|
end
|
131
167
|
end
|
132
168
|
|
data/spec/model_spec.rb
CHANGED
@@ -10,7 +10,7 @@ describe 'Model' do
|
|
10
10
|
end
|
11
11
|
|
12
12
|
it 'Invalid definition' do
|
13
|
-
error = proc {
|
13
|
+
error = proc { Rasti::DB::Model[:id, :name, :name] }.must_raise ArgumentError
|
14
14
|
error.message.must_equal 'Attribute name already exists'
|
15
15
|
end
|
16
16
|
|
@@ -79,4 +79,12 @@ describe 'Model' do
|
|
79
79
|
refute_equal User.new(id: 1, name: 'User 1').hash, User.new(id: 2, name: 'User 2').hash
|
80
80
|
end
|
81
81
|
|
82
|
+
it 'Merge' do
|
83
|
+
user = User.new(id: 1, name: 'User 1')
|
84
|
+
changed_user = user.merge(name: 'User 2')
|
85
|
+
|
86
|
+
user.must_equal User.new(id: 1, name: 'User 1')
|
87
|
+
changed_user.must_equal User.new(id: 1, name: 'User 2')
|
88
|
+
end
|
89
|
+
|
82
90
|
end
|
data/spec/query_spec.rb
CHANGED
@@ -3,18 +3,44 @@ require 'minitest_helper'
|
|
3
3
|
describe 'Query' do
|
4
4
|
|
5
5
|
before do
|
6
|
-
|
6
|
+
custom_db[:languages].insert name: 'Spanish'
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
1.upto(10) do |i|
|
9
|
+
db[:users].insert name: "User #{i}"
|
10
|
+
|
11
|
+
db[:people].insert user_id: i,
|
12
|
+
document_number: "document_#{i}",
|
13
|
+
first_name: "Name #{i}",
|
14
|
+
last_name: "Last Name #{i}",
|
15
|
+
birth_date: Date.parse('2020-04-24')
|
16
|
+
|
17
|
+
db[:languages_people].insert language_id: 1, document_number: "document_#{i}"
|
18
|
+
end
|
12
19
|
|
13
|
-
|
20
|
+
db[:posts].insert user_id: 2, title: 'Sample post', body: '...', language_id: 1
|
21
|
+
db[:posts].insert user_id: 1, title: 'Another post', body: '...', language_id: 1
|
22
|
+
db[:posts].insert user_id: 4, title: 'Best post', body: '...', language_id: 1
|
14
23
|
|
15
|
-
|
24
|
+
1.upto(3) { |i| db[:categories].insert name: "Category #{i}" }
|
25
|
+
|
26
|
+
db[:comments].insert post_id: 1, user_id: 5, text: 'Comment 1'
|
27
|
+
db[:comments].insert post_id: 1, user_id: 7, text: 'Comment 2'
|
28
|
+
db[:comments].insert post_id: 2, user_id: 2, text: 'Comment 3'
|
29
|
+
|
30
|
+
db[:categories_posts].insert post_id: 1, category_id: 1
|
31
|
+
db[:categories_posts].insert post_id: 1, category_id: 2
|
32
|
+
db[:categories_posts].insert post_id: 2, category_id: 2
|
33
|
+
db[:categories_posts].insert post_id: 2, category_id: 3
|
34
|
+
db[:categories_posts].insert post_id: 3, category_id: 3
|
35
|
+
end
|
36
|
+
|
37
|
+
let(:users_query) { Rasti::DB::Query.new collection_class: Users, dataset: db[:users], environment: environment }
|
38
|
+
|
39
|
+
let(:posts_query) { Rasti::DB::Query.new collection_class: Posts, dataset: db[:posts], environment: environment }
|
16
40
|
|
17
|
-
let(:comments_query) { Rasti::DB::Query.new Comments, db[:comments] }
|
41
|
+
let(:comments_query) { Rasti::DB::Query.new collection_class: Comments, dataset: db[:comments], environment: environment }
|
42
|
+
|
43
|
+
let(:languages_query) { Rasti::DB::Query.new collection_class: Languages, dataset: custom_db[:languages], environment: environment }
|
18
44
|
|
19
45
|
it 'Count' do
|
20
46
|
users_query.count.must_equal 10
|
@@ -37,6 +63,83 @@ describe 'Query' do
|
|
37
63
|
users_query.primary_keys.must_equal db[:users].map { |u| u[:id] }
|
38
64
|
end
|
39
65
|
|
66
|
+
it 'Select attributes' do
|
67
|
+
posts_query.select_attributes(:id, :user_id).all.must_equal db[:posts].select(:id, :user_id).map { |r| Post.new r }
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'Exclude attributes' do
|
71
|
+
posts_query.exclude_attributes(:body).all.must_equal db[:posts].select(:id, :user_id, :title, :language_id).map { |r| Post.new r }
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'All attributes' do
|
75
|
+
posts_query.exclude_attributes(:body).all_attributes.all.must_equal db[:posts].map { |r| Post.new r }
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'Select graph attributes' do
|
79
|
+
language = Language.new custom_db[:languages].where(id: 1).select(:id).first
|
80
|
+
|
81
|
+
person = Person.new db[:people].where(document_number: 'document_2').select(:document_number, :user_id).first.merge(languages: [language])
|
82
|
+
|
83
|
+
user = User.new db[:users].where(id: 2).select(:id).first.merge(person: person)
|
84
|
+
|
85
|
+
categories = db[:categories].where(id: [1,2]).select(:id).map { |c| Category.new c }
|
86
|
+
|
87
|
+
post = Post.new db[:posts].where(id: 1).first.merge(user: user, categories: categories)
|
88
|
+
|
89
|
+
selected_attributes = {
|
90
|
+
user: [:id],
|
91
|
+
'user.person' => [:document_number, :user_id],
|
92
|
+
'user.person.languages' => [:id],
|
93
|
+
categories: [:id]
|
94
|
+
}
|
95
|
+
|
96
|
+
posts_query.where(id: 1)
|
97
|
+
.graph(*selected_attributes.keys)
|
98
|
+
.select_graph_attributes(selected_attributes)
|
99
|
+
.all
|
100
|
+
.must_equal [post]
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'Exclude graph attributes' do
|
104
|
+
language = Language.new custom_db[:languages].where(id: 1).select(:id).first
|
105
|
+
|
106
|
+
person = Person.new db[:people].where(document_number: 'document_2').select(:document_number, :user_id).first.merge(languages: [language])
|
107
|
+
|
108
|
+
user = User.new db[:users].where(id: 2).select(:id).first.merge(person: person)
|
109
|
+
|
110
|
+
categories = db[:categories].where(id: [1,2]).select(:id).map { |c| Category.new c }
|
111
|
+
|
112
|
+
post = Post.new db[:posts].where(id: 1).first.merge(user: user, categories: categories)
|
113
|
+
|
114
|
+
excluded_attributes = {
|
115
|
+
user: [:name],
|
116
|
+
'user.person' => [:first_name, :last_name, :birth_date],
|
117
|
+
'user.person.languages' => [:name],
|
118
|
+
categories: [:name]
|
119
|
+
}
|
120
|
+
|
121
|
+
posts_query.where(id: 1)
|
122
|
+
.graph(*excluded_attributes.keys)
|
123
|
+
.exclude_graph_attributes(excluded_attributes)
|
124
|
+
.all
|
125
|
+
.must_equal [post]
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'All graph attributes' do
|
129
|
+
person = Person.new db[:people].where(document_number: 'document_2').first
|
130
|
+
|
131
|
+
user = User.new db[:users].where(id: 2).select(:id).first.merge(person: person)
|
132
|
+
|
133
|
+
post = Post.new db[:posts].where(id: 1).first.merge(user: user)
|
134
|
+
|
135
|
+
posts_query.where(id: 1)
|
136
|
+
.graph('user.person')
|
137
|
+
.exclude_graph_attributes(user: [:name], 'user.person' => [:birth_date, :first_name, :last_name])
|
138
|
+
.all_graph_attributes('user.person')
|
139
|
+
.all
|
140
|
+
.must_equal [post]
|
141
|
+
end
|
142
|
+
|
40
143
|
it 'Map' do
|
41
144
|
users_query.map(&:name).must_equal db[:users].map(:name)
|
42
145
|
end
|
@@ -66,17 +169,17 @@ describe 'Query' do
|
|
66
169
|
|
67
170
|
it 'Order' do
|
68
171
|
posts_query.order(:title).all.must_equal [
|
69
|
-
Post.new(id: 2, user_id: 1, title: 'Another post', body: '...'),
|
70
|
-
Post.new(id: 3, user_id: 4, title: 'Best post', body: '...'),
|
71
|
-
Post.new(id: 1, user_id: 2, title: 'Sample post', body: '...')
|
172
|
+
Post.new(id: 2, user_id: 1, title: 'Another post', body: '...', language_id: 1),
|
173
|
+
Post.new(id: 3, user_id: 4, title: 'Best post', body: '...', language_id: 1),
|
174
|
+
Post.new(id: 1, user_id: 2, title: 'Sample post', body: '...', language_id: 1)
|
72
175
|
]
|
73
176
|
end
|
74
177
|
|
75
178
|
it 'Reverse order' do
|
76
179
|
posts_query.reverse_order(:title).all.must_equal [
|
77
|
-
Post.new(id: 1, user_id: 2, title: 'Sample post', body: '...'),
|
78
|
-
Post.new(id: 3, user_id: 4, title: 'Best post', body: '...'),
|
79
|
-
Post.new(id: 2, user_id: 1, title: 'Another post', body: '...')
|
180
|
+
Post.new(id: 1, user_id: 2, title: 'Sample post', body: '...', language_id: 1),
|
181
|
+
Post.new(id: 3, user_id: 4, title: 'Best post', body: '...', language_id: 1),
|
182
|
+
Post.new(id: 2, user_id: 1, title: 'Another post', body: '...', language_id: 1)
|
80
183
|
]
|
81
184
|
end
|
82
185
|
|
@@ -93,21 +196,48 @@ describe 'Query' do
|
|
93
196
|
end
|
94
197
|
|
95
198
|
it 'Graph' do
|
96
|
-
users_query.graph(:posts).where(id: 1).first.must_equal User.new(id: 1, name: 'User 1', posts: [Post.new(id: 2, user_id: 1, title: 'Another post', body: '...')])
|
199
|
+
users_query.graph(:posts).where(id: 1).first.must_equal User.new(id: 1, name: 'User 1', posts: [Post.new(id: 2, user_id: 1, title: 'Another post', body: '...', language_id: 1)])
|
97
200
|
end
|
98
201
|
|
99
|
-
it '
|
202
|
+
it 'Graph with multiple data sources' do
|
203
|
+
language = Language.new id: 1, name: 'Spanish'
|
204
|
+
|
205
|
+
person = Person.new user_id: 2,
|
206
|
+
document_number: 'document_2',
|
207
|
+
first_name: 'Name 2',
|
208
|
+
last_name: 'Last Name 2',
|
209
|
+
birth_date: Date.parse('2020-04-24'),
|
210
|
+
languages: [language]
|
211
|
+
|
212
|
+
user = User.new id: 2,
|
213
|
+
name: 'User 2',
|
214
|
+
person: person
|
215
|
+
|
216
|
+
post = Post.new id: 1,
|
217
|
+
user_id: 2,
|
218
|
+
user: user,
|
219
|
+
title: 'Sample post',
|
220
|
+
body: '...',
|
221
|
+
language_id: 1,
|
222
|
+
language: language
|
223
|
+
|
224
|
+
posts_query.where(id: 1).graph(:language, 'user.person.languages').first.must_equal post
|
225
|
+
end
|
226
|
+
|
227
|
+
it 'Any?' do
|
100
228
|
users_query.empty?.must_equal false
|
101
229
|
users_query.any?.must_equal true
|
102
230
|
end
|
103
231
|
|
104
|
-
it '
|
232
|
+
it 'Empty?' do
|
233
|
+
db[:comments].truncate
|
234
|
+
|
105
235
|
comments_query.empty?.must_equal true
|
106
236
|
comments_query.any?.must_equal false
|
107
237
|
end
|
108
238
|
|
109
239
|
it 'To String' do
|
110
|
-
users_query.where(id: [1,2,3]).order(:name).to_s.must_equal '#<Rasti::DB::Query: "SELECT
|
240
|
+
users_query.where(id: [1,2,3]).order(:name).to_s.must_equal '#<Rasti::DB::Query: "SELECT `users`.* FROM `users` WHERE (`users`.`id` IN (1, 2, 3)) ORDER BY `users`.`name`">'
|
111
241
|
end
|
112
242
|
|
113
243
|
describe 'Named queries' do
|
@@ -126,108 +256,100 @@ describe 'Query' do
|
|
126
256
|
|
127
257
|
describe 'Join' do
|
128
258
|
|
129
|
-
before do
|
130
|
-
1.upto(10) do |i|
|
131
|
-
db[:people].insert user_id: i,
|
132
|
-
document_number: i,
|
133
|
-
first_name: "Name #{i}",
|
134
|
-
last_name: "Last Name #{i}",
|
135
|
-
birth_date: Time.now
|
136
|
-
end
|
137
|
-
|
138
|
-
1.upto(3) { |i| db[:categories].insert name: "Category #{i}" }
|
139
|
-
|
140
|
-
db[:comments].insert post_id: 1, user_id: 5, text: 'Comment 1'
|
141
|
-
db[:comments].insert post_id: 1, user_id: 7, text: 'Comment 2'
|
142
|
-
db[:comments].insert post_id: 2, user_id: 2, text: 'Comment 3'
|
143
|
-
|
144
|
-
db[:categories_posts].insert post_id: 1, category_id: 1
|
145
|
-
db[:categories_posts].insert post_id: 1, category_id: 2
|
146
|
-
db[:categories_posts].insert post_id: 2, category_id: 2
|
147
|
-
db[:categories_posts].insert post_id: 2, category_id: 3
|
148
|
-
db[:categories_posts].insert post_id: 3, category_id: 3
|
149
|
-
end
|
150
|
-
|
151
259
|
it 'One to Many' do
|
152
|
-
users_query.join(:posts).where(title
|
260
|
+
users_query.join(:posts).where(Sequel[:posts][:title] => 'Sample post').all.must_equal [User.new(id: 2, name: 'User 2')]
|
153
261
|
end
|
154
262
|
|
155
263
|
it 'Many to One' do
|
156
|
-
posts_query.join(:user).where(name
|
264
|
+
posts_query.join(:user).where(Sequel[:user][:name] => 'User 4').all.must_equal [Post.new(id: 3, user_id: 4, title: 'Best post', body: '...', language_id: 1)]
|
157
265
|
end
|
158
266
|
|
159
267
|
it 'One to One' do
|
160
|
-
users_query.join(:person).where(document_number
|
268
|
+
users_query.join(:person).where(Sequel[:person][:document_number] => 'document_1').all.must_equal [User.new(id: 1, name: 'User 1')]
|
161
269
|
end
|
162
270
|
|
163
271
|
it 'Many to Many' do
|
164
|
-
posts_query.join(:categories).where(name
|
165
|
-
Post.new(id: 2, user_id: 1, title: 'Another post', body: '...'),
|
166
|
-
Post.new(id: 3, user_id: 4, title: 'Best post', body: '...'),
|
272
|
+
posts_query.join(:categories).where(Sequel[:categories][:name] => 'Category 3').order(:id).all.must_equal [
|
273
|
+
Post.new(id: 2, user_id: 1, title: 'Another post', body: '...', language_id: 1),
|
274
|
+
Post.new(id: 3, user_id: 4, title: 'Best post', body: '...', language_id: 1),
|
167
275
|
]
|
168
276
|
end
|
169
277
|
|
170
278
|
it 'Nested' do
|
171
279
|
posts_query.join('categories', 'comments.user.person')
|
172
280
|
.where(Sequel[:categories][:name] => 'Category 2')
|
173
|
-
.where(Sequel[:comments__user__person][:document_number] =>
|
281
|
+
.where(Sequel[:comments__user__person][:document_number] => 'document_7')
|
174
282
|
.all
|
175
|
-
.must_equal [Post.new(id: 1, user_id: 2, title: 'Sample post', body: '...')]
|
283
|
+
.must_equal [Post.new(id: 1, user_id: 2, title: 'Sample post', body: '...', language_id: 1)]
|
176
284
|
end
|
177
285
|
|
178
|
-
|
286
|
+
it 'Excluded attributes permanents excluded when join' do
|
287
|
+
posts_query.join(:user)
|
288
|
+
.exclude_attributes(:body)
|
289
|
+
.where(Sequel[:user][:name] => 'User 4')
|
290
|
+
.all
|
291
|
+
.must_equal [Post.new(id: 3, title: 'Best post', user_id: 4, language_id: 1)]
|
179
292
|
|
180
|
-
|
293
|
+
posts_query.exclude_attributes(:body)
|
294
|
+
.join(:user)
|
295
|
+
.where(Sequel[:user][:name] => 'User 4')
|
296
|
+
.all
|
297
|
+
.must_equal [Post.new(id: 3, title: 'Best post', user_id: 4, language_id: 1)]
|
298
|
+
end
|
181
299
|
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
300
|
+
describe 'Multiple data sources' do
|
301
|
+
|
302
|
+
it 'One to Many' do
|
303
|
+
error = proc { languages_query.join(:posts).all }.must_raise RuntimeError
|
304
|
+
error.message.must_equal 'Invalid join of multiple data sources: custom.languages > default.posts'
|
305
|
+
end
|
306
|
+
|
307
|
+
it 'Many to One' do
|
308
|
+
error = proc { posts_query.join(:language).all }.must_raise RuntimeError
|
309
|
+
error.message.must_equal 'Invalid join of multiple data sources: default.posts > custom.languages'
|
189
310
|
end
|
190
311
|
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
db[:comments].insert post_id: 2, user_id: 2, text: 'Comment 3'
|
196
|
-
|
197
|
-
db[:categories_posts].insert post_id: 1, category_id: 1
|
198
|
-
db[:categories_posts].insert post_id: 1, category_id: 2
|
199
|
-
db[:categories_posts].insert post_id: 2, category_id: 2
|
200
|
-
db[:categories_posts].insert post_id: 2, category_id: 3
|
201
|
-
db[:categories_posts].insert post_id: 3, category_id: 3
|
312
|
+
it 'Many to Many' do
|
313
|
+
error = proc { languages_query.join(:people).all }.must_raise RuntimeError
|
314
|
+
error.message.must_equal 'Invalid join of multiple data sources: custom.languages > default.people'
|
315
|
+
end
|
202
316
|
end
|
203
317
|
|
318
|
+
end
|
319
|
+
|
320
|
+
describe 'NQL' do
|
321
|
+
|
204
322
|
it 'Invalid expression' do
|
205
323
|
error = proc { posts_query.nql('a + b') }.must_raise Rasti::DB::NQL::InvalidExpressionError
|
206
324
|
error.message.must_equal 'Invalid filter expression: a + b'
|
207
325
|
end
|
208
326
|
|
209
327
|
it 'Filter to self table' do
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
.sort
|
215
|
-
.must_equal [8, 9, 10]
|
328
|
+
posts_query.nql('user_id > 1')
|
329
|
+
.pluck(:user_id)
|
330
|
+
.sort
|
331
|
+
.must_equal [2, 4]
|
216
332
|
end
|
217
333
|
|
218
334
|
it 'Filter to join table' do
|
219
335
|
posts_query.nql('categories.name = Category 2')
|
220
|
-
.
|
336
|
+
.pluck(:id)
|
221
337
|
.sort
|
222
338
|
.must_equal [1, 2]
|
223
339
|
end
|
224
340
|
|
225
341
|
it 'Filter to 2nd order relation' do
|
226
|
-
posts_query.nql('comments.user.person.document_number =
|
227
|
-
.
|
342
|
+
posts_query.nql('comments.user.person.document_number = document_7')
|
343
|
+
.pluck(:id)
|
228
344
|
.must_equal [1]
|
229
345
|
end
|
230
346
|
|
347
|
+
it 'Filter combined' do
|
348
|
+
posts_query.nql('(categories.id = 1 | categories.id = 3) & comments.user.person.document_number = document_2')
|
349
|
+
.pluck(:id)
|
350
|
+
.must_equal [2]
|
351
|
+
end
|
352
|
+
|
231
353
|
end
|
232
354
|
|
233
355
|
end
|