lib/candy/crunch.rb in candy-0.2.8 vs lib/candy/crunch.rb in candy-0.2.9
- old
+ new
@@ -210,21 +210,78 @@
end
end
end
+ # HERE BEGINNETH THE MODULE PROPER.
+ # (The above were class methods.)
- # We're implementing FindAndModify on Mongo 1.4 until the Ruby driver gets around to being updated...
- def findAndModify(query, update, sort={})
- command = OrderedHash[
- findandmodify: self.collection.name,
- query: query,
- update: update,
- sort: sort
- ]
- result = self.class.db.command(command)
+ # The MongoDB collection object that everything saves to. Defaults to the class's
+ # collection, which in turn defaults to the classname.
+ def collection
+ @__candy_collection ||= self.class.collection
end
+
+ # This is normally set at the class level (with a default of the classname) but you
+ # can override it on a per-object basis if you need to.
+ def collection=(val)
+ @__candy_collection = val
+ end
+
+ ### RETRIEVAL METHODS
+ # Returns the listed fields of the document. If no fields are given, returns the whole document.
+ def retrieve(*fields)
+ options = (fields.empty? ? {} : {fields: fields})
+ from_candy(collection.find_one({'_id' => id}, options)) if id
+ end
+
+
+ # A generic updater that performs the atomic operation specified on a value nested arbitrarily deeply.
+ # Operates in "unsafe" mode, meaning that no document errors will be returned and results are not
+ # guaranteed. The benefit is that it's very, very fast. Always returns true.
+ def operate!(operator, fields)
+ operate operator, fields, {safe: false} and true
+ end
+
+ # A generic updater that performs the atomic operation specified on a value nested arbitrarily deeply.
+ #
+ def operate(operator, fields, options={safe: true})
+ if @__candy_parent
+ @__candy_parent.operate operator, embedded(fields), options
+ else
+ @__candy_id = collection.insert({}) unless id # Ensure we have something to update
+ collection.update({'_id' => id}, {"$#{operator}" => Wrapper.wrap(fields)}, options)
+ end
+ end
+ # Given a hash of property/value pairs, sets those values in Mongo using the atomic $set if
+ # we have a document ID. Otherwise inserts them and sets the object's ID. Operates in
+ # 'unsafe' mode, so database exceptions are not reported but updates are very fast.
+ def set!(fields)
+ operate! :set, fields
+ end
+
+ # Given a hash of property/value pairs, sets those values in Mongo using the atomic $set if
+ # we have a document ID. Otherwise inserts them and sets the object's ID. Returns the
+ # values passed to it.
+ def set(fields)
+ operate :set, fields
+ fields
+ end
+
+ # Increments the specified field by the specified amount (defaults to 1). Does not return the
+ # new value or any document errors.
+ def inc!(field, value=1)
+ operate! :inc, field: value
+ end
+
+ # Increments the specified field by the specified amount (defaults to 1) and returns the
+ # new value.
+ def inc(field, value=1)
+ operate :inc, field => value
+ retrieve(field)[field]
+ end
+
def self.included(receiver)
receiver.extend ClassMethods
end
\ No newline at end of file