candy 0.2.9 → 0.2.10

Sign up to get free protection for your applications and to get access to all the features.
@@ -3,6 +3,16 @@ 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.10 - 2010-06-10 (the "This is not my beautiful hash" release)
7
+ ------------------------------------------------------------------
8
+ Made arrays enumerable finally (thanks to dominikh with issue #13) and added some vital hash methods to Piece that I needed.
9
+
10
+ **NOTE:** I've been slow on updates the past few weeks. It's because I got a crazy new idea on how to interface with the Mongo parts (the "Candy::Crunch" part of this gem) and I've been spending my free dev time playing with that. It might take a bit longer, but if I can get it to work, the non-driver parts of Candy will be both simpler and more incredible. Ping me if you want to know more about what I'm babbling about.
11
+
12
+ * Fixed Github issue #13
13
+ * Added Piece#keys and Piece#values
14
+
15
+
6
16
  v0.2.9 - 2010-05-14 (the "+1" release)
7
17
  --------------------------------------
8
18
  Moved methods around again, placing more of the database update methods into Candy::Crunch. Also began support for two flavors of
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.9
1
+ 0.2.10
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{candy}
8
- s.version = "0.2.9"
8
+ s.version = "0.2.10"
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-14}
12
+ s.date = %q{2010-06-10}
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
@@ -33,6 +33,7 @@ method calls like 'save' and 'find.'
33
33
  "lib/candy/array.rb",
34
34
  "lib/candy/collection.rb",
35
35
  "lib/candy/crunch.rb",
36
+ "lib/candy/crunch/document.rb",
36
37
  "lib/candy/embeddable.rb",
37
38
  "lib/candy/exceptions.rb",
38
39
  "lib/candy/factory.rb",
@@ -56,7 +57,7 @@ method calls like 'save' and 'find.'
56
57
  s.homepage = %q{http://github.com/SFEley/candy}
57
58
  s.rdoc_options = ["--charset=UTF-8"]
58
59
  s.require_paths = ["lib"]
59
- s.rubygems_version = %q{1.3.6}
60
+ s.rubygems_version = %q{1.3.7}
60
61
  s.summary = %q{Transparent persistence for MongoDB}
61
62
  s.test_files = [
62
63
  "spec/candy/array_spec.rb",
@@ -75,7 +76,7 @@ method calls like 'save' and 'find.'
75
76
  current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
76
77
  s.specification_version = 3
77
78
 
78
- if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
79
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
79
80
  s.add_runtime_dependency(%q<bson>, [">= 0.20.1"])
80
81
  s.add_runtime_dependency(%q<bson_ext>, [">= 0.20.1"])
81
82
  s.add_runtime_dependency(%q<mongo>, [">= 0.20.1"])
@@ -9,6 +9,7 @@ module Candy
9
9
  class CandyArray
10
10
  include Crunch
11
11
  include Embeddable
12
+ include Enumerable
12
13
 
13
14
  # Creates the object with parent and attribute values set properly on the object and any children.
14
15
  def self.embed(parent, attribute, *args)
@@ -36,6 +37,11 @@ module Candy
36
37
  candy[index]
37
38
  end
38
39
 
40
+ # Iterates over each value in turn, so that we can have proper Enumerable support
41
+ def each(&block)
42
+ candy.each(&block)
43
+ end
44
+
39
45
  # Appends a value to our array.
40
46
  def <<(val)
41
47
  property = candy_coat(@__candy_parent_key, val)
@@ -96,6 +96,8 @@ module Candy
96
96
 
97
97
  # All of the hard crunchy bits that connect us to a collection within a Mongo database.
98
98
  module Crunch
99
+ autoload :Document, 'candy/crunch/document'
100
+
99
101
  module ClassMethods
100
102
 
101
103
  # Returns the connection you gave, or uses the application-level Candy collection.
@@ -227,59 +229,6 @@ module Candy
227
229
  @__candy_collection = val
228
230
  end
229
231
 
230
- ### RETRIEVAL METHODS
231
- # Returns the listed fields of the document. If no fields are given, returns the whole document.
232
- def retrieve(*fields)
233
- options = (fields.empty? ? {} : {fields: fields})
234
- from_candy(collection.find_one({'_id' => id}, options)) if id
235
- end
236
-
237
-
238
- # A generic updater that performs the atomic operation specified on a value nested arbitrarily deeply.
239
- # Operates in "unsafe" mode, meaning that no document errors will be returned and results are not
240
- # guaranteed. The benefit is that it's very, very fast. Always returns true.
241
- def operate!(operator, fields)
242
- operate operator, fields, {safe: false} and true
243
- end
244
-
245
- # A generic updater that performs the atomic operation specified on a value nested arbitrarily deeply.
246
- #
247
- def operate(operator, fields, options={safe: true})
248
- if @__candy_parent
249
- @__candy_parent.operate operator, embedded(fields), options
250
- else
251
- @__candy_id = collection.insert({}) unless id # Ensure we have something to update
252
- collection.update({'_id' => id}, {"$#{operator}" => Wrapper.wrap(fields)}, options)
253
- end
254
- end
255
-
256
- # Given a hash of property/value pairs, sets those values in Mongo using the atomic $set if
257
- # we have a document ID. Otherwise inserts them and sets the object's ID. Operates in
258
- # 'unsafe' mode, so database exceptions are not reported but updates are very fast.
259
- def set!(fields)
260
- operate! :set, fields
261
- end
262
-
263
- # Given a hash of property/value pairs, sets those values in Mongo using the atomic $set if
264
- # we have a document ID. Otherwise inserts them and sets the object's ID. Returns the
265
- # values passed to it.
266
- def set(fields)
267
- operate :set, fields
268
- fields
269
- end
270
-
271
- # Increments the specified field by the specified amount (defaults to 1). Does not return the
272
- # new value or any document errors.
273
- def inc!(field, value=1)
274
- operate! :inc, field: value
275
- end
276
-
277
- # Increments the specified field by the specified amount (defaults to 1) and returns the
278
- # new value.
279
- def inc(field, value=1)
280
- operate :inc, field => value
281
- retrieve(field)[field]
282
- end
283
232
 
284
233
 
285
234
  def self.included(receiver)
@@ -0,0 +1,62 @@
1
+ module Candy
2
+ module Crunch
3
+
4
+ # MongoDB interface methods specific to the handling of individual documents (as opposed to collections or cursors).
5
+ module Document
6
+ ### RETRIEVAL METHODS
7
+ # Returns the listed fields of the document. If no fields are given, returns the whole document.
8
+ def retrieve(*fields)
9
+ options = (fields.empty? ? {} : {fields: fields})
10
+ from_candy(collection.find_one({'_id' => id}, options)) if id
11
+ end
12
+
13
+
14
+ # A generic updater that performs the atomic operation specified on a value nested arbitrarily deeply.
15
+ # Operates in "unsafe" mode, meaning that no document errors will be returned and results are not
16
+ # guaranteed. The benefit is that it's very, very fast. Always returns true.
17
+ def operate!(operator, fields)
18
+ operate operator, fields, {safe: false} and true
19
+ end
20
+
21
+ # A generic updater that performs the atomic operation specified on a value nested arbitrarily deeply.
22
+ #
23
+ def operate(operator, fields, options={safe: true})
24
+ if @__candy_parent
25
+ @__candy_parent.operate operator, embedded(fields), options
26
+ else
27
+ @__candy_id = collection.insert({}) unless id # Ensure we have something to update
28
+ collection.update({'_id' => id}, {"$#{operator}" => Wrapper.wrap(fields)}, options)
29
+ end
30
+ end
31
+
32
+ # Given a hash of property/value pairs, sets those values in Mongo using the atomic $set if
33
+ # we have a document ID. Otherwise inserts them and sets the object's ID. Operates in
34
+ # 'unsafe' mode, so database exceptions are not reported but updates are very fast.
35
+ def set!(fields)
36
+ operate! :set, fields
37
+ end
38
+
39
+ # Given a hash of property/value pairs, sets those values in Mongo using the atomic $set if
40
+ # we have a document ID. Otherwise inserts them and sets the object's ID. Returns the
41
+ # values passed to it.
42
+ def set(fields)
43
+ operate :set, fields
44
+ fields
45
+ end
46
+
47
+ # Increments the specified field by the specified amount (defaults to 1). Does not return the
48
+ # new value or any document errors.
49
+ def inc!(field, value=1)
50
+ operate! :inc, field: value
51
+ end
52
+
53
+ # Increments the specified field by the specified amount (defaults to 1) and returns the
54
+ # new value.
55
+ def inc(field, value=1)
56
+ operate :inc, field => value
57
+ retrieve(field)[field]
58
+ end
59
+
60
+ end
61
+ end
62
+ end
@@ -2,7 +2,7 @@ require 'candy/piece'
2
2
 
3
3
  module Candy
4
4
 
5
- # A subclass of Hash that behaves like a Candy::Piece. This class has two major uses:
5
+ # An untyped hash that behaves like a Candy::Piece. This class has two major uses:
6
6
  #
7
7
  # * It's a convenient starting point if you just want to store a bunch of data in Mongo
8
8
  # and don't need to implement any business logic in your own classes; and
@@ -13,13 +13,12 @@ module Candy
13
13
  # If you don't tell them otherwise, top-level CandyHash objects store themselves in
14
14
  # the 'candy' collection. You can change that at any time by setting a different
15
15
  # collection at the class or object level.
16
- class CandyHash < Hash
16
+ class CandyHash
17
17
  include Crunch
18
18
  include Piece
19
19
 
20
20
  self.collection = 'candy'
21
21
 
22
-
23
22
  # Overrides the default behavior in Candy::Piece so that we DO NOT add our
24
23
  # class name to the saved values.
25
24
  def to_candy
@@ -78,6 +78,7 @@ module Candy
78
78
 
79
79
  # HERE STARTETH THE MODULE PROPER. (The above are the class methods.)
80
80
  include Crunch
81
+ include Crunch::Document
81
82
  include Embeddable
82
83
 
83
84
 
@@ -148,6 +149,15 @@ module Candy
148
149
  self
149
150
  end
150
151
 
152
+ # Returns the keys we've stored.
153
+ def keys
154
+ candy.keys
155
+ end
156
+
157
+ # Returns the values we've stored.
158
+ def values
159
+ candy.values
160
+ end
151
161
 
152
162
  # Convenience method for debugging. Shows the class, the Mongo ID, and the saved state hash.
153
163
  def to_s
@@ -51,6 +51,14 @@ describe Candy::CandyArray do
51
51
  @this.bits[3].should == 'schadenfreude'
52
52
  end
53
53
 
54
+ it "is enumerable" do
55
+ @this.bits.map{|b| b.upcase}.should == ['PEANUT', 'ALMONDS', 'TITANIUM']
56
+ end
57
+
58
+ it "is sortable" do
59
+ @this.bits.sort.should == ['almonds', 'peanut', 'titanium']
60
+ end
61
+
54
62
  after(:each) do
55
63
  Zagnut.collection.remove
56
64
  end
@@ -17,7 +17,11 @@ describe Candy::CandyHash do
17
17
  it "reads the hash" do
18
18
  that = Zagnut(@this.id)
19
19
  that.filling.taste.should == 'caramel'
20
- that.filling.should be_a(Hash)
20
+ end
21
+
22
+ it "reads the hash with brackets" do
23
+ that = Zagnut(@this.id)
24
+ that[:filling][:taste].should == 'caramel'
21
25
  end
22
26
 
23
27
  it "cascades changes" do
@@ -229,6 +229,16 @@ describe Candy::Piece do
229
229
  @verifier.find_one(ounces: 12)["crunchy"].should == :very
230
230
  end
231
231
 
232
+
233
+ it "knows its keys" do
234
+ @this.keys.should == [:ounces, :crunchy]
235
+ end
236
+
237
+ it "knows its values" do
238
+ @this.values.should == [17, :very]
239
+ end
240
+
241
+
232
242
  end
233
243
 
234
244
  describe "embedding" do
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: candy
3
3
  version: !ruby/object:Gem::Version
4
+ hash: 3
4
5
  prerelease: false
5
6
  segments:
6
7
  - 0
7
8
  - 2
8
- - 9
9
- version: 0.2.9
9
+ - 10
10
+ version: 0.2.10
10
11
  platform: ruby
11
12
  authors:
12
13
  - Stephen Eley
@@ -14,16 +15,18 @@ autorequire:
14
15
  bindir: bin
15
16
  cert_chain: []
16
17
 
17
- date: 2010-05-14 00:00:00 -04:00
18
+ date: 2010-06-10 00:00:00 -04:00
18
19
  default_executable:
19
20
  dependencies:
20
21
  - !ruby/object:Gem::Dependency
21
22
  name: bson
22
23
  prerelease: false
23
24
  requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
24
26
  requirements:
25
27
  - - ">="
26
28
  - !ruby/object:Gem::Version
29
+ hash: 77
27
30
  segments:
28
31
  - 0
29
32
  - 20
@@ -35,9 +38,11 @@ dependencies:
35
38
  name: bson_ext
36
39
  prerelease: false
37
40
  requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
38
42
  requirements:
39
43
  - - ">="
40
44
  - !ruby/object:Gem::Version
45
+ hash: 77
41
46
  segments:
42
47
  - 0
43
48
  - 20
@@ -49,9 +54,11 @@ dependencies:
49
54
  name: mongo
50
55
  prerelease: false
51
56
  requirement: &id003 !ruby/object:Gem::Requirement
57
+ none: false
52
58
  requirements:
53
59
  - - ">="
54
60
  - !ruby/object:Gem::Version
61
+ hash: 77
55
62
  segments:
56
63
  - 0
57
64
  - 20
@@ -63,9 +70,11 @@ dependencies:
63
70
  name: rspec
64
71
  prerelease: false
65
72
  requirement: &id004 !ruby/object:Gem::Requirement
73
+ none: false
66
74
  requirements:
67
75
  - - ">="
68
76
  - !ruby/object:Gem::Version
77
+ hash: 13
69
78
  segments:
70
79
  - 1
71
80
  - 2
@@ -77,9 +86,11 @@ dependencies:
77
86
  name: mocha
78
87
  prerelease: false
79
88
  requirement: &id005 !ruby/object:Gem::Requirement
89
+ none: false
80
90
  requirements:
81
91
  - - ">="
82
92
  - !ruby/object:Gem::Version
93
+ hash: 43
83
94
  segments:
84
95
  - 0
85
96
  - 9
@@ -114,6 +125,7 @@ files:
114
125
  - lib/candy/array.rb
115
126
  - lib/candy/collection.rb
116
127
  - lib/candy/crunch.rb
128
+ - lib/candy/crunch/document.rb
117
129
  - lib/candy/embeddable.rb
118
130
  - lib/candy/exceptions.rb
119
131
  - lib/candy/factory.rb
@@ -143,23 +155,27 @@ rdoc_options:
143
155
  require_paths:
144
156
  - lib
145
157
  required_ruby_version: !ruby/object:Gem::Requirement
158
+ none: false
146
159
  requirements:
147
160
  - - ">="
148
161
  - !ruby/object:Gem::Version
162
+ hash: 3
149
163
  segments:
150
164
  - 0
151
165
  version: "0"
152
166
  required_rubygems_version: !ruby/object:Gem::Requirement
167
+ none: false
153
168
  requirements:
154
169
  - - ">="
155
170
  - !ruby/object:Gem::Version
171
+ hash: 3
156
172
  segments:
157
173
  - 0
158
174
  version: "0"
159
175
  requirements: []
160
176
 
161
177
  rubyforge_project:
162
- rubygems_version: 1.3.6
178
+ rubygems_version: 1.3.7
163
179
  signing_key:
164
180
  specification_version: 3
165
181
  summary: Transparent persistence for MongoDB