Browse files

Update the changelog, updated the YARD docs to represent that Request…

…Response(s) will be returned instead of real values where applicable, added a backwards compatibility file (prev.rb) as well as an example of using that file to revert to the previous API
  • Loading branch information...
1 parent dffe290 commit 6e1956595b3152c90a6104284e8db7946edff8c7 @PlasticLizard PlasticLizard committed Jul 13, 2011
Showing with 140 additions and 41 deletions.
  1. +9 −0 CHANGELOG
  2. +2 −0 README.rdoc
  3. +38 −0 examples/legacy.rb
  4. +1 −0 examples/readme.rb
  5. +15 −15 lib/em-mongo/collection.rb
  6. +12 −7 lib/em-mongo/cursor.rb
  7. +13 −13 lib/em-mongo/database.rb
  8. +50 −6 lib/em-mongo/prev.rb
View
9 CHANGELOG
@@ -1,3 +1,12 @@
+- 0.4.0?
+
+ * added a Cursor implementation
+ * replaced raw callbacks in the API with deferrables
+ * removed CRUD methods from the Connection
+ * added a variety of server side aggregation commands
+ * added support for indexes
+ * added safe update methods
+
- 0.3.6
* dj2: fixes reconnects. (see: https://github.com/bcg/em-mongo/pull/23)
View
2 README.rdoc
@@ -116,6 +116,8 @@ em-mongo has the following safe methods:
In addition to calling your errback if the write fails, you can provide the usual 'safety' options that you can to Database#get_last_error, such as :fsync => true or :w => 2, to control the degree of safety you want. Please the 10gen documentation on DB#get_last_error for specifics.
+ safe_insert( {:a=>"v"}, :last_error_params => { :fsync => true, :w => 5 } )
+
== Upgrading
View
38 examples/legacy.rb
@@ -0,0 +1,38 @@
+#bundle exec ruby examples/legacy.rb
+require 'em-mongo'
+require 'em-mongo/prev.rb'
+
+require 'eventmachine'
+
+EM.run do
+ conn = EM::Mongo::Connection.new('localhost')
+ db = conn.db('my_database')
+ collection = db.collection('my_collection')
+ EM.next_tick do
+
+ (1..10).each do |i|
+ conn.insert('my_database.my_collection', { :revolution => i } )
+ end
+
+ conn.update('my_database.my_collection', {:revolution => 9}, {:revolution => 8.5})
+
+ conn.delete('my_database.my_collection', {:revolution => 1})
+
+ collection.find do |documents|
+ puts "I just got #{documents.length} documents! I'm really cool!"
+ end
+
+ #iterate though each result in a query
+ collection.find( {:revolution => { "$gt" => 5 }}, :limit =>1, :skip => 1, :order => [:revolution, -1]) do |docs|
+ docs.each do |doc|
+ puts "Revolution ##{doc['revolution']}"
+ end
+ end
+
+ collection.drop
+
+ EM.add_periodic_timer(1) { EM.stop }
+
+ end
+
+end
View
1 examples/readme.rb
@@ -1,3 +1,4 @@
+#bundle exec ruby examples/readme.rb
require 'em-mongo'
require 'eventmachine'
View
30 lib/em-mongo/collection.rb
@@ -140,8 +140,8 @@ def find(selector={}, opts={})
# Return a single object from the database.
#
- # @return [OrderedHash, Nil]
- # a single document or nil if no result is found.
+ # @return [EM::Mongo::RequestResponse]
+ # calls back with a single document or nil if no result is found.
#
# @param [Hash, ObjectId, Nil] spec_or_object_id a hash specifying elements
# which must be present for a document to be included in the result set or an
@@ -190,8 +190,8 @@ def insert(doc_or_docs)
# @param [Hash, Array] doc_or_docs
# a document (as a hash) or array of documents to be inserted.
#
- # @return [ObjectId, Array]
- # The _id of the inserted document or a list of _ids of all inserted documents.
+ # @return [EM::Mongo::RequestResponse]
+ # Calls backw ith the _id of the inserted document or a list of _ids of all inserted documents.
#
# @option opts [Boolean, Hash] :safe (+true+)
# run the operation in safe mode, which run a getlasterror command on the
@@ -250,8 +250,8 @@ def update(selector, document, opts={})
# the update command currently updates only the first document matching the
# given selector. If you want all matching documents to be updated, be sure
# to specify :multi => true.
- # @param [Hash] document
- # a hash specifying the fields to be changed in the selected document,
+ # @param [EM::Mongo::RequestResponse] document
+ # calls back with a hash specifying the fields to be changed in the selected document,
# or (in the case of an upsert) the document to be inserted
#
# @option opts [Boolean] :upsert (+false+) if true, performs an upsert (update or insert)
@@ -313,7 +313,7 @@ def save(doc, opts={})
# then an update (upsert) operation will be performed, and any existing
# document with that _id is overwritten. Otherwise an insert operation is performed.
#
- # @return [ObjectId] the _id of the saved document.
+ # @return [EM::Mongo::RequestResponse] Calls backw with the _id of the saved document.
#
# @option opts [Boolean, Hash] :safe (+true+)
# run the operation in safe mode, which run a getlasterror command on the
@@ -382,7 +382,7 @@ def drop
# @option opts [Boolean] :new (false) If true, returns the updated document; otherwise, returns the document
# prior to update.
#
- # @return [Hash] the matched document.
+ # @return [EM::Mongo::RequestResponse] Calls back with the matched document.
#
# @core findandmodify find_and_modify-instance_method
def find_and_modify(opts={})
@@ -425,7 +425,7 @@ def find_and_modify(opts={})
# map-reduce output (as, for example, when using :out => {:inline => 1}), then you must specify this option
# or an ArgumentError will be raised.
#
- # @return [Collection, Hash] a Mongo::Collection object or a Hash with the map-reduce command's results.
+ # @return [EM::Mongo::RequestResponse] Calls back with a EM::Mongo::Collection object or a Hash with the map-reduce command's results.
#
# @raise ArgumentError if you specify {:out => {:inline => true}} but don't specify :raw => true.
#
@@ -488,7 +488,7 @@ def map_reduce(map, reduce, opts={})
# @collection.distinct("name.age", {"name.age" => {"$gt" => 24}})
# [27]
#
- # @return [Array] an array of distinct values.
+ # @return [EM::Mongo::RequestResponse] Calls back with an array of distinct values.
def distinct(key, query=nil)
raise MongoArgumentError unless [String, Symbol].include?(key.class)
response = RequestResponse.new
@@ -522,7 +522,7 @@ def distinct(key, query=nil)
# each of the resultant grouped objects. Available only when group is run with command
# set to true.
#
- # @return [Array] the command response consisting of grouped items.
+ # @return [EM::Mongo::RequestResponse] calls back with the command response consisting of grouped items.
def group(opts={})
response = RequestResponse.new
reduce = opts[:reduce]
@@ -571,22 +571,22 @@ def group(opts={})
# Get the number of documents in this collection.
#
- # @return [Integer]
+ # @return [EM::Mongo::RequestResponse]
def count
find().count
end
alias :size :count
# Return stats on the collection. Uses MongoDB's collstats command.
#
- # @return [Hash]
+ # @return [EM::Mongo::RequestResponse]
def stats
@db.command({:collstats => @name})
end
# Get information on the indexes for this collection.
#
- # @return [Hash] a hash where the keys are index names.
+ # @return [EM::Mongo::RequestResponse] Calls back with a hash where the keys are index names.
#
# @core indexes
def index_information
@@ -647,7 +647,7 @@ def create_index(spec, opts={})
# Drop a specified index.
#
- # @param [String] name
+ # @param [EM::Mongo::RequestResponse] name
#
# @core indexes
def drop_index(name)
View
19 lib/em-mongo/cursor.rb
@@ -82,7 +82,7 @@ def initialize(collection, opts={})
# Get the next document specified the cursor options.
#
- # @return [Hash, Nil] the next document or Nil if no documents remain.
+ # @return [EM::Mongo::RequestResponse] Calls back with the next document or Nil if no documents remain.
def next_document
response = RequestResponse.new
if @cache.length == 0
@@ -134,7 +134,7 @@ def rewind!
# Determine whether this cursor has any remaining results.
#
- # @return [Boolean]
+ # @return [EM::Mongo::RequestResponse]
def has_next?
response = RequestResponse.new
num_resp = num_remaining
@@ -147,7 +147,7 @@ def has_next?
#
# @param [Boolean] whether of not to take notice of skip and limit
#
- # @return [Integer] the number of objects in the result set for this query.
+ # @return [EM::Mongo::RequestResponse] Calls back with the number of objects in the result set for this query.
#
# @raise [OperationFailure] on a database error.
def count(skip_and_limit = false)
@@ -260,11 +260,14 @@ def batch_size(size=0)
#
# Iterating over an entire cursor will close it.
#
- # @yield passes each document to a block for processing.
+ # @yield passes each document to a block for processing. When the cursor is empty,
+ # each will yield a nil value
#
# @example if 'comments' represents a collection of comments:
# comments.find.each do |doc|
- # puts doc['user']
+ # if doc
+ # puts doc['user']
+ # end
# end
def each(&blk)
raise "A callback block is required for #each" unless blk
@@ -295,7 +298,7 @@ def each(&blk)
# Use of this method is discouraged - in most cases, it's much more
# efficient to retrieve documents as you need them by iterating over the cursor.
#
- # @return [Array] an array of documents.
+ # @return [EM::Mongo::RequestResponse] Calls back with an array of documents.
def to_a
response = RequestResponse.new
items = []
@@ -313,7 +316,7 @@ def to_a
# Get the explain plan for this cursor.
#
- # @return [Hash] a document containing the explain plan for this cursor.
+ # @return [EM::Mongo::RequestResponse] Calls back with a document containing the explain plan for this cursor.
#
# @core explain explain-instance_method
def explain
@@ -351,6 +354,7 @@ def close
message.put_long(@cursor_id)
@connection.send_command(EM::Mongo::OP_KILL_CURSORS, message)
end
+ true
end
# Is this cursor closed?
@@ -413,6 +417,7 @@ def convert_fields_for_query(fields)
end
# Return the number of documents remaining for this cursor.
+ # @return [EM::Mongo::RequestResponse]
def num_remaining
response = RequestResponse.new
if @cache.length == 0
View
26 lib/em-mongo/database.rb
@@ -49,7 +49,7 @@ def name
# Get an array of collection names in this database.
#
- # @return [Array]
+ # @return [EM::Mongo::RequestResponse]
def collection_names
response = RequestResponse.new
name_resp = collections_info.to_a
@@ -65,7 +65,7 @@ def collection_names
# Get an array of Collection instances, one for each collection in this database.
#
- # @return [Array<EM::Mongo::Collection>]
+ # @return [EM::Mongo::RequestResponse]
def collections
response = RequestResponse.new
name_resp = collection_names
@@ -112,7 +112,7 @@ def collections_info(coll_name=nil)
# either we're in +strict+ mode and the collection
# already exists or collection creation fails on the server.
#
- # @return [EM::Mongo::Collection]
+ # @return [EM::Mongo::RequestResponse] Calls back with the new collection
def create_collection(name)
response = RequestResponse.new
names_resp = collection_names
@@ -142,7 +142,7 @@ def create_collection(name)
#
# @param [String, Symbol] name
#
- # @return [Boolean] +true+ on success or +false+ if the collection name doesn't exist.
+ # @return [EM::Mongo::RequestResponse] Calls back with +true+ on success or +false+ if the collection name doesn't exist.
def drop_collection(name)
response = RequestResponse.new
names_resp = collection_names
@@ -154,7 +154,7 @@ def drop_collection(name)
end
cmd_resp.errback { |err| response.fail err }
else
- response.succeed true
+ response.succeed false
end
end
names_resp.errback { |err| response.fail err }
@@ -167,7 +167,7 @@ def drop_collection(name)
# @param [String] collection_name
# @param [String] index_name
#
- # @return [True] returns +true+ on success.
+ # @return [EM::Mongo::RequestResponse] returns +true+ on success.
#
# @raise MongoDBError if there's an error renaming the collection.
def drop_index(collection_name, index_name)
@@ -194,7 +194,7 @@ def drop_index(collection_name, index_name)
#
# @param [String] collection_name
#
- # @return [Hash] keys are index names and the values are lists of [key, direction] pairs
+ # @return [EM::Mongo::RequestResponse] Calls back with a hash where keys are index names and the values are lists of [key, direction] pairs
# defining the index.
def index_information(collection_name)
response = RequestResponse.new
@@ -219,7 +219,7 @@ def index_information(collection_name)
# @option opts [Integer] :w (nil)
# @option opts [Integer] :wtimeout (nil)
#
- # @return [Hash] the entire response to getlasterror.
+ # @return [EM::Mongo::RequestResponse] the entire response to getlasterror.
#
# @raise [MongoDBError] if the operation fails.
def get_last_error(opts={})
@@ -242,7 +242,7 @@ def get_last_error(opts={})
# Return +true+ if an error was caused by the most recently executed
# database operation.
#
- # @return [Boolean]
+ # @return [EM::Mongo::RequestResponse]
def error?
response = RequestResponse.new
err_resp = get_last_error
@@ -260,7 +260,7 @@ def error?
# Calls to DB#previous_error will only return errors that have occurred
# since the most recent call to this method.
#
- # @return [Hash]
+ # @return [EM::Mongo::RequestResponse]
def reset_error_history
command(:reseterror => 1)
end
@@ -294,7 +294,7 @@ def full_collection_name(collection_name)
# command fails.
# @option opts [Socket] :socket a socket to use for sending the command. This is mainly for internal use.
#
- # @return [EM::Deferrable]
+ # @return [EM::Mongo::RequestResponse] Calls back with a hash representing the result of the command
#
# @core commands command_instance-method
def command(selector, opts={})
@@ -331,7 +331,7 @@ def command(selector, opts={})
# @param [String] username
# @param [String] password
#
- # @return [Boolean]
+ # @return [EM::Mongo::RequestResponse] Calls back with +true+ or +false+, indicating success or failure
#
# @raise [AuthenticationError]
#
@@ -370,7 +370,7 @@ def authenticate(username, password)
# @param [String] username
# @param [String] password
#
- # @return [Hash] an object representing the user.
+ # @return [EM::Mongo::RequestResponse] Calls back with an object representing the user.
def add_user(username, password)
response = RequestResponse.new
user_resp = self.collection(SYSTEM_USER_COLLECTION).first({:user => username})
View
56 lib/em-mongo/prev.rb
@@ -1,9 +1,53 @@
module EM
- module Mongo
- class Collection
- end
+ module Mongo
+ class Collection
- class Connection
- end
- end
+ alias :new_find :find
+ def find(selector={}, opts={}, &blk)
+ raise "find requires a block" if not block_given?
+
+ new_find(selector, opts).to_a.callback do |docs|
+ blk.call(docs)
+ end
+ end
+
+ def first(selector={}, opts={}, &blk)
+ opts[:limit] = 1
+ find(selector, opts) do |res|
+ yield res.first
+ end
+ end
+ end
+
+ class Connection
+
+ def insert(collection_name, documents)
+ db_name, col_name = db_and_col_name(collection_name)
+ db(db_name).collection(col_name).insert(documents)
+ end
+
+ def update(collection_name, selector, document, options={})
+ db_name, col_name = db_and_col_name(collection_name)
+ db(db_name).collection(col_name).update(selector, document, options)
+ end
+
+ def delete(collection_name, selector)
+ db_name, col_name = db_and_col_name(collection_name)
+ db(db_name).collection(col_name).remove(selector)
+ end
+
+ def find(collection_name, skip, limit, order, query, fields, &blk)
+ db_name, col_name = db_and_col_name(collection_name)
+ db(db_name).collection(col_name).find(query, :skip=>skip,:limit=>limit,:order=>order,:fields=>fields).to_a.callback do |docs|
+ yield docs if block_given?
+ end
+ end
+
+ def db_and_col_name(full_name)
+ parts = full_name.split(".")
+ [ parts.shift, parts.join(".") ]
+ end
+
+ end
+ end
end

0 comments on commit 6e19565

Please sign in to comment.