diff --git a/README.rdoc b/README.rdoc index 87458d7..d7424b5 100644 --- a/README.rdoc +++ b/README.rdoc @@ -56,7 +56,7 @@ That's all there is to it! For extensive examples, see the MongoDB Ruby Tutorial (http://www.mongodb.org/display/DOCS/Ruby+Tutorial). -Bundled with the dirver are many examples in the "examples" subdirectory. Samples include using +Bundled with the driver are many examples, located in the "examples" subdirectory. Samples include using the driver and using the GridFS class GridStore. MongoDB must be running for these examples to work, of course. @@ -90,7 +90,7 @@ Example code: end # Output "Hello, world!" - GridStore.open(database, 'filename, 'r') do |f| + GridStore.open(database, 'filename', 'r') do |f| puts f.read end @@ -100,7 +100,7 @@ Example code: end # Retrieve everything, outputting "Hello, world!\nBut wait, there's more!\n" - GridStore.open(database, 'filename, 'r') do |f| + GridStore.open(database, 'filename', 'r') do |f| puts f.read end @@ -128,7 +128,7 @@ A pooled connection to a paired instance would look like this: :right => ["db2.example.com", 27017]}, nil, :pool_size => 20, :timeout => 5) -Though the pooling architecure will undoubtedly evolve, it currently owes much credit +Though the pooling architecture will undoubtedly evolve, it currently owes much credit to the connection pooling implementations in ActiveRecord and PyMongo. == Using with Phusion Passenger @@ -191,8 +191,8 @@ hash and return a hash which merges the original hash with any primary key fields the factory wishes to inject. NOTE: if the object already has a primary key, the factory should not inject -a new key; this means that the object is being used in a repsert but it already -exists. The idea here is that whenever a record is inserted, +a new key; this means that the object may already exist in the database. +The idea here is that whenever a record is inserted, the :pk_factory object's +create_pk+ method will be called and the new hash returned will be inserted. @@ -277,7 +277,7 @@ These will run both unit and functional tests. To run these tests alone: $ rake test:unit $ rake test:functional -To run any individual rake tasks with the C extenson enabled, just pass C_EXT=true to the task: +To run any individual rake tasks with the C extension enabled, just pass C_EXT=true to the task: $ rake test:unit C_EXT=true @@ -327,9 +327,9 @@ validator script. This documentation is available online at http://api.mongodb.org/ruby. You can generate the documentation if you have the source by typing - $ rake rdoc + $ rake ydoc -Then open the file html/index.html. +Then open the file +ydoc/index.html+. = Release Notes diff --git a/bin/standard_benchmark b/bin/standard_benchmark index c4ab630..af94eb4 100755 --- a/bin/standard_benchmark +++ b/bin/standard_benchmark @@ -6,8 +6,8 @@ # The c-extension, mongo_ext, will be used if installed. require 'rubygems' -require 'benchmark' require 'mongo' +require 'benchmark' include Mongo diff --git a/lib/mongo/db.rb b/lib/mongo/db.rb index 598da81..72048aa 100644 --- a/lib/mongo/db.rb +++ b/lib/mongo/db.rb @@ -49,12 +49,6 @@ module Mongo # The Mongo::Connection instance connecting to the MongoDB server. attr_reader :connection - # An array of [host, port] pairs. - attr_reader :nodes - - # The logger instance if :logger is passed to initialize. - attr_reader :logger - # Instances of DB are normally obtained by calling Mongo#db. # # @param [String] db_name the database name. @@ -75,7 +69,7 @@ module Mongo @pk_factory = options[:pk] end - # Authenticates with the given username and password. Note that mongod + # Authenticate with the given username and password. Note that mongod # must be started with the --auth option for authentication to be enabled. # # @param [String] username @@ -130,7 +124,7 @@ module Mongo # # @param [String] coll_name return info for the specifed collection only. # - # @return [Mongo::Cursor] + # @return [Mongo::Cursor] def collections_info(coll_name=nil) selector = {} selector[:name] = full_collection_name(coll_name) if coll_name @@ -187,6 +181,8 @@ module Mongo # @param [String] name the collection name. # # @raise [MongoDBError] if collection does not already exist and we're in +strict+ mode. + # + # @return [Mongo::Collection] def collection(name) return Collection.new(self, name, @pk_factory) if !strict? || collection_names.include?(name) raise MongoDBError, "Collection #{name} doesn't exist. Currently in strict mode." @@ -205,9 +201,10 @@ module Mongo end # Get the error message from the most recently executed database - # operation for this connection, or +nil+ if there was no error. + # operation for this connection. # - # @return [String, Nil] + # @return [String, Nil] either the text describing the error or nil if no + # error has occurred. def error doc = command(:getlasterror => 1) raise MongoDBError, "error retrieving last error: #{doc}" unless ok?(doc) @@ -234,7 +231,7 @@ module Mongo # This command only returns errors that have occured since the last call to # DB#reset_error_history - returns +nil+ if there is no such error. # - # @return [String, Nil] + # @return [String, Nil] the text of the error or +nil+ if no error has occurred. def previous_error error = command(:getpreverror => 1) if error["err"] @@ -281,6 +278,8 @@ module Mongo # @param [String, Code] code a JavaScript expression to evaluate server-side. # @param [Integer, Hash] args any additional argument to be passed to the +code+ expression when # it's run on the server. + # + # @return [String] the return value of the function. def eval(code, *args) if not code.is_a? Code code = Code.new(code) @@ -367,12 +366,14 @@ module Mongo ok.kind_of?(Numeric) && ok.to_i == 1 end - # Send a command to the database. Note that a command has a formal definition in MongoDB: it's - # a kind of overloaded query. + # Send a command to the database. # # Note: DB commands must start with the "command" key. For this reason, # any selector containing more than one key must be an OrderedHash. # + # It may be of interest hat a command in MongoDB is technically a kind of query + # that occurs on the system command collection ($cmd). + # # @param [OrderedHash, Hash] selector an OrderedHash, or a standard Hash with just one # key, specifying the command to be performed. # @@ -434,7 +435,8 @@ module Mongo @pk_factory = pk_factory end - # Return the current database profiling level. + # Return the current database profiling level. If profiling is enabled, you can + # get the results using DB#profiling_info. # # @return [Symbol] :off, :slow_only, or :all def profiling_level @@ -454,7 +456,8 @@ module Mongo end end - # Set this database's profiling level. + # Set this database's profiling level. If profiling is enabled, you can + # get the results using DB#profiling_info. # # @param [Symbol] level acceptable options are +:off+, +:slow_only+, or +:all+. def profiling_level=(level) diff --git a/lib/mongo/gridfs/grid_store.rb b/lib/mongo/gridfs/grid_store.rb index f12cc9d..5501d93 100644 --- a/lib/mongo/gridfs/grid_store.rb +++ b/lib/mongo/gridfs/grid_store.rb @@ -33,7 +33,7 @@ module GridFS # end # # # Output "Hello, world!" - # GridStore.open(database, 'filename, 'r') do |f| + # GridStore.open(database, 'filename', 'r') do |f| # puts f.read # end # @@ -43,7 +43,7 @@ module GridFS # end # # # Retrieve everything, outputting "Hello, world!\nBut wait, there's more!\n" - # GridStore.open(database, 'filename, 'r') do |f| + # GridStore.open(database, 'filename', 'r') do |f| # puts f.read # end class GridStore diff --git a/lib/mongo/types/binary.rb b/lib/mongo/types/binary.rb index 37422d6..9d4577c 100644 --- a/lib/mongo/types/binary.rb +++ b/lib/mongo/types/binary.rb @@ -18,7 +18,10 @@ require 'mongo/util/byte_buffer' module Mongo - # An array of binary bytes with a Mongo subtype value. + # An array of binary bytes with a MongoDB subtype. See the subtype + # constants for reference. + # + # Use this class when storing binary data in documents. class Binary < ByteBuffer SUBTYPE_BYTES = 0x02 @@ -29,6 +32,13 @@ module Mongo # One of the SUBTYPE_* constants. Default is SUBTYPE_BYTES. attr_accessor :subtype + # Create a buffer for storing binary data in MongoDB. + # + # @param [Array] initia_data + # @param [Fixnum] one of four values specifying a BSON binary subtype. Possible values are + # SUBTYPE_BYTES, SUBTYPE_UUID, SUBTYPE_MD5, and SUBTYPE_USER_DEFINED. + # + # @see http://www.mongodb.org/display/DOCS/BSON#BSON-noteondatabinary BSON binary subtypes. def initialize(initial_data=[], subtype=SUBTYPE_BYTES) super(initial_data) @subtype = subtype diff --git a/lib/mongo/types/code.rb b/lib/mongo/types/code.rb index dd94908..579fddf 100644 --- a/lib/mongo/types/code.rb +++ b/lib/mongo/types/code.rb @@ -16,12 +16,17 @@ module Mongo - # JavaScript code to be evaluated by MongoDB + # JavaScript code to be evaluated by MongoDB. class Code < String # Hash mapping identifiers to their values attr_accessor :scope + # Wrap code to be evaluated by MongoDB. + # + # @param [String] code the JavaScript code. + # @param [Hash] a document mapping identifiers to values, which + # represent the scope in which the code is to be executed. def initialize(code, scope={}) super(code) @scope = scope diff --git a/lib/mongo/types/dbref.rb b/lib/mongo/types/dbref.rb index 2c1f4d7..1a68ea5 100644 --- a/lib/mongo/types/dbref.rb +++ b/lib/mongo/types/dbref.rb @@ -16,13 +16,18 @@ module Mongo + # A reference to another object in a MongoDB database. class DBRef attr_reader :namespace, :object_id + # Create a DBRef. Use this class in conjunction with DB#dereference. + # + # @param [String] a collection name + # @param [ObjectID] an object id def initialize(namespace, object_id) - @namespace, @object_id = - namespace, object_id + @namespace = namespace + @object_id = object_id end def to_s diff --git a/lib/mongo/types/objectid.rb b/lib/mongo/types/objectid.rb index 6afd016..9d3b2d6 100644 --- a/lib/mongo/types/objectid.rb +++ b/lib/mongo/types/objectid.rb @@ -14,13 +14,13 @@ # limitations under the License. # ++ -require 'mutex_m' +require 'thread' require 'socket' require 'digest/md5' module Mongo - # Representation of an ObjectId for Mongo. + # ObjectID class for documents in MongoDB. class ObjectID # This is the legacy byte ordering for Babble. Versions of the Ruby # driver prior to 0.14 used this byte ordering when converting ObjectID @@ -30,11 +30,20 @@ module Mongo # with ObjectID#legacy_string_convert BYTE_ORDER = [7, 6, 5, 4, 3, 2, 1, 0, 11, 10, 9, 8] - LOCK = Object.new - LOCK.extend Mutex_m - + @@lock = Mutex.new @@index = 0 + # Create a new object id. If no parameter is given, an id corresponding + # to the ObjectID BSON data type will be created. This is a 12-byte value + # consisting of a 4-byte timestamp, a 3-byte machine id, a 2-byte process id, + # and a 3-byte counter. + # + # @param [Array] data should be an array of bytes. If you want + # to generate a standard MongoDB object id, leave this argument blank. + def initialize(data=nil) + @data = data || generate + end + def self.legal?(str) len = BYTE_ORDER.length * 2 str =~ /([0-9a-f]+)/i @@ -43,32 +52,44 @@ module Mongo end # Adds a primary key to the given document if needed. + # + # @param [Hash] doc a document requiring an _id. + # + # @return [Mongo::ObjectID, Object] returns a newly-created or + # current _id for the given document. def self.create_pk(doc) doc.has_key?(:_id) || doc.has_key?('_id') ? doc : doc.merge!(:_id => self.new) end - # +data+ is an array of bytes. If nil, a new id will be generated. - def initialize(data=nil) - @data = data || generate - end - - def eql?(other) - @data == other.instance_variable_get("@data") + # Check equality of this object id with another. + # + # @param [Mongo::ObjectID] object_id + def eql?(object_id) + @data == object_id.instance_variable_get("@data") end alias_method :==, :eql? - # Returns a unique hashcode for the object. + # Get a unique hashcode for this object. # This is required since we've defined an #eql? method. + # + # @return [Integer] def hash @data.hash end + # Get an array representation of the object id. + # + # @return [Array] def to_a @data.dup end # Given a string representation of an ObjectID, return a new ObjectID # with that value. + # + # @param [String] str + # + # @return [Mongo::ObjectID] def self.from_string(str) raise InvalidObjectID, "illegal ObjectID format" unless legal?(str) data = [] @@ -78,11 +99,13 @@ module Mongo self.new(data) end + # @deprecated # Create a new ObjectID given a string representation of an ObjectID # using the legacy byte ordering. This method may eventually be # removed. If you are not sure that you need this method you should be # using the regular from_string. def self.from_string_legacy(str) + warn "Support for legacy object ids has been DEPRECATED." raise InvalidObjectID, "illegal ObjectID format" unless legal?(str) data = [] BYTE_ORDER.each_with_index { |string_position, data_index| @@ -91,6 +114,9 @@ module Mongo self.new(data) end + # Get a string representation of this object id. + # + # @return [String] def to_s str = ' ' * 24 12.times do |i| @@ -98,17 +124,18 @@ module Mongo end str end + alias_method :inspect, :to_s - def inspect; to_s; end - def to_json(*args) %Q("#{to_s}") end + # @deprecated # Get a string representation of this ObjectID using the legacy byte # ordering. This method may eventually be removed. If you are not sure # that you need this method you should be using the regular to_s. def to_s_legacy + warn "Support for legacy object ids has been DEPRECATED." str = ' ' * 24 BYTE_ORDER.each_with_index { |string_position, data_index| str[string_position * 2, 2] = '%02x' % @data[data_index] @@ -116,11 +143,13 @@ module Mongo str end + # @deprecated # Convert a string representation of an ObjectID using the legacy byte # ordering to the proper byte ordering. This method may eventually be # removed. If you are not sure that you need this method it is probably # unnecessary. def self.legacy_string_convert(str) + warn "Support for legacy object ids has been DEPRECATED." legacy = ' ' * 24 BYTE_ORDER.each_with_index do |legacy_pos, pos| legacy[legacy_pos * 2, 2] = str[pos * 2, 2] @@ -128,8 +157,11 @@ module Mongo legacy end - # Returns the utc time at which this ObjectID was generated. This may - # be used in lieu of a created_at timestamp. + # Return the UTC time at which this ObjectID was generated. This may + # be used in lieu of a created_at timestamp since this information + # is always encoded in the object id. + # + # @return [Time] the time at which this object was created. def generation_time Time.at(@data.pack("C4").unpack("N")[0]) end @@ -159,9 +191,9 @@ module Mongo end def get_inc - LOCK.mu_synchronize { + @@lock.synchronize do @@index = (@@index + 1) % 0xFFFFFF - } + end end end end