candy 0.2.9 → 0.2.10
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/HISTORY.markdown +10 -0
- data/VERSION +1 -1
- data/candy.gemspec +5 -4
- data/lib/candy/array.rb +6 -0
- data/lib/candy/crunch.rb +2 -53
- data/lib/candy/crunch/document.rb +62 -0
- data/lib/candy/hash.rb +2 -3
- data/lib/candy/piece.rb +10 -0
- data/spec/candy/array_spec.rb +8 -0
- data/spec/candy/hash_spec.rb +5 -1
- data/spec/candy/piece_spec.rb +10 -0
- metadata +20 -4
data/HISTORY.markdown
CHANGED
@@ -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.
|
1
|
+
0.2.10
|
data/candy.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{candy}
|
8
|
-
s.version = "0.2.
|
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-
|
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.
|
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::
|
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"])
|
data/lib/candy/array.rb
CHANGED
@@ -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)
|
data/lib/candy/crunch.rb
CHANGED
@@ -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
|
data/lib/candy/hash.rb
CHANGED
@@ -2,7 +2,7 @@ require 'candy/piece'
|
|
2
2
|
|
3
3
|
module Candy
|
4
4
|
|
5
|
-
#
|
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
|
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
|
data/lib/candy/piece.rb
CHANGED
@@ -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
|
data/spec/candy/array_spec.rb
CHANGED
@@ -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
|
data/spec/candy/hash_spec.rb
CHANGED
@@ -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
|
-
|
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
|
data/spec/candy/piece_spec.rb
CHANGED
@@ -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
|
-
version: 0.2.
|
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-
|
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.
|
178
|
+
rubygems_version: 1.3.7
|
163
179
|
signing_key:
|
164
180
|
specification_version: 3
|
165
181
|
summary: Transparent persistence for MongoDB
|