rasti-db 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,122 @@
1
+ require 'minitest_helper'
2
+
3
+ describe 'Query' do
4
+
5
+ before do
6
+ 1.upto(10) { |i| db[:users].insert name: "User #{i}" }
7
+ db[:posts].insert user_id: 2, title: 'Sample post', body: '...'
8
+ db[:posts].insert user_id: 1, title: 'Another post', body: '...'
9
+ db[:posts].insert user_id: 4, title: 'Best post', body: '...'
10
+ end
11
+
12
+ let(:users_query) { Rasti::DB::Query.new Users, db[:users] }
13
+
14
+ let(:posts_query) { Rasti::DB::Query.new Posts, db[:posts] }
15
+
16
+ let(:comments_query) { Rasti::DB::Query.new Comments, db[:comments] }
17
+
18
+ it 'Count' do
19
+ users_query.count.must_equal 10
20
+ end
21
+
22
+ it 'All' do
23
+ users_query.all.must_equal db[:users].map { |u| User.new u }
24
+ end
25
+
26
+ it 'Raw' do
27
+ users_query.raw.must_equal db[:users].all
28
+ end
29
+
30
+ it 'Pluck' do
31
+ users_query.pluck(:name).must_equal db[:users].map { |u| u[:name] }
32
+ users_query.pluck(:id, :name).must_equal db[:users].map { |u| [u[:id], u[:name]] }
33
+ end
34
+
35
+ it 'Primary keys' do
36
+ users_query.primary_keys.must_equal db[:users].map { |u| u[:id] }
37
+ end
38
+
39
+ it 'Map' do
40
+ users_query.map { |u| u.name }.must_equal db[:users].map(:name)
41
+ end
42
+
43
+ it 'Where' do
44
+ users_query.where(id: 3).all.must_equal [User.new(id: 3, name: 'User 3')]
45
+ end
46
+
47
+ it 'Exclude' do
48
+ users_query.exclude(id: [1,2,3,4,5,6,7,8,9]).all.must_equal [User.new(id: 10, name: 'User 10')]
49
+ end
50
+
51
+ it 'And' do
52
+ users_query.where(id: [1,2]).and(name: 'User 2').all.must_equal [User.new(id: 2, name: 'User 2')]
53
+ end
54
+
55
+ it 'Or' do
56
+ users_query.where(id: 1).or(name: 'User 2').all.must_equal [
57
+ User.new(id: 1, name: 'User 1'),
58
+ User.new(id: 2, name: 'User 2')
59
+ ]
60
+ end
61
+
62
+ it 'Order' do
63
+ posts_query.order(:title).all.must_equal [
64
+ Post.new(id: 2, user_id: 1, title: 'Another post', body: '...'),
65
+ Post.new(id: 3, user_id: 4, title: 'Best post', body: '...'),
66
+ Post.new(id: 1, user_id: 2, title: 'Sample post', body: '...')
67
+ ]
68
+ end
69
+
70
+ it 'Reverse order' do
71
+ posts_query.reverse_order(:title).all.must_equal [
72
+ Post.new(id: 1, user_id: 2, title: 'Sample post', body: '...'),
73
+ Post.new(id: 3, user_id: 4, title: 'Best post', body: '...'),
74
+ Post.new(id: 2, user_id: 1, title: 'Another post', body: '...')
75
+ ]
76
+ end
77
+
78
+ it 'Limit and offset' do
79
+ users_query.limit(1).offset(1).all.must_equal [User.new(id: 2, name: 'User 2')]
80
+ end
81
+
82
+ it 'First' do
83
+ users_query.first.must_equal User.new(id: 1, name: 'User 1')
84
+ end
85
+
86
+ it 'Last' do
87
+ users_query.order(:id).last.must_equal User.new(id: 10, name: 'User 10')
88
+ end
89
+
90
+ it 'Graph' do
91
+ 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: '...')])
92
+ end
93
+
94
+ it 'Empty?' do
95
+ users_query.empty?.must_equal false
96
+ users_query.any?.must_equal true
97
+ end
98
+
99
+ it 'Any?' do
100
+ comments_query.empty?.must_equal true
101
+ comments_query.any?.must_equal false
102
+ end
103
+
104
+ it 'To String' do
105
+ users_query.where(id: [1,2,3]).order(:name).to_s.must_equal '#<Rasti::DB::Query: "SELECT * FROM `users` WHERE (`id` IN (1, 2, 3)) ORDER BY `name`">'
106
+ end
107
+
108
+ describe 'Named queries' do
109
+
110
+ it 'Respond to' do
111
+ posts_query.must_respond_to :created_by
112
+ posts_query.wont_respond_to :by_user
113
+ end
114
+
115
+ it 'Safe method missing' do
116
+ posts_query.created_by(1).first.must_equal Post.new(db[:posts][user_id: 1])
117
+ proc { posts_query.by_user(1) }.must_raise NoMethodError
118
+ end
119
+
120
+ end
121
+
122
+ end
@@ -0,0 +1,144 @@
1
+ require 'minitest_helper'
2
+
3
+ describe 'Relations' do
4
+
5
+ describe 'One to Many' do
6
+
7
+ describe 'Specification' do
8
+
9
+ it 'Implicit' do
10
+ relation = Rasti::DB::Relations::OneToMany.new :posts, Users
11
+
12
+ relation.target_collection_class.must_equal Posts
13
+ relation.foreign_key.must_equal :user_id
14
+ end
15
+
16
+ it 'Explicit' do
17
+ relation = Rasti::DB::Relations::OneToMany.new :articles, Users, collection: 'Posts',
18
+ foreign_key: :id_user
19
+
20
+ relation.target_collection_class.must_equal Posts
21
+ relation.foreign_key.must_equal :id_user
22
+ end
23
+
24
+ end
25
+
26
+ it 'Type' do
27
+ relation = Rasti::DB::Relations::OneToMany.new :posts, Users
28
+
29
+ relation.one_to_many?.must_equal true
30
+ relation.many_to_one?.must_equal false
31
+ relation.many_to_many?.must_equal false
32
+ end
33
+
34
+ it 'Graph' do
35
+ user_id = db[:users].insert name: 'User 1'
36
+ 1.upto(2) { |i| db[:posts].insert user_id: user_id, title: "Post #{i}", body: '...' }
37
+ rows = db[:users].all
38
+
39
+ Users.relations[:posts].graph_to rows, db
40
+
41
+ rows[0][:posts].must_equal posts.where(user_id: user_id).all
42
+ end
43
+
44
+ end
45
+
46
+ describe 'Many to One' do
47
+
48
+ describe 'Specification' do
49
+
50
+ it 'Implicit' do
51
+ relation = Rasti::DB::Relations::ManyToOne.new :user, Posts
52
+
53
+ relation.target_collection_class.must_equal Users
54
+ relation.foreign_key.must_equal :user_id
55
+ end
56
+
57
+ it 'Explicit' do
58
+ relation = Rasti::DB::Relations::ManyToOne.new :publisher, Posts, collection: 'Users',
59
+ foreign_key: :publisher_id
60
+
61
+ relation.target_collection_class.must_equal Users
62
+ relation.foreign_key.must_equal :publisher_id
63
+ end
64
+
65
+ end
66
+
67
+ it 'Type' do
68
+ relation = Rasti::DB::Relations::ManyToOne.new :user, Posts
69
+
70
+ relation.one_to_many?.must_equal false
71
+ relation.many_to_one?.must_equal true
72
+ relation.many_to_many?.must_equal false
73
+ end
74
+
75
+ it 'Graph' do
76
+ user_id = db[:users].insert name: 'User 1'
77
+ db[:posts].insert user_id: user_id, title: 'Post 1', body: '...'
78
+ rows = db[:posts].all
79
+
80
+ Posts.relations[:user].graph_to rows, db
81
+
82
+ rows[0][:user].must_equal users.first
83
+ end
84
+
85
+ end
86
+
87
+ describe 'Many To Many' do
88
+
89
+ describe 'Specification' do
90
+
91
+ it 'Implicit' do
92
+ relation = Rasti::DB::Relations::ManyToMany.new :categories, Posts
93
+
94
+ relation.target_collection_class.must_equal Categories
95
+ relation.source_foreign_key.must_equal :post_id
96
+ relation.target_foreign_key.must_equal :category_id
97
+ relation.relation_collection_name.must_equal :categories_posts
98
+ end
99
+
100
+ it 'Explicit' do
101
+ relation = Rasti::DB::Relations::ManyToMany.new :tags, Posts, collection: 'Categories',
102
+ source_foreign_key: :article_id,
103
+ target_foreign_key: :tag_id,
104
+ relation_collection_name: :tags_articles
105
+
106
+ relation.target_collection_class.must_equal Categories
107
+ relation.source_foreign_key.must_equal :article_id
108
+ relation.target_foreign_key.must_equal :tag_id
109
+ relation.relation_collection_name.must_equal :tags_articles
110
+ end
111
+
112
+ end
113
+
114
+ it 'Type' do
115
+ relation = Rasti::DB::Relations::ManyToMany.new :categories, Posts
116
+
117
+ relation.one_to_many?.must_equal false
118
+ relation.many_to_one?.must_equal false
119
+ relation.many_to_many?.must_equal true
120
+ end
121
+
122
+ it 'Graph' do
123
+ user_id = db[:users].insert name: 'User 1'
124
+
125
+ 1.upto(2) { |i| db[:posts].insert user_id: user_id, title: "Post #{i}", body: '...' }
126
+
127
+ 1.upto(4) { |i| db[:categories].insert name: "Category #{i}" }
128
+
129
+ db[:categories_posts].insert post_id: 1, category_id: 1
130
+ db[:categories_posts].insert post_id: 1, category_id: 2
131
+ db[:categories_posts].insert post_id: 2, category_id: 3
132
+ db[:categories_posts].insert post_id: 2, category_id: 4
133
+
134
+ rows = db[:posts].all
135
+
136
+ Posts.relations[:categories].graph_to rows, db
137
+
138
+ rows[0][:categories].must_equal categories.where(id: [1,2]).all
139
+ rows[1][:categories].must_equal categories.where(id: [3,4]).all
140
+ end
141
+
142
+ end
143
+
144
+ end
@@ -0,0 +1,98 @@
1
+ require 'minitest_helper'
2
+
3
+ describe 'Type Converter' do
4
+
5
+ it 'Apply convertion' do
6
+ type_converter = Rasti::DB::TypeConverter.new db, :users
7
+ type_converter.apply_to(id: '123', name: 'User 1').must_equal id: 123, name: 'User 1'
8
+ end
9
+
10
+ describe 'Postgres' do
11
+
12
+ let(:pg) do
13
+ Object.new.tap do |pg|
14
+ def pg.database_type
15
+ :postgres
16
+ end
17
+
18
+ def pg.schema(table_name, opts={})
19
+ [
20
+ [:hash, {db_type: 'hstore'}],
21
+ [:text_array, {db_type: 'text[]'}],
22
+ [:integer_array, {db_type: 'integer[]'}],
23
+ [:hstore_array, {db_type: 'hstore[]'}],
24
+ [:json, {db_type: 'json'}]
25
+ ]
26
+ end
27
+ end
28
+ end
29
+
30
+ let(:type_converter) { Rasti::DB::TypeConverter.new pg, :table_name }
31
+
32
+ it 'HStore' do
33
+ attributes = type_converter.apply_to hash: {key_1: 1, key_2: 2}
34
+
35
+ attributes[:hash].class.must_equal Sequel::Postgres::HStore
36
+ attributes[:hash].must_equal 'key_1' => '1', 'key_2' => '2'
37
+ end
38
+
39
+ it 'Empty hstore' do
40
+ attributes = type_converter.apply_to hash: {}
41
+
42
+ attributes[:hash].class.must_equal Sequel::Postgres::HStore
43
+ attributes[:hash].must_equal Hash.new
44
+ end
45
+
46
+ it 'Text array' do
47
+ attributes = type_converter.apply_to text_array: %w(a b c)
48
+
49
+ attributes[:text_array].class.must_equal Sequel::Postgres::PGArray
50
+ attributes[:text_array].array_type.must_equal 'text'
51
+ attributes[:text_array].must_equal %w(a b c)
52
+ end
53
+
54
+ it 'Integer array' do
55
+ attributes = type_converter.apply_to integer_array: [1,2,3]
56
+
57
+ attributes[:integer_array].class.must_equal Sequel::Postgres::PGArray
58
+ attributes[:integer_array].array_type.must_equal 'integer'
59
+ attributes[:integer_array].must_equal [1,2,3]
60
+ end
61
+
62
+ it 'Hstore array' do
63
+ attributes = type_converter.apply_to hstore_array: [{key: 0}, {key: 1}]
64
+
65
+ attributes[:hstore_array].class.must_equal Sequel::Postgres::PGArray
66
+ attributes[:hstore_array].array_type.must_equal 'hstore'
67
+
68
+ 2.times do |i|
69
+ attributes[:hstore_array][i].class.must_equal Sequel::Postgres::HStore
70
+ attributes[:hstore_array][i].must_equal 'key' => i.to_s
71
+ end
72
+ end
73
+
74
+ it 'Empty array' do
75
+ attributes = type_converter.apply_to integer_array: []
76
+
77
+ attributes[:integer_array].class.must_equal Sequel::Postgres::PGArray
78
+ attributes[:integer_array].array_type.must_equal 'integer'
79
+ attributes[:integer_array].must_equal []
80
+ end
81
+
82
+ it 'Json' do
83
+ attributes = type_converter.apply_to json: {key_1: {key_2: [3]}}
84
+
85
+ attributes[:json].class.must_equal Sequel::Postgres::JSONHash
86
+ attributes[:json].must_equal key_1: {key_2: [3]}
87
+ end
88
+
89
+ it 'Json array' do
90
+ attributes = type_converter.apply_to json: [{key_1: {key_2: [3]}}]
91
+
92
+ attributes[:json].class.must_equal Sequel::Postgres::JSONArray
93
+ attributes[:json].must_equal [{key_1: {key_2: [3]}}]
94
+ end
95
+
96
+ end
97
+
98
+ end
metadata ADDED
@@ -0,0 +1,231 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rasti-db
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Gabriel Naiman
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-08-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: sequel
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '4.38'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '4.38'
27
+ - !ruby/object:Gem::Dependency
28
+ name: consty
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.12'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.12'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '11.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '11.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: minitest
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '5.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '5.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: minitest-colorin
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '0.1'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0.1'
97
+ - !ruby/object:Gem::Dependency
98
+ name: minitest-line
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '0.6'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '0.6'
111
+ - !ruby/object:Gem::Dependency
112
+ name: simplecov
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '0.12'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '0.12'
125
+ - !ruby/object:Gem::Dependency
126
+ name: coveralls
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '0.8'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '0.8'
139
+ - !ruby/object:Gem::Dependency
140
+ name: pry-nav
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '0.2'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: '0.2'
153
+ - !ruby/object:Gem::Dependency
154
+ name: sqlite3
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: '1.3'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: '1.3'
167
+ description: Database collections and relations
168
+ email:
169
+ - gabynaiman@gmail.com
170
+ executables: []
171
+ extensions: []
172
+ extra_rdoc_files: []
173
+ files:
174
+ - ".coveralls.yml"
175
+ - ".gitignore"
176
+ - ".ruby-gemset"
177
+ - ".ruby-version"
178
+ - ".travis.yml"
179
+ - Gemfile
180
+ - LICENSE.txt
181
+ - README.md
182
+ - Rakefile
183
+ - lib/rasti-db.rb
184
+ - lib/rasti/db.rb
185
+ - lib/rasti/db/collection.rb
186
+ - lib/rasti/db/helpers.rb
187
+ - lib/rasti/db/model.rb
188
+ - lib/rasti/db/query.rb
189
+ - lib/rasti/db/relations.rb
190
+ - lib/rasti/db/type_converter.rb
191
+ - lib/rasti/db/version.rb
192
+ - rasti-db.gemspec
193
+ - spec/collection_spec.rb
194
+ - spec/coverage_helper.rb
195
+ - spec/minitest_helper.rb
196
+ - spec/model_spec.rb
197
+ - spec/query_spec.rb
198
+ - spec/relations_spec.rb
199
+ - spec/type_converter_spec.rb
200
+ homepage: https://github.com/gabynaiman/rasti-db
201
+ licenses:
202
+ - MIT
203
+ metadata: {}
204
+ post_install_message:
205
+ rdoc_options: []
206
+ require_paths:
207
+ - lib
208
+ required_ruby_version: !ruby/object:Gem::Requirement
209
+ requirements:
210
+ - - ">="
211
+ - !ruby/object:Gem::Version
212
+ version: '0'
213
+ required_rubygems_version: !ruby/object:Gem::Requirement
214
+ requirements:
215
+ - - ">="
216
+ - !ruby/object:Gem::Version
217
+ version: '0'
218
+ requirements: []
219
+ rubyforge_project:
220
+ rubygems_version: 2.5.1
221
+ signing_key:
222
+ specification_version: 4
223
+ summary: Database collections and relations
224
+ test_files:
225
+ - spec/collection_spec.rb
226
+ - spec/coverage_helper.rb
227
+ - spec/minitest_helper.rb
228
+ - spec/model_spec.rb
229
+ - spec/query_spec.rb
230
+ - spec/relations_spec.rb
231
+ - spec/type_converter_spec.rb