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 CHANGED
@@ -1,5 +1,5 @@
1
1
  task :default => :spec
2
2
 
3
3
  task :spec do
4
- exec *%w[bundle exec ruby lib/mingo.rb --color]
4
+ exec *%w[bundle exec ruby -Ilib lib/mingo.rb --color]
5
5
  end
@@ -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, 'mingo/cursor'
45
- autoload :ManyProxy, 'mingo/many_proxy'
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
- attr_reader :changes
123
-
124
- def initialize(obj = nil)
125
- @changes = {}
126
- @destroyed = false
127
-
128
- if obj and obj['_id'].is_a? BSON::ObjectId
129
- # a doc loaded straight from the db
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.1.5
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-03-07 00:00:00.000000000 +01:00
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: &2157373800 !ruby/object:Gem::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.0'
21
+ version: '1.3'
23
22
  type: :runtime
24
23
  prerelease: false
25
- version_requirements: *2157373800
24
+ version_requirements: *2157911220
26
25
  - !ruby/object:Gem::Dependency
27
26
  name: hashie
28
- requirement: &2157373320 !ruby/object:Gem::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: *2157373320
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.5.3
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: