mongocore 0.1.1 → 0.1.2
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/CHANGELOG.md +4 -0
- data/README.md +28 -10
- data/lib/mongocore/document.rb +22 -5
- data/lib/mongocore/errors.rb +5 -0
- data/lib/mongocore/ext.rb +8 -0
- data/lib/mongocore/query.rb +44 -5
- data/lib/mongocore.rb +6 -1
- data/mongocore.gemspec +3 -3
- metadata +8 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 55808be92e72f178a15d79162ce306e93697af46
|
4
|
+
data.tar.gz: 616b1fa1123ee89dae66153e1b5702679a829310
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c3ca71c855ad06198b6d4d05c8a5abf8816868c53d649caeeb81b9063f72657ce70f6e773d4c7d4a171a06c291279d1524e1153376ba3670f841e748c23eb91b
|
7
|
+
data.tar.gz: e33647c2848cc8d04dc6db9db061c2009637e6e1714c7a74996744efd2ad64e62a60feda4d1137d4f5257a0e7c033c9a79e43a9938df11fcafc43de86d33eea5
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -7,11 +7,11 @@ The perfect companion for Sinatra or other Rack-based web frameworks.
|
|
7
7
|
With Mongocore you can do:
|
8
8
|
|
9
9
|
* Insert, update and delete
|
10
|
-
* Finding, sorting, limit, defaults
|
11
|
-
* Scopes, associations, validations
|
10
|
+
* Finding, sorting, limit, skip, defaults
|
11
|
+
* Scopes, associations, validations, pagination
|
12
12
|
* Read and write access control for each key
|
13
13
|
* Request cache, counter cache, track changes
|
14
|
-
* Automatic timestamps, tagged keys
|
14
|
+
* Automatic timestamps, tagged keys, json
|
15
15
|
|
16
16
|
The schema is specified with a YAML file which supports default values, data types, and security levels for each key.
|
17
17
|
|
@@ -21,10 +21,9 @@ Please read [the source code](https://github.com/fugroup/mongocore/tree/master/l
|
|
21
21
|
| -------------------------------------- | ----- | ------- | ------------- |
|
22
22
|
| [Mongoid](http://mongoid.com) | 256 | 14371 | 10590 |
|
23
23
|
| [MongoMapper](http://mongomapper.com) | 91 | 200 | 4070 |
|
24
|
-
| [Mongocore](http://mongocore.com) |
|
24
|
+
| [Mongocore](http://mongocore.com) | 8 | 224 | 354 |
|
25
25
|
|
26
26
|
<br>
|
27
|
-
If you are looking for something even lighter, we also [have Minimongo,](https://github.com/fugroup/minimongo) the world's tiniest MongoDB library.
|
28
27
|
|
29
28
|
The tests are written [using Futest,](https://github.com/fugroup/futest) try it out if you haven't, it makes testing so much fun.
|
30
29
|
|
@@ -57,6 +56,9 @@ Mongocore.access = true
|
|
57
56
|
# Enable timestamps, auto-save created_at and updated_at keys
|
58
57
|
Mongocore.timestamps = true
|
59
58
|
|
59
|
+
# Pagination results per page
|
60
|
+
Mogocore.per_page = 20
|
61
|
+
|
60
62
|
# Enable debug to see caching information and help
|
61
63
|
Mongocore.debug = false
|
62
64
|
```
|
@@ -64,6 +66,9 @@ Mongocore.debug = false
|
|
64
66
|
### Usage
|
65
67
|
|
66
68
|
```ruby
|
69
|
+
# Set up connection to database engine
|
70
|
+
Mongocore.db = Mongo::Client.new(['127.0.0.1:27017'], :database => "mongocore_#{ENV['RACK_ENV']}")
|
71
|
+
|
67
72
|
# Create a new document
|
68
73
|
m = Model.new
|
69
74
|
m.duration = 59
|
@@ -93,6 +98,11 @@ f = query.first
|
|
93
98
|
# All
|
94
99
|
m = Model.find.all
|
95
100
|
|
101
|
+
# Pagination returns an array
|
102
|
+
m = Model.find.paginate
|
103
|
+
m = Model.find.paginate(:per_page => 10, :page => 5)
|
104
|
+
m.total # => Total number of results
|
105
|
+
|
96
106
|
# All of these can be used:
|
97
107
|
# https://docs.mongodb.com/manual/reference/operator/query-comparison
|
98
108
|
m = Model.find(:house => {:$ne => nil, :$eq => 'Nice'}).last
|
@@ -193,10 +203,17 @@ Mongocore.db[:models].indexes.create_one({:key => 1})
|
|
193
203
|
Mongocore.db[:models].indexes.create_one({:key => 1}, :unique => true)
|
194
204
|
```
|
195
205
|
|
196
|
-
### Schema
|
197
|
-
|
206
|
+
### Schema and models
|
207
|
+
Each model defined using a [YAML.](http://yaml.org) schema file. This is where you define keys, defaults, description, counters, associations, access, tags, scopes and accessors.
|
208
|
+
|
209
|
+
The default schema file location is `APP_ROOT/config/db/schema/*.yml`, so if you have a model called Parent, create a yml file called parent.yml.
|
210
|
+
|
211
|
+
You can change the shema file location like this:
|
212
|
+
```ruby
|
213
|
+
Mongocore.schema = File.join(Dir.pwd, 'your', 'schema', 'path')
|
214
|
+
```
|
198
215
|
|
199
|
-
#### Parent example schema
|
216
|
+
#### Parent example schema, has many Models
|
200
217
|
```yml
|
201
218
|
|
202
219
|
# The meta is information about your model
|
@@ -206,7 +223,8 @@ meta:
|
|
206
223
|
|
207
224
|
keys:
|
208
225
|
|
209
|
-
#
|
226
|
+
# Define the _id field for all your models. The id field (without _)
|
227
|
+
# is an alias to _id, but always returns a string instead of a BSON::ObjectId
|
210
228
|
# @desc: Describes the key, can be used for documentation.
|
211
229
|
# @type: object_id, string, integer, float, boolean, time, hash, array
|
212
230
|
# @default: the default value for the key when you call .new
|
@@ -253,7 +271,7 @@ many:
|
|
253
271
|
```
|
254
272
|
|
255
273
|
|
256
|
-
#### Model example schema
|
274
|
+
#### Model example schema, belongs to Parent
|
257
275
|
|
258
276
|
```yml
|
259
277
|
meta:
|
data/lib/mongocore/document.rb
CHANGED
@@ -57,7 +57,7 @@ module Mongocore
|
|
57
57
|
a[:_id] ? @saved = true : a[:_id] = BSON::ObjectId.new
|
58
58
|
|
59
59
|
# The errors hash
|
60
|
-
@errors =
|
60
|
+
@errors = Mongocore::Errors.new{|h, k| h[k] = []}
|
61
61
|
|
62
62
|
# Defaults
|
63
63
|
self.class.schema.defaults.each{|k, v| write(k, v)}
|
@@ -79,15 +79,15 @@ module Mongocore
|
|
79
79
|
# Save attributes to db
|
80
80
|
def save(o = {})
|
81
81
|
# Send :validate => true to validate
|
82
|
-
return
|
82
|
+
return false unless valid? if o[:validate]
|
83
83
|
|
84
84
|
# Create a new query
|
85
|
-
filter(:save){mq(self.class, {:_id => @_id}).update(attributes)}
|
85
|
+
filter(:save){mq(self.class, {:_id => @_id}).update(attributes).ok?}
|
86
86
|
end
|
87
87
|
|
88
88
|
# Update document in db
|
89
89
|
def update(a = {})
|
90
|
-
a.each{|k, v| write(k, v)}; filter(:update){single.update(a)}
|
90
|
+
a.each{|k, v| write(k, v)}; filter(:update){single.update(a).ok?}
|
91
91
|
end
|
92
92
|
|
93
93
|
# Delete a document in db
|
@@ -132,9 +132,10 @@ module Mongocore
|
|
132
132
|
|
133
133
|
# JSON format, pass tags as symbols: to_json(:badge, :gun)
|
134
134
|
def to_json(*args)
|
135
|
-
attributes(*args).to_json
|
135
|
+
a = attributes(*args); a.delete(:_id); {:id => id}.merge(a).to_json
|
136
136
|
end
|
137
137
|
|
138
|
+
|
138
139
|
# # # # # # # # # # # # # # # #
|
139
140
|
# Validation methods
|
140
141
|
#
|
@@ -225,6 +226,11 @@ module Mongocore
|
|
225
226
|
super
|
226
227
|
end
|
227
228
|
|
229
|
+
# Alias for _id but returns string
|
230
|
+
def id
|
231
|
+
@_id ? @_id.to_s : nil
|
232
|
+
end
|
233
|
+
|
228
234
|
end
|
229
235
|
|
230
236
|
|
@@ -269,6 +275,17 @@ module Mongocore
|
|
269
275
|
find({}, {}, :limit => n)
|
270
276
|
end
|
271
277
|
|
278
|
+
# Skip
|
279
|
+
def skip(n = 0)
|
280
|
+
find({}, {}, :skip => n)
|
281
|
+
end
|
282
|
+
|
283
|
+
# Fields (projection)
|
284
|
+
def fields(o = {})
|
285
|
+
find({}, {}, :fields => o)
|
286
|
+
end
|
287
|
+
|
288
|
+
|
272
289
|
# # # # # # # # #
|
273
290
|
# After, before and validation filters
|
274
291
|
# Pass a method name as symbol or a block
|
data/lib/mongocore/query.rb
CHANGED
@@ -12,11 +12,18 @@ module Mongocore
|
|
12
12
|
|
13
13
|
attr_accessor :model, :collection, :colname, :query, :options, :store, :cache
|
14
14
|
|
15
|
-
#
|
15
|
+
# Mongocore query initializer
|
16
16
|
def initialize(m, q = {}, o = {}, s = {})
|
17
|
-
|
17
|
+
|
18
|
+
# Support find passing an ID
|
18
19
|
q = {:_id => oid(q)} unless q.is_a?(Hash)
|
19
20
|
|
21
|
+
# Support passing :id as :_id
|
22
|
+
q[:_id] = q.delete(:id) if q[:id]
|
23
|
+
|
24
|
+
# Support passing _id as a string
|
25
|
+
q[:_id] = oid(q[:_id]) if q[:_id].is_a?(String)
|
26
|
+
|
20
27
|
# Storing model class. The instance can be found in store[:source]
|
21
28
|
@model = m
|
22
29
|
|
@@ -27,7 +34,7 @@ module Mongocore
|
|
27
34
|
@collection = Mongocore.db[@colname]
|
28
35
|
|
29
36
|
# Storing query and options. Sort and limit is stored in options
|
30
|
-
s[:sort] ||= {}; s[:limit] ||= 0; s[:chain] ||= []; s[:source] ||= nil
|
37
|
+
s[:sort] ||= {}; s[:limit] ||= 0; s[:chain] ||= []; s[:source] ||= nil; s[:fields] ||= {}; s[:skip] ||= 0
|
31
38
|
@query, @options, @store = q, o, s
|
32
39
|
|
33
40
|
# Set up cache
|
@@ -41,7 +48,7 @@ module Mongocore
|
|
41
48
|
|
42
49
|
# Cursor
|
43
50
|
def cursor
|
44
|
-
@collection.find(@query, @options).sort(@store[:sort]).limit(@store[:limit])
|
51
|
+
@collection.find(@query, @options).projection(@store[:fields]).skip(@store[:skip]).sort(@store[:sort]).limit(@store[:limit])
|
45
52
|
end
|
46
53
|
|
47
54
|
# Update
|
@@ -85,6 +92,28 @@ module Mongocore
|
|
85
92
|
fetch(:to_a).map{|d| first(d)}
|
86
93
|
end
|
87
94
|
|
95
|
+
# Paginate
|
96
|
+
def paginate(o = {})
|
97
|
+
|
98
|
+
# Get total count before applying pagination
|
99
|
+
total = fetch(:count)
|
100
|
+
|
101
|
+
# Set page, defaults to 1
|
102
|
+
o[:page] = o[:page].to_i; o[:page] = 1 if o[:page] < 1
|
103
|
+
|
104
|
+
# Set results per page, defaults to 20 in Mongocore.per_page setting
|
105
|
+
o[:per_page] = o[:per_page].to_i; o[:per_page] = Mongocore.per_page if o[:per_page] < 1
|
106
|
+
|
107
|
+
# Skip results
|
108
|
+
store[:skip] = o[:per_page] * (o[:page] - 1)
|
109
|
+
|
110
|
+
# Apply limit
|
111
|
+
store[:limit] = o[:per_page]
|
112
|
+
|
113
|
+
# Fetch the result as array
|
114
|
+
fetch(:to_a).map{|d| first(d)}.tap{|r| r.total = total}
|
115
|
+
end
|
116
|
+
|
88
117
|
# Fetch docs, pass type :first, :to_a or :count
|
89
118
|
def fetch(t)
|
90
119
|
cache.get(t) if Mongocore.cache
|
@@ -95,7 +124,7 @@ module Mongocore
|
|
95
124
|
|
96
125
|
# Sort
|
97
126
|
def sort(o = {})
|
98
|
-
find(@query, options, @store.tap{store[:sort].merge!(o)})
|
127
|
+
find(@query, @options, @store.tap{store[:sort].merge!(o)})
|
99
128
|
end
|
100
129
|
|
101
130
|
# Limit
|
@@ -103,6 +132,16 @@ module Mongocore
|
|
103
132
|
find(@query, @options, @store.tap{store[:limit] = n})
|
104
133
|
end
|
105
134
|
|
135
|
+
# Skip
|
136
|
+
def skip(n = 0)
|
137
|
+
find(@query, @options, @store.tap{store[:skip] = n})
|
138
|
+
end
|
139
|
+
|
140
|
+
# Fields (projection)
|
141
|
+
def fields(o = {})
|
142
|
+
find(@query, @options, @store.tap{store[:fields].merge!(o)})
|
143
|
+
end
|
144
|
+
|
106
145
|
# Cache key
|
107
146
|
def key
|
108
147
|
@key ||= "#{@model}#{@query.sort}#{@options.sort}#{@store.values}"
|
data/lib/mongocore.rb
CHANGED
@@ -15,7 +15,7 @@ module Mongocore
|
|
15
15
|
# @license: MIT, contributions are welcome.
|
16
16
|
# # # # # #
|
17
17
|
|
18
|
-
class << self; attr_accessor :db, :schema, :cache, :access, :timestamps, :debug; end
|
18
|
+
class << self; attr_accessor :db, :schema, :cache, :access, :timestamps, :per_page, :debug; end
|
19
19
|
|
20
20
|
# Schema path is $app_root/config/db/schema/:model_name.yml
|
21
21
|
@schema = File.join(Dir.pwd, 'config', 'db', 'schema')
|
@@ -29,10 +29,15 @@ module Mongocore
|
|
29
29
|
# Enable timestamps, auto-save created_at and updated_at fields
|
30
30
|
@timestamps = true
|
31
31
|
|
32
|
+
# Pagination results per page
|
33
|
+
@per_page = 20
|
34
|
+
|
32
35
|
# Debug option
|
33
36
|
@debug = false
|
34
37
|
end
|
35
38
|
|
39
|
+
require_relative 'mongocore/ext'
|
40
|
+
require_relative 'mongocore/errors'
|
36
41
|
require_relative 'mongocore/document'
|
37
42
|
require_relative 'mongocore/query'
|
38
43
|
require_relative 'mongocore/schema'
|
data/mongocore.gemspec
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'mongocore'
|
3
|
-
s.version = '0.1.
|
4
|
-
s.date = '2017-
|
3
|
+
s.version = '0.1.2'
|
4
|
+
s.date = '2017-10-11'
|
5
5
|
s.summary = "MongoDB ORM implementation on top of the Ruby MongoDB driver"
|
6
|
-
s.description = "Does validations, associations, scopes, filters, counter cache, request cache, and nested queries. Using a YAML schema file, which supports default values, data types, and security levels for each key."
|
6
|
+
s.description = "Does validations, associations, scopes, filters, pagination, counter cache, request cache, and nested queries. Using a YAML schema file, which supports default values, data types, and security levels for each key."
|
7
7
|
s.authors = ["Fugroup Limited"]
|
8
8
|
s.email = 'mail@fugroup.net'
|
9
9
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mongocore
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Fugroup Limited
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-10-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mongo
|
@@ -66,9 +66,9 @@ dependencies:
|
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
|
-
description: Does validations, associations, scopes, filters,
|
70
|
-
cache, and nested queries. Using a YAML schema file, which supports
|
71
|
-
data types, and security levels for each key.
|
69
|
+
description: Does validations, associations, scopes, filters, pagination, counter
|
70
|
+
cache, request cache, and nested queries. Using a YAML schema file, which supports
|
71
|
+
default values, data types, and security levels for each key.
|
72
72
|
email: mail@fugroup.net
|
73
73
|
executables: []
|
74
74
|
extensions: []
|
@@ -86,6 +86,8 @@ files:
|
|
86
86
|
- lib/mongocore/access.rb
|
87
87
|
- lib/mongocore/cache.rb
|
88
88
|
- lib/mongocore/document.rb
|
89
|
+
- lib/mongocore/errors.rb
|
90
|
+
- lib/mongocore/ext.rb
|
89
91
|
- lib/mongocore/filters.rb
|
90
92
|
- lib/mongocore/query.rb
|
91
93
|
- lib/mongocore/schema.rb
|
@@ -112,7 +114,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
112
114
|
version: '0'
|
113
115
|
requirements: []
|
114
116
|
rubyforge_project:
|
115
|
-
rubygems_version: 2.
|
117
|
+
rubygems_version: 2.6.12
|
116
118
|
signing_key:
|
117
119
|
specification_version: 4
|
118
120
|
summary: MongoDB ORM implementation on top of the Ruby MongoDB driver
|