mingo 0.1.5 → 0.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.
- data/Rakefile +1 -1
- data/lib/mingo/callbacks.rb +19 -0
- data/lib/mingo/changes.rb +47 -0
- data/lib/mingo/persistence.rb +63 -0
- data/lib/mingo/timestamps.rb +21 -0
- data/lib/mingo.rb +22 -107
- metadata +13 -10
data/Rakefile
CHANGED
@@ -0,0 +1,19 @@
|
|
1
|
+
class Mingo
|
2
|
+
module Callbacks
|
3
|
+
def self.included(base)
|
4
|
+
base.extend ActiveModel::Callbacks
|
5
|
+
base.send :define_model_callbacks, :create, :save, :update, :destroy
|
6
|
+
end
|
7
|
+
|
8
|
+
def save(*args)
|
9
|
+
action = persisted? ? 'update' : 'create'
|
10
|
+
send(:"_run_#{action}_callbacks") do
|
11
|
+
_run_save_callbacks { super }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def destroy
|
16
|
+
_run_destroy_callbacks { super }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
class Mingo
|
2
|
+
module Changes
|
3
|
+
def self.included(base)
|
4
|
+
base.after_save :clear_changes
|
5
|
+
end
|
6
|
+
|
7
|
+
attr_reader :changes
|
8
|
+
|
9
|
+
def initialize(*args)
|
10
|
+
@changes = {}
|
11
|
+
super
|
12
|
+
end
|
13
|
+
|
14
|
+
def changed?
|
15
|
+
changes.any?
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def _regular_writer(key, value)
|
21
|
+
track_change(key, value)
|
22
|
+
super
|
23
|
+
end
|
24
|
+
|
25
|
+
def track_change(key, value)
|
26
|
+
old_value = _regular_reader(key)
|
27
|
+
unless value == old_value
|
28
|
+
memo = (changes[key.to_sym] ||= [old_value])
|
29
|
+
memo[0] == value ? changes.delete(key.to_sym) : (memo[1] = value)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def clear_changes
|
34
|
+
changes.clear
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def values_for_update
|
40
|
+
changes.inject('$set' => {}, '$unset' => {}) do |doc, (key, values)|
|
41
|
+
value = values[1]
|
42
|
+
value.nil? ? (doc['$unset'][key] = 1) : (doc['$set'][key] = value)
|
43
|
+
doc
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
|
3
|
+
class Mingo
|
4
|
+
module Persistence
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
def create(obj = nil)
|
9
|
+
new(obj).tap do |object|
|
10
|
+
yield object if block_given?
|
11
|
+
object.save
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
module InstanceMethods
|
17
|
+
def initialize(*args)
|
18
|
+
@destroyed = false
|
19
|
+
super
|
20
|
+
end
|
21
|
+
|
22
|
+
def persisted?
|
23
|
+
!!id
|
24
|
+
end
|
25
|
+
|
26
|
+
def save(options = {})
|
27
|
+
if persisted?
|
28
|
+
hash = values_for_update
|
29
|
+
unless %w[$set $unset] == hash.keys && hash.values.all? { |v| v.empty? }
|
30
|
+
update(hash, options)
|
31
|
+
end
|
32
|
+
else
|
33
|
+
self['_id'] = self.class.collection.insert(self.to_hash, options)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def update(doc, options = {})
|
38
|
+
self.class.collection.update({'_id' => self.id}, doc, options)
|
39
|
+
end
|
40
|
+
|
41
|
+
def reload
|
42
|
+
doc = self.class.first(id, :convert => nil)
|
43
|
+
replace doc
|
44
|
+
end
|
45
|
+
|
46
|
+
def destroy
|
47
|
+
self.class.collection.remove('_id' => self.id)
|
48
|
+
@destroyed = true
|
49
|
+
self.freeze
|
50
|
+
end
|
51
|
+
|
52
|
+
def destroyed?
|
53
|
+
@destroyed
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def values_for_update
|
59
|
+
self.to_hash
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class Mingo
|
2
|
+
module Timestamps
|
3
|
+
def self.included(base)
|
4
|
+
base.before_update :touch_updated_timestamp
|
5
|
+
end
|
6
|
+
|
7
|
+
def created_at
|
8
|
+
@created_at ||= self.id && self.id.generation_time
|
9
|
+
end
|
10
|
+
|
11
|
+
def updated_at
|
12
|
+
self[:updated_at] || created_at
|
13
|
+
end
|
14
|
+
|
15
|
+
protected
|
16
|
+
|
17
|
+
def touch_updated_timestamp
|
18
|
+
self[:updated_at] = Time.now if changed?
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/mingo.rb
CHANGED
@@ -2,10 +2,6 @@ require 'active_support/core_ext/hash/conversions'
|
|
2
2
|
require 'mongo'
|
3
3
|
require 'active_model'
|
4
4
|
require 'hashie/dash'
|
5
|
-
# for ObjectId:
|
6
|
-
require 'thread'
|
7
|
-
require 'socket'
|
8
|
-
require 'digest/md5'
|
9
5
|
|
10
6
|
BSON::ObjectId.class_eval do
|
11
7
|
def self.[](id)
|
@@ -15,34 +11,18 @@ BSON::ObjectId.class_eval do
|
|
15
11
|
def id
|
16
12
|
self
|
17
13
|
end
|
18
|
-
|
19
|
-
def initialize(time_or_data = nil)
|
20
|
-
if Time === time_or_data or Date === time_or_data
|
21
|
-
@data = generate_from_time(time_or_data)
|
22
|
-
else
|
23
|
-
@data = time_or_data || generate
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
private
|
28
|
-
|
29
|
-
def generate_from_time(time)
|
30
|
-
oid = ''
|
31
|
-
oid += [time.to_i].pack("N")
|
32
|
-
oid += Digest::MD5.digest(Socket.gethostname)[0, 3]
|
33
|
-
oid += [Process.pid % 0xFFFF].pack("n")
|
34
|
-
oid += [get_inc].pack("N")[1, 3]
|
35
|
-
oid.unpack("C12")
|
36
|
-
end
|
37
14
|
end
|
38
15
|
|
39
16
|
class Mingo < Hashie::Dash
|
40
|
-
# ActiveModel::Callbacks
|
41
17
|
include ActiveModel::Conversion
|
42
18
|
extend ActiveModel::Translation
|
43
19
|
|
44
|
-
autoload :Cursor,
|
45
|
-
autoload :ManyProxy,
|
20
|
+
autoload :Cursor, 'mingo/cursor'
|
21
|
+
autoload :ManyProxy, 'mingo/many_proxy'
|
22
|
+
autoload :Persistence, 'mingo/persistence'
|
23
|
+
autoload :Callbacks, 'mingo/callbacks'
|
24
|
+
autoload :Changes, 'mingo/changes'
|
25
|
+
autoload :Timestamps, 'mingo/timestamps'
|
46
26
|
|
47
27
|
class << self
|
48
28
|
attr_writer :db, :collection
|
@@ -101,13 +81,6 @@ class Mingo < Hashie::Dash
|
|
101
81
|
end
|
102
82
|
end
|
103
83
|
|
104
|
-
def create(obj = nil)
|
105
|
-
new(obj).tap do |object|
|
106
|
-
yield object if block_given?
|
107
|
-
object.save
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
84
|
def many(property, *args, &block)
|
112
85
|
proxy_class = block_given?? Class.new(ManyProxy, &block) : ManyProxy
|
113
86
|
ivar = "@#{property}"
|
@@ -119,18 +92,23 @@ class Mingo < Hashie::Dash
|
|
119
92
|
end
|
120
93
|
end
|
121
94
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
merge!(obj)
|
131
|
-
else
|
132
|
-
super
|
95
|
+
include Module.new {
|
96
|
+
def initialize(obj = nil)
|
97
|
+
if obj and obj['_id'].is_a? BSON::ObjectId
|
98
|
+
# a doc loaded straight from the db
|
99
|
+
merge!(obj)
|
100
|
+
else
|
101
|
+
super
|
102
|
+
end
|
133
103
|
end
|
104
|
+
}
|
105
|
+
|
106
|
+
include Persistence
|
107
|
+
include Callbacks
|
108
|
+
include Changes
|
109
|
+
|
110
|
+
def id
|
111
|
+
self['_id']
|
134
112
|
end
|
135
113
|
|
136
114
|
# overwrite these to avoid checking for declared properties
|
@@ -147,72 +125,9 @@ class Mingo < Hashie::Dash
|
|
147
125
|
def stringify_keys() self end
|
148
126
|
alias :stringify_keys! :stringify_keys
|
149
127
|
|
150
|
-
def id
|
151
|
-
self['_id']
|
152
|
-
end
|
153
|
-
|
154
|
-
def persisted?
|
155
|
-
!!id
|
156
|
-
end
|
157
|
-
|
158
|
-
def save(options = {})
|
159
|
-
if persisted?
|
160
|
-
update(values_for_update, options)
|
161
|
-
else
|
162
|
-
self['_id'] = self.class.collection.insert(self.to_hash, options)
|
163
|
-
end.
|
164
|
-
tap { changes.clear }
|
165
|
-
end
|
166
|
-
|
167
|
-
def update(doc, options = {})
|
168
|
-
self.class.collection.update({'_id' => self.id}, doc, options)
|
169
|
-
end
|
170
|
-
|
171
|
-
def reload
|
172
|
-
doc = self.class.first(id, :convert => nil)
|
173
|
-
replace doc
|
174
|
-
end
|
175
|
-
|
176
|
-
def destroy
|
177
|
-
self.class.collection.remove('_id' => self.id)
|
178
|
-
@destroyed = true
|
179
|
-
self.freeze
|
180
|
-
end
|
181
|
-
|
182
|
-
def destroyed?
|
183
|
-
@destroyed
|
184
|
-
end
|
185
|
-
|
186
|
-
def changed?
|
187
|
-
changes.any?
|
188
|
-
end
|
189
|
-
|
190
128
|
def ==(other)
|
191
129
|
other.is_a?(self.class) and other.id == self.id
|
192
130
|
end
|
193
|
-
|
194
|
-
private
|
195
|
-
|
196
|
-
def values_for_update
|
197
|
-
changes.inject('$set' => {}, '$unset' => {}) do |doc, (key, values)|
|
198
|
-
value = values[1]
|
199
|
-
value.nil? ? (doc['$unset'][key] = 1) : (doc['$set'][key] = value)
|
200
|
-
doc
|
201
|
-
end
|
202
|
-
end
|
203
|
-
|
204
|
-
def _regular_writer(key, value)
|
205
|
-
track_change(key, value)
|
206
|
-
super
|
207
|
-
end
|
208
|
-
|
209
|
-
def track_change(key, value)
|
210
|
-
old_value = _regular_reader(key)
|
211
|
-
unless value == old_value
|
212
|
-
memo = (changes[key.to_sym] ||= [old_value])
|
213
|
-
memo[0] == value ? changes.delete(key.to_sym) : (memo[1] = value)
|
214
|
-
end
|
215
|
-
end
|
216
131
|
end
|
217
132
|
|
218
133
|
if $0 == __FILE__
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mingo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,23 +9,22 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-
|
13
|
-
default_executable:
|
12
|
+
date: 2011-04-26 00:00:00.000000000Z
|
14
13
|
dependencies:
|
15
14
|
- !ruby/object:Gem::Dependency
|
16
15
|
name: mongo
|
17
|
-
requirement: &
|
16
|
+
requirement: &2157911220 !ruby/object:Gem::Requirement
|
18
17
|
none: false
|
19
18
|
requirements:
|
20
19
|
- - ! '>='
|
21
20
|
- !ruby/object:Gem::Version
|
22
|
-
version: '1.
|
21
|
+
version: '1.3'
|
23
22
|
type: :runtime
|
24
23
|
prerelease: false
|
25
|
-
version_requirements: *
|
24
|
+
version_requirements: *2157911220
|
26
25
|
- !ruby/object:Gem::Dependency
|
27
26
|
name: hashie
|
28
|
-
requirement: &
|
27
|
+
requirement: &2157910740 !ruby/object:Gem::Requirement
|
29
28
|
none: false
|
30
29
|
requirements:
|
31
30
|
- - ! '>='
|
@@ -33,7 +32,7 @@ dependencies:
|
|
33
32
|
version: 0.4.0
|
34
33
|
type: :runtime
|
35
34
|
prerelease: false
|
36
|
-
version_requirements: *
|
35
|
+
version_requirements: *2157910740
|
37
36
|
description: Mingo is a minimal document-object mapper for MongoDB.
|
38
37
|
email: mislav.marohnic@gmail.com
|
39
38
|
executables: []
|
@@ -41,10 +40,13 @@ extensions: []
|
|
41
40
|
extra_rdoc_files: []
|
42
41
|
files:
|
43
42
|
- Rakefile
|
43
|
+
- lib/mingo/callbacks.rb
|
44
|
+
- lib/mingo/changes.rb
|
44
45
|
- lib/mingo/cursor.rb
|
45
46
|
- lib/mingo/many_proxy.rb
|
47
|
+
- lib/mingo/persistence.rb
|
48
|
+
- lib/mingo/timestamps.rb
|
46
49
|
- lib/mingo.rb
|
47
|
-
has_rdoc: false
|
48
50
|
homepage: http://github.com/mislav/mingo
|
49
51
|
licenses: []
|
50
52
|
post_install_message:
|
@@ -65,8 +67,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
65
67
|
version: '0'
|
66
68
|
requirements: []
|
67
69
|
rubyforge_project:
|
68
|
-
rubygems_version: 1.
|
70
|
+
rubygems_version: 1.7.2
|
69
71
|
signing_key:
|
70
72
|
specification_version: 3
|
71
73
|
summary: Minimal Mongo
|
72
74
|
test_files: []
|
75
|
+
has_rdoc:
|