mongoo 0.3.1 → 0.4.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/CHANGELOG CHANGED
@@ -1,18 +1,19 @@
1
1
  == Changelog
2
2
 
3
- === 0.3.0
3
+ === 0.4.0
4
4
 
5
- * refactored a bunch of connection and async related stuff. see README
5
+ * Reverted 0.3.2 and replaced with better, more compatible improvements.
6
+ Major speed increases are still here but it works as it did before.
6
7
 
7
- === 0.2.4
8
+ === 0.3.2
8
9
 
9
- * async mode works again, but now you have to manually require:
10
+ * implemented some optimizations that provide some major speed improvements
11
+ for instantiating Mongoo::Base objects. Also added a :raw => true option
12
+ to finds so that you can get back a raw hash.
10
13
 
11
- require "mongoo/async"
12
- Mongoo.conn_opts = ["localhost", 27017, :pool_size => 5, :timeout => 5]
13
- Mongoo.db_name = "mongoo-test"
14
+ === 0.3.0
14
15
 
15
- see test_async.rb for an example.
16
+ * refactored a bunch of connection and async related stuff. see README
16
17
 
17
18
  === 0.2.1
18
19
 
@@ -25,24 +26,12 @@
25
26
 
26
27
  * Can no longer set Mongoo.config = {...}
27
28
 
28
- Set Mongoo.conn_opts and Mongoo.db_name instead (more flexibility):
29
-
30
- Mongoo.conn_opts = ["localhost", 27017, :pool_size => 5, :timeout => 5]
31
- Mongoo.db_name = "mongoo-test"
32
-
33
- You can set these on a model level as well:
34
-
35
- Person.conn = Mongo::Connection.new("localhost", 30000, :pool_size => 5, :timeout => 5)
36
- Person.db_name = "mongoo-test"
37
-
38
-
39
29
  * You can optionally set the collection name on a model now:
40
30
 
41
31
  class Person < Mongoo::Base
42
32
  collection_name "spacemen"
43
33
  end
44
34
 
45
-
46
35
  * There is a new Identity Map feature available. It will only work when using find_one to
47
36
  find a specific id. You need to manually turn it on:
48
37
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.1
1
+ 0.4.0
data/lib/mongoo/base.rb CHANGED
@@ -1,30 +1,30 @@
1
1
  module Mongoo
2
2
  class UnknownAttributeError < Exception; end
3
-
3
+
4
4
  class Base
5
-
5
+
6
6
  include Mongoo::Changelog
7
7
  include Mongoo::Persistence
8
8
  include Mongoo::Modifiers
9
-
9
+
10
10
  include ActiveModel::Validations
11
-
11
+
12
12
  extend ActiveModel::Callbacks
13
13
  extend ActiveModel::Naming
14
-
14
+
15
15
  define_model_callbacks :insert, :update, :remove
16
-
16
+
17
17
  def self.attribute(name, opts={})
18
18
  raise ArgumentError.new("missing :type") unless opts[:type]
19
19
  self.attributes[name.to_s] = opts
20
20
  define_attribute_methods
21
21
  true
22
22
  end
23
-
23
+
24
24
  def self.attributes
25
25
  Mongoo::ATTRIBUTE_META[self.to_s] ||= {}
26
26
  end
27
-
27
+
28
28
  def self.attributes_tree
29
29
  tree = {}
30
30
  self.attributes.each do |name, opts|
@@ -41,7 +41,7 @@ module Mongoo
41
41
  end
42
42
  tree
43
43
  end
44
-
44
+
45
45
  def self.define_attribute_methods
46
46
  define_method("id") do
47
47
  get("_id")
@@ -49,7 +49,7 @@ module Mongoo
49
49
  define_method("id=") do |val|
50
50
  set("_id", val)
51
51
  end
52
-
52
+
53
53
  self.attributes_tree.each do |name, val|
54
54
  if val.is_a?(Hash)
55
55
  define_method(name) do
@@ -65,17 +65,17 @@ module Mongoo
65
65
  end
66
66
  end
67
67
  end
68
-
68
+
69
69
  def self.known_attribute?(k)
70
70
  k == "_id" || self.attributes[k.to_s]
71
71
  end
72
-
72
+
73
73
  def initialize(hash={}, persisted=false)
74
74
  @persisted = persisted
75
75
  init_from_hash(hash)
76
- set_persisted_mongohash((persisted? ? mongohash.deep_clone : nil))
76
+ set_persisted_mongohash((persisted? ? mongohash : nil))
77
77
  end
78
-
78
+
79
79
  def ==(val)
80
80
  if val.class.to_s == self.class.to_s
81
81
  if val.persisted?
@@ -85,15 +85,15 @@ module Mongoo
85
85
  end
86
86
  end
87
87
  end
88
-
88
+
89
89
  def known_attribute?(k)
90
90
  self.class.known_attribute?(k)
91
91
  end
92
-
92
+
93
93
  def read_attribute_for_validation(key)
94
94
  get_attribute(key)
95
95
  end
96
-
96
+
97
97
  def get_attribute(k)
98
98
  unless known_attribute?(k)
99
99
  raise UnknownAttributeError, k
@@ -102,7 +102,7 @@ module Mongoo
102
102
  end
103
103
  alias :get :get_attribute
104
104
  alias :g :get_attribute
105
-
105
+
106
106
  def set_attribute(k,v)
107
107
  unless known_attribute?(k)
108
108
  if self.respond_to?("#{k}=")
@@ -119,36 +119,36 @@ module Mongoo
119
119
  end
120
120
  alias :set :set_attribute
121
121
  alias :s :set_attribute
122
-
122
+
123
123
  def unset_attribute(k)
124
124
  mongohash.dot_delete(k); true
125
125
  end
126
126
  alias :unset :unset_attribute
127
127
  alias :u :unset_attribute
128
-
128
+
129
129
  def set_attributes(k_v_pairs)
130
130
  k_v_pairs.each do |k,v|
131
131
  set_attribute(k,v)
132
132
  end
133
133
  end
134
134
  alias :sets :set_attributes
135
-
135
+
136
136
  def get_attributes(keys)
137
137
  found = {}
138
138
  keys.each { |k| found[k.to_s] = get_attribute(k) }
139
139
  found
140
140
  end
141
141
  alias :gets :get_attributes
142
-
142
+
143
143
  def unset_attributes(keys)
144
144
  keys.each { |k| unset_attribute(k) }; true
145
145
  end
146
146
  alias :unsets :unset_attributes
147
-
147
+
148
148
  def attributes
149
149
  mongohash.to_key_value
150
150
  end
151
-
151
+
152
152
  def merge!(hash)
153
153
  if hash.is_a?(Mongoo::Mongohash)
154
154
  hash = hash.raw_hash
@@ -158,36 +158,37 @@ module Mongoo
158
158
  set_mongohash( Mongoo::Mongohash.new(hash) )
159
159
  mongohash
160
160
  end
161
-
161
+
162
162
  def init_from_hash(hash)
163
163
  unless hash.is_a?(Mongoo::Mongohash)
164
164
  hash = Mongoo::Mongohash.new(hash)
165
165
  end
166
- verify_attributes_in_mongohash(hash)
167
166
  set_mongohash hash
168
167
  end
169
168
  protected :init_from_hash
170
-
169
+
171
170
  def set_mongohash(mongohash)
172
171
  @mongohash = mongohash
173
172
  end
174
173
  protected :set_mongohash
175
-
174
+
176
175
  def mongohash
177
176
  @mongohash
178
177
  end
179
-
178
+
180
179
  def set_persisted_mongohash(hash)
181
- @persisted_mongohash = hash
180
+ @serialized_persisted_mongohash = Marshal.dump(hash)
181
+ @persisted_mongohash = nil
182
+ true
182
183
  end
183
184
  protected :set_persisted_mongohash
184
-
185
+
185
186
  def persisted_mongohash
186
- @persisted_mongohash
187
+ @persisted_mongohash ||= begin
188
+ if @serialized_persisted_mongohash
189
+ Marshal.load(@serialized_persisted_mongohash)
190
+ end
191
+ end
187
192
  end
188
-
189
- def verify_attributes_in_mongohash(hash)
190
- true
191
- end # verify_attributes_in_mongohash
192
193
  end
193
194
  end
data/lib/mongoo/cursor.rb CHANGED
@@ -11,9 +11,7 @@ module Mongoo
11
11
 
12
12
  def next_document
13
13
  if doc = @mongo_cursor.next_document
14
- obj = @obj_class.new(doc, true)
15
- Mongoo::IdentityMap.write(obj) if Mongoo::IdentityMap.on?
16
- obj
14
+ obj_from_doc(doc)
17
15
  end
18
16
  end
19
17
 
@@ -21,17 +19,12 @@ module Mongoo
21
19
 
22
20
  def each
23
21
  @mongo_cursor.each do |doc|
24
- obj = @obj_class.new(doc, true)
25
- Mongoo::IdentityMap.write(obj) if Mongoo::IdentityMap.on?
26
- yield obj
22
+ yield obj_from_doc(doc)
27
23
  end
28
24
  end
29
25
 
30
26
  def to_a
31
- arr = @mongo_cursor.to_a.collect { |doc| @obj_class.new(doc, true) }
32
- if Mongoo::IdentityMap.on?
33
- arr.each { |obj| Mongoo::IdentityMap.write(obj) }
34
- end; arr
27
+ @mongo_cursor.to_a.collect { |doc| obj_from_doc(doc) }
35
28
  end
36
29
 
37
30
  def count
@@ -65,6 +58,18 @@ module Mongoo
65
58
  super
66
59
  end
67
60
  end
61
+
62
+ def obj_from_doc(doc)
63
+ obj = nil
64
+ if Mongoo::IdentityMap.on?
65
+ if obj = Mongoo::IdentityMap.read(doc["_id"])
66
+ obj.merge!(doc)
67
+ end
68
+ end
69
+ obj ||= @obj_class.new(doc, true)
70
+ Mongoo::IdentityMap.write(obj) if Mongoo::IdentityMap.on?
71
+ obj
72
+ end
68
73
 
69
74
  end
70
75
  end
@@ -1,9 +1,6 @@
1
1
  module Mongoo
2
2
  module HashExt
3
- def deep_stringify_keys
4
- deep_clone.deep_stringify_keys!
5
- end
6
-
3
+
7
4
  def deep_stringify_keys!
8
5
  keys.each do |key|
9
6
  self[key.to_s] = delete(key)
@@ -13,10 +10,7 @@ module Mongoo
13
10
  end
14
11
  self
15
12
  end
16
-
17
- def deep_clone
18
- Marshal.load(Marshal.dump(self))
19
- end
13
+
20
14
  end
21
15
  end
22
16
 
@@ -48,7 +48,7 @@ module Mongoo
48
48
  end
49
49
 
50
50
  def write(doc)
51
- if store
51
+ if store && !store.has_key?(doc.id.to_s)
52
52
  store[doc.id.to_s] = doc
53
53
  end
54
54
  end
@@ -1,24 +1,20 @@
1
1
  module Mongoo
2
2
  class Mongohash
3
3
  extend Forwardable
4
-
4
+
5
5
  def_delegators :@raw_hash, :==, :[], :[], :[]=, :clear, :default, :default=, :default_proc, :delete, :delete_if,
6
6
  :each, :each_key, :each_pair, :each_value, :empty?, :fetch, :has_key?, :has_value?, :include?,
7
7
  :index, :indexes, :indices, :initialize_copy, :inspect, :invert, :key?, :keys, :length, :member?,
8
8
  :merge, :merge!, :pretty_print, :pretty_print_cycle, :rehash, :reject, :reject!, :replace, :select,
9
9
  :shift, :size, :sort, :store, :to_a, :to_hash, :to_s, :update, :value?, :values, :values_at
10
-
10
+
11
11
  attr_reader :raw_hash
12
-
12
+
13
13
  def initialize(hash={})
14
14
  hash = hash.to_hash unless hash.class.to_s == "Hash"
15
- @raw_hash = hash.deep_stringify_keys
15
+ @raw_hash = hash.deep_stringify_keys!
16
16
  end
17
17
 
18
- def deep_clone
19
- Mongoo::Mongohash.new(self.raw_hash.deep_clone)
20
- end
21
-
22
18
  def dot_set(k,v)
23
19
  parts = k.to_s.split(".")
24
20
  curr_val = to_hash
@@ -33,7 +29,7 @@ module Mongoo
33
29
  end
34
30
  true
35
31
  end
36
-
32
+
37
33
  def dot_get(k)
38
34
  parts = k.to_s.split(".")
39
35
  curr_val = to_hash
@@ -44,7 +40,7 @@ module Mongoo
44
40
  end
45
41
  curr_val
46
42
  end
47
-
43
+
48
44
  def dot_delete(k)
49
45
  parts = k.to_s.split(".")
50
46
  curr_val = to_hash
@@ -59,7 +55,7 @@ module Mongoo
59
55
  end
60
56
  false
61
57
  end
62
-
58
+
63
59
  def dot_list(curr_hash=self.to_hash, path=[])
64
60
  list = []
65
61
  curr_hash.each do |k,v|
@@ -71,7 +67,7 @@ module Mongoo
71
67
  end
72
68
  list
73
69
  end
74
-
70
+
75
71
  def to_key_value
76
72
  kv = {}; dot_list.collect { |k| kv[k] = dot_get(k) }; kv
77
73
  end
@@ -74,11 +74,7 @@ module Mongoo
74
74
  end
75
75
 
76
76
  if doc = collection.find_one(query, opts)
77
- doc = new(doc, true)
78
- Mongoo::IdentityMap.write(doc) if id_map_on && is_simple_query
79
- doc
80
- else
81
- nil
77
+ Mongoo::Cursor.new(self, nil).obj_from_doc(doc)
82
78
  end
83
79
  end
84
80
 
@@ -155,13 +151,13 @@ module Mongoo
155
151
  return false
156
152
  end
157
153
  end
158
- ret = self.collection.insert(mongohash.deep_clone, opts)
154
+ ret = self.collection.insert(mongohash, opts)
159
155
  unless ret.is_a?(BSON::ObjectId)
160
156
  raise InsertError, "not an object: #{ret.inspect}"
161
157
  end
162
158
  set("_id", ret)
163
159
  @persisted = true
164
- set_persisted_mongohash(mongohash.deep_clone)
160
+ set_persisted_mongohash(mongohash)
165
161
  ret
166
162
  end
167
163
  Mongoo::IdentityMap.write(self) if Mongoo::IdentityMap.on?
@@ -194,7 +190,7 @@ module Mongoo
194
190
  end
195
191
  ret = self.collection.update(update_query_hash.merge({"_id" => get("_id")}), update_hash, opts)
196
192
  if !ret.is_a?(Hash) || (ret["updatedExisting"] && ret["n"] == 1)
197
- set_persisted_mongohash(mongohash.deep_clone)
193
+ set_persisted_mongohash(mongohash)
198
194
  @persisted = true
199
195
  true
200
196
  else
@@ -242,7 +238,7 @@ module Mongoo
242
238
  def reload
243
239
  init_from_hash(collection.find_one(get("_id")))
244
240
  @persisted = true
245
- set_persisted_mongohash(mongohash.deep_clone)
241
+ set_persisted_mongohash(mongohash)
246
242
  true
247
243
  end
248
244
 
data/mongoo.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{mongoo}
8
- s.version = "0.3.1"
8
+ s.version = "0.4.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Ben Myles"]
12
- s.date = %q{2011-05-17}
12
+ s.date = %q{2011-05-27}
13
13
  s.description = %q{Simple object mapper for MongoDB}
14
14
  s.email = %q{ben.myles@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -8,6 +8,22 @@ class TestIdentityMap < Test::Unit::TestCase
8
8
  obj.create_indexes
9
9
  end
10
10
  end
11
+
12
+ should "be performant" do
13
+ 1.upto(1000) do |i|
14
+ p = Person.new("name" => "Ben#{i}")
15
+ p.insert!
16
+ end
17
+
18
+ Mongoo::IdentityMap.on!
19
+
20
+ all = Person.find.to_a
21
+
22
+ p = Person.find(name: "Ben5").next
23
+ assert_equal p.object_id, all[all.index(p)].object_id
24
+
25
+ Mongoo::IdentityMap.off!
26
+ end
11
27
 
12
28
  should "set and get attributes" do
13
29
  p = Person.new("name" => "Ben")
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: mongoo
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.3.1
5
+ version: 0.4.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - Ben Myles
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-05-17 00:00:00 -07:00
13
+ date: 2011-05-27 00:00:00 -07:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -197,7 +197,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
197
197
  requirements:
198
198
  - - ">="
199
199
  - !ruby/object:Gem::Version
200
- hash: -2907379497624021949
200
+ hash: 2193445635464889624
201
201
  segments:
202
202
  - 0
203
203
  version: "0"