candy 0.2.6 → 0.2.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -3,6 +3,14 @@ Candy History
3
3
 
4
4
  This document aims to provide only an overview. Further, we've only really been tracking things since **v0.2**. For obsessive detail, just check out the `git log`.
5
5
 
6
+ v0.2.7 - 2010-05-05 (the "yes, you MAY put your peanut butter in my chocolate" release)
7
+ --------------------------------------------------------------------------------------
8
+ Found and fixed a convoluted bug that was preventing embedded Candy objects from being saved properly. (It was treating them as _non_-Candy objects, which makes the world a gray and boring place.) While I was at it, refactored some methods and chipped away at some complexity.
9
+
10
+ **MODERATELY BREAKING CHANGE ALERT:** I've renamed the `to_mongo` and `from_mongo` methods to `to_candy` and `from_candy`. The initial reason for the _mongo_ names was for some vague semblance of compatibility with [MongoMapper](http://github.com/jnunemaker/mongomapper), but that doesn't make sense since we're treating serialized Candy objects completely differently and expecting them to unpack themselves. I seriously doubt anyone was using these methods yet, but just in case, now you know.
11
+
12
+ * Fixed embedding bug on Candy objects
13
+
6
14
  v0.2.6 - 2010-05-03 (the "Spanish Fly" release)
7
15
  -----------------------------------------------
8
16
  Thanks to [xpaulbettsx](http://github.com/xpaulbettsx) for pointing out in issue \#4 that Candy was attempting to connect to localhost prematurely.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.6
1
+ 0.2.7
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{candy}
8
- s.version = "0.2.6"
8
+ s.version = "0.2.7"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Stephen Eley"]
12
- s.date = %q{2010-05-03}
12
+ s.date = %q{2010-05-05}
13
13
  s.description = %q{Candy provides simple, transparent object persistence for the MongoDB database. Classes that
14
14
  include Candy modules save all properties to Mongo automatically, can be recursively embedded,
15
15
  and can retrieve records with chainable open-ended class methods, eliminating the need for
@@ -11,13 +11,14 @@ module Candy
11
11
  autoload :Wrapper, 'candy/wrapper'
12
12
  autoload :Piece, 'candy/piece'
13
13
  autoload :Collection, 'candy/collection'
14
+
15
+ # Special keys for Candy metadata in the Mongo store. We try to keep these to a minimum,
16
+ # and we're using moderately obscure Unicode symbols to reduce the odds of collisions.
17
+ # If by some strange happenstance you might have single-character keys in your Mongo
18
+ # collections that use the 'CIRCLED LATIN SMALL LETTER' Unicode set, you may need to
19
+ # change these constants. Just be consistent about it if you want to use embedded
20
+ # documents in Candy.
21
+ CLASS_KEY = 'ⓒ'.to_sym
22
+ EMBED_KEY = 'ⓔ'.to_sym
14
23
  end
15
24
 
16
- # Special keys for Candy metadata in the Mongo store. We try to keep these to a minimum,
17
- # and we're using moderately obscure Unicode symbols to reduce the odds of collisions.
18
- # If by some strange happenstance you might have single-character keys in your Mongo
19
- # collections that use the 'CIRCLED LATIN SMALL LETTER' Unicode set, you may need to
20
- # change these constants. Just be consistent about it if you want to use embedded
21
- # documents in Candy.
22
- CLASS_KEY = 'ⓒ'.to_sym
23
- EMBED_KEY = 'ⓔ'.to_sym
@@ -26,7 +26,7 @@ module Candy
26
26
  # array in Mongo still matches our current state. If concurrent updates have happened, you might end up
27
27
  # overwriting something other than what you thought.
28
28
  def []=(index, val)
29
- property = embeddify(val)
29
+ property = candy_coat(@__candy_parent_key, val)
30
30
  @__candy_parent.set embedded(index => property)
31
31
  self.candy[index] = property
32
32
  end
@@ -38,7 +38,7 @@ module Candy
38
38
 
39
39
  # Appends a value to our array.
40
40
  def <<(val)
41
- property = embeddify(val)
41
+ property = candy_coat(@__candy_parent_key, val)
42
42
  @__candy_parent.operate :push, @__candy_parent_key => property
43
43
  self.candy << property
44
44
  end
@@ -56,7 +56,7 @@ module Candy
56
56
  def candy
57
57
  @__candy ||= []
58
58
  end
59
- alias_method :to_mongo, :candy
59
+ alias_method :to_candy, :candy
60
60
  alias_method :to_ary, :candy
61
61
 
62
62
  # Array equality.
@@ -3,9 +3,9 @@ module Candy
3
3
  # Shared methods to create associations between top-level objects and embedded objects (hashes,
4
4
  # arrays, or Candy::Pieces).
5
5
  module Embeddable
6
- # Tells an embedded object whom it belongs to and what attribute it's associated with. When
7
- # its own state changes, it can use this information to update the parent.
8
- def adopt(parent, attribute)
6
+ # Tells an embedded object about its parent. When its own state changes, it can use this
7
+ # information to write home and update the parent.
8
+ def candy_adopt(parent, attribute)
9
9
  @__candy_parent = parent
10
10
  @__candy_parent_key = attribute
11
11
  end
@@ -18,16 +18,18 @@ module Candy
18
18
  new_fields
19
19
  end
20
20
 
21
- # Convert hashes and arrays to CandyHashes and CandyArrays.
22
- def embeddify(value)
23
- case value
24
- when CandyHash then value
25
- when Hash then CandyHash.embed(value)
26
- when CandyArray then value
27
- when Array then CandyArray.embed(*value) # Explode our array into separate arguments
28
- else
29
- value
30
- end
21
+ # Convert hashes and arrays to CandyHashes and CandyArrays, and set the parent key for any Candy pieces.
22
+ def candy_coat(key, value)
23
+ piece = case value
24
+ when CandyHash then value
25
+ when Hash then CandyHash.embed(value)
26
+ when CandyArray then value
27
+ when Array then CandyArray.embed(*value) # Explode our array into separate arguments
28
+ else
29
+ value
30
+ end
31
+ piece.candy_adopt(self, key) if piece.respond_to?(:candy_adopt)
32
+ piece
31
33
  end
32
34
 
33
35
  end
@@ -22,7 +22,7 @@ module Candy
22
22
 
23
23
  # Overrides the default behavior in Candy::Piece so that we DO NOT add our
24
24
  # class name to the saved values.
25
- def to_mongo
25
+ def to_candy
26
26
  candy
27
27
  end
28
28
 
@@ -79,7 +79,7 @@ module Candy
79
79
  if args[-1].is_a?(Hash)
80
80
  data = args.pop
81
81
  if @__candy_id = data.delete('_id') # We're an existing document
82
- @__candy = self.from_mongo(Wrapper.unwrap(data))
82
+ @__candy = self.from_candy(Wrapper.unwrap(data))
83
83
  elsif data.delete(EMBED_KEY) # We're being embedded: take any data, but don't save to Mongo
84
84
  @__candy = data
85
85
  else
@@ -134,14 +134,9 @@ module Candy
134
134
  # Hash-like setter. Updates the object's internal state, and writes to the database if the state
135
135
  # has changed. Keys should be passed in as symbols for best consistency with the database.
136
136
  def []=(key, value)
137
- property = embeddify(value)
137
+ property = candy_coat(key, value) # Transform hashes and arrays, and communicate embedding
138
138
  candy[key] = property
139
- if property.respond_to?(:to_mongo)
140
- property.adopt(self, key)
141
- set key => property.to_mongo
142
- else
143
- set key => property
144
- end
139
+ set key => property
145
140
  end
146
141
 
147
142
  # Clears memoized data so that the next read pulls from the database.
@@ -170,14 +165,14 @@ module Candy
170
165
 
171
166
  # Converts the object into a hash for MongoDB storage. Keep in mind that wrapping happens _after_
172
167
  # this stage, so it's best to use symbols for keys and leave internal arrays and hashes alone.
173
- def to_mongo
168
+ def to_candy
174
169
  candy.merge(CLASS_KEY => self.class.name)
175
170
  end
176
171
 
177
172
  # A hoook for specific object classes to set their internal state using the hash passed in by
178
173
  # MongoDB. If you override this method, delete any hash keys you need for your own purposes
179
174
  # and then call 'super' on the remainder.
180
- def from_mongo(hash)
175
+ def from_candy(hash)
181
176
  hash
182
177
  end
183
178
 
@@ -27,6 +27,7 @@ module Candy
27
27
  def self.wrap(thing)
28
28
  # Pass the simple cases through
29
29
  return thing if BSON_SAFE.include?(thing.class)
30
+ thing = thing.to_candy if thing.respond_to?(:to_candy) # Make it sweeter if it can be sweetened
30
31
  case thing
31
32
  when Array
32
33
  wrap_array(thing)
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 2
8
- - 6
9
- version: 0.2.6
8
+ - 7
9
+ version: 0.2.7
10
10
  platform: ruby
11
11
  authors:
12
12
  - Stephen Eley
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-05-03 00:00:00 -04:00
17
+ date: 2010-05-05 00:00:00 -04:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency