mingo 0.1.5 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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: