mongo 1.8.3 → 1.8.4.rc0

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.
checksums.yaml CHANGED
@@ -1,7 +1,15 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 9292e4cac6a44329fb7c7940421fe07ff8e787bd
4
- data.tar.gz: 14a5d525f6fd6cefe6694576e02d841d2882994b
5
- SHA512:
6
- metadata.gz: b58e0adafd2a3b6522a74c87c8aaae7ea7ae2968fc8fa83b1fe0851accc74df459e683d3755a5d96d84509d19b6b3e11c55d35a6ed4024997b28d847dd587233
7
- data.tar.gz: a910cea9b47023cd6bca4771557d00e435f2acc9234acafcfd43445e82ab947e941bca3db71afb2030aeedb1454e0956bf530b8e82b6b606b5a9d5b9fd404e1b
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ YjU5N2Y3NjIxZDMyODFiMDI3MWYzODQ1MzNiMDk2YjgxZmQwY2EyYg==
5
+ data.tar.gz: !binary |-
6
+ MTEwZTgzOWQ3MzkyNGNhNmQ3ZDY2YzE0ZGVkMDc0MTJhNWRlOWM4Yg==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ NjYwYTlmNDYwNTZkZjZiMmQyZTUzNzgxOTM5NGMwMWQ0YjY5MDE3M2M3YmUx
10
+ MmI3MWNmN2QxMTgwMTZiMTdjNzMyODJhZjAzYTg1M2VkMTI4OTI5ZjNlMjdl
11
+ NTVlY2E0MDc5MTY3ZmNjOTBhZmFkMjA2MDlkYjAzYjgyNTMyNWE=
12
+ data.tar.gz: !binary |-
13
+ MGJlZGJlMjk5NWFhYjI1MjhiYjYwMmVkZjViZTdiNDE0ZjY0YWEwZmIxZDRj
14
+ NzEyYjk5N2Y1MDMyNWM4ZmU1YTM0ODA2ZDQ3ZTQwNTdhNTRmOGNhZmEwNjA3
15
+ ZTZlNzM5YzRiYmJkN2JlM2VmYTEzNWJhOThjYTRhMzRiNTg2N2U=
Binary file
data.tar.gz.sig CHANGED
Binary file
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.8.3
1
+ 1.8.4.rc0
@@ -2,7 +2,18 @@ module Mongo
2
2
  ASCENDING = 1
3
3
  DESCENDING = -1
4
4
  GEO2D = '2d'
5
+ GEO2DSPHERE = '2dsphere'
5
6
  GEOHAYSTACK = 'geoHaystack'
7
+ TEXT = 'text'
8
+ HASHED = 'hashed'
9
+ INDEX_TYPES = [ ASCENDING,
10
+ DESCENDING,
11
+ GEO2D,
12
+ GEO2DSPHERE,
13
+ GEOHAYSTACK,
14
+ TEXT,
15
+ HASHED
16
+ ]
6
17
 
7
18
  DEFAULT_MAX_BSON_SIZE = 4 * 1024 * 1024
8
19
  DEFAULT_MAX_MESSAGE_SIZE = DEFAULT_MAX_BSON_SIZE * 2
@@ -9,7 +9,8 @@ module Mongo
9
9
  :name,
10
10
  :pk_factory,
11
11
  :hint,
12
- :write_concern
12
+ :write_concern,
13
+ :capped
13
14
 
14
15
  # Read Preference
15
16
  attr_accessor :read,
@@ -20,20 +21,20 @@ module Mongo
20
21
  #
21
22
  # @param [String, Symbol] name the name of the collection.
22
23
  # @param [DB] db a MongoDB database instance.
23
- #
24
+ #
24
25
  # @option opts [String, Integer, Symbol] :w (1) Set default number of nodes to which a write
25
26
  # should be acknowledged
26
27
  # @option opts [Boolean] :j (false) Set journal acknowledgement
27
28
  # @option opts [Integer] :wtimeout (nil) Set replica set acknowledgement timeout
28
29
  # @option opts [Boolean] :fsync (false) Set fsync acknowledgement.
29
- #
30
+ #
30
31
  # Notes about write concern:
31
- # These write concern options will be used for insert, update, and remove methods called on this
32
- # Collection instance. If no value is provided, the default values set on this instance's DB will be used.
32
+ # These write concern options will be used for insert, update, and remove methods called on this
33
+ # Collection instance. If no value is provided, the default values set on this instance's DB will be used.
33
34
  # These option values can be overridden for any invocation of insert, update, or remove.
34
35
  #
35
36
  # @option opts [:create_pk] :pk (BSON::ObjectId) A primary key factory to use
36
- # other than the default BSON::ObjectId.
37
+ # other than the default BSON::ObjectId.
37
38
  # @option opts [:primary, :secondary] :read The default read preference for queries
38
39
  # initiates from this connection object. If +:secondary+ is chosen, reads will be sent
39
40
  # to one of the closest available secondary nodes. If a secondary node cannot be located, the
@@ -57,30 +58,26 @@ module Mongo
57
58
  db, name = name, db
58
59
  end
59
60
 
60
- case name
61
- when Symbol, String
62
- else
63
- raise TypeError, "new_name must be a string or symbol"
64
- end
65
-
61
+ raise TypeError,
62
+ "Collection name must be a String or Symbol." unless [String, Symbol].include?(name.class)
66
63
  name = name.to_s
67
64
 
68
- if name.empty? or name.include? ".."
69
- raise Mongo::InvalidNSName, "collection names cannot be empty"
70
- end
71
- if name.include? "$"
72
- raise Mongo::InvalidNSName, "collection names must not contain '$'" unless name =~ /((^\$cmd)|(oplog\.\$main))/
73
- end
74
- if name.match(/^\./) or name.match(/\.$/)
75
- raise Mongo::InvalidNSName, "collection names must not start or end with '.'"
65
+ raise Mongo::InvalidNSName,
66
+ "Collection names cannot be empty." if name.empty? || name.include?("..")
67
+
68
+ if name.include?("$")
69
+ raise Mongo::InvalidNSName,
70
+ "Collection names must not contain '$'" unless name =~ /((^\$cmd)|(oplog\.\$main))/
76
71
  end
77
72
 
73
+ raise Mongo::InvalidNSName,
74
+ "Collection names must not start or end with '.'" if name.match(/^\./) || name.match(/\.$/)
75
+
76
+ pk_factory = nil
78
77
  if opts.respond_to?(:create_pk) || !opts.is_a?(Hash)
79
78
  warn "The method for specifying a primary key factory on a Collection has changed.\n" +
80
- "Please specify it as an option (e.g., :pk => PkFactory)."
79
+ "Please specify it as an option (e.g., :pk => PkFactory)."
81
80
  pk_factory = opts
82
- else
83
- pk_factory = nil
84
81
  end
85
82
 
86
83
  @db, @name = db, name
@@ -92,6 +89,7 @@ module Mongo
92
89
  @write_concern = get_write_concern(opts, db)
93
90
  @read = opts[:read] || @db.read
94
91
  Mongo::ReadPreference::validate(@read)
92
+ @capped = opts[:capped]
95
93
  @tag_sets = opts.fetch(:tag_sets, @db.tag_sets)
96
94
  @acceptable_latency = opts.fetch(:acceptable_latency, @db.acceptable_latency)
97
95
  end
@@ -106,7 +104,7 @@ module Mongo
106
104
  #
107
105
  # @return [Boolean]
108
106
  def capped?
109
- [1, true].include? @db.command({:collstats => @name})['capped']
107
+ @capped ||= [1, true].include?(@db.command({:collstats => @name})['capped'])
110
108
  end
111
109
 
112
110
  # Return a sub-collection of this collection by name. If 'users' is a collection, then
@@ -315,10 +313,10 @@ module Mongo
315
313
  # @return [ObjectId] the _id of the saved document.
316
314
  #
317
315
  # @option opts [Hash] :w, :j, :wtimeout, :fsync Set the write concern for this operation.
318
- # :w > 0 will run a +getlasterror+ command on the database to report any assertion.
316
+ # :w > 0 will run a +getlasterror+ command on the database to report any assertion.
319
317
  # :j will confirm a write has been committed to the journal,
320
318
  # :wtimeout specifies how long to wait for write confirmation,
321
- # :fsync will confirm that a write has been fsynced.
319
+ # :fsync will confirm that a write has been fsynced.
322
320
  # Options provided here will override any write concern options set on this collection,
323
321
  # its database object, or the current connection. See the options
324
322
  # for DB#get_last_error.
@@ -351,23 +349,23 @@ module Mongo
351
349
  # @option opts [Boolean] :j (false) Set journal acknowledgement
352
350
  # @option opts [Integer] :wtimeout (nil) Set replica set acknowledgement timeout
353
351
  # @option opts [Boolean] :fsync (false) Set fsync acknowledgement.
354
- #
352
+ #
355
353
  # Notes on write concern:
356
354
  # Options provided here will override any write concern options set on this collection,
357
- # its database object, or the current connection. See the options for +DB#get_last_error+.
355
+ # its database object, or the current connection. See the options for +DB#get_last_error+.
358
356
  #
359
357
  # @option opts [Boolean] :continue_on_error (+false+) If true, then
360
358
  # continue a bulk insert even if one of the documents inserted
361
359
  # triggers a database assertion (as in a duplicate insert, for instance).
362
360
  # If not acknowledging writes, the list of ids returned will
363
361
  # include the object ids of all documents attempted on insert, even
364
- # if some are rejected on error. When acknowledging writes, any error will raise an
362
+ # if some are rejected on error. When acknowledging writes, any error will raise an
365
363
  # OperationFailure exception.
366
364
  # MongoDB v2.0+.
367
365
  # @option opts [Boolean] :collect_on_error (+false+) if true, then
368
366
  # collects invalid documents as an array. Note that this option changes the result format.
369
367
  #
370
- # @raise [Mongo::OperationFailure] will be raised iff :w > 0 and the operation fails.
368
+ # @raise [Mongo::OperationFailure] will be raised iff :w > 0 and the operation fails.
371
369
  #
372
370
  # @core insert insert-instance_method
373
371
  def insert(doc_or_docs, opts={})
@@ -392,7 +390,7 @@ module Mongo
392
390
  #
393
391
  # Notes on write concern:
394
392
  # Options provided here will override any write concern options set on this collection,
395
- # its database object, or the current connection. See the options for +DB#get_last_error+.
393
+ # its database object, or the current connection. See the options for +DB#get_last_error+.
396
394
  #
397
395
  # @example remove all documents from the 'users' collection:
398
396
  # users.remove
@@ -446,7 +444,7 @@ module Mongo
446
444
  #
447
445
  # Notes on write concern:
448
446
  # Options provided here will override any write concern options set on this collection,
449
- # its database object, or the current connection. See the options for DB#get_last_error.
447
+ # its database object, or the current connection. See the options for DB#get_last_error.
450
448
  #
451
449
  # @return [Hash, true] Returns a Hash containing the last error object if acknowledging writes.
452
450
  # Otherwise, returns true.
@@ -483,8 +481,9 @@ module Mongo
483
481
  #
484
482
  # @param [String, Array] spec
485
483
  # should be either a single field name or an array of
486
- # [field name, direction] pairs. Directions should be specified
487
- # as Mongo::ASCENDING, Mongo::DESCENDING, or Mongo::GEO2D.
484
+ # [field name, type] pairs. Index types should be specified
485
+ # as Mongo::ASCENDING, Mongo::DESCENDING, Mongo::GEO2D, Mongo::GEO2DSPHERE, Mongo::GEOHAYSTACK,
486
+ # Mongo::TEXT or Mongo::HASHED.
488
487
  #
489
488
  # Note that geospatial indexing only works with versions of MongoDB >= 1.3.3+. Keep in mind, too,
490
489
  # that in order to geo-index a given field, that field must reference either an array or a sub-object
@@ -501,6 +500,8 @@ module Mongo
501
500
  # feature is only available in MongoDB >= 1.3.2.
502
501
  # @option opts [Boolean] :drop_dups (nil) If creating a unique index on a collection with pre-existing records,
503
502
  # this option will keep the first document the database indexes and drop all subsequent with duplicate values.
503
+ # @option opts [Integer] :bucket_size (nil) For use with geoHaystack indexes. Number of documents to group
504
+ # together within a certain proximity to a given longitude and latitude.
504
505
  # @option opts [Integer] :min (nil) specify the minimum longitude and latitude for a geo index.
505
506
  # @option opts [Integer] :max (nil) specify the maximum longitude and latitude for a geo index.
506
507
  #
@@ -525,11 +526,12 @@ module Mongo
525
526
  #
526
527
  # @core indexes create_index-instance_method
527
528
  def create_index(spec, opts={})
528
- opts[:dropDups] = opts[:drop_dups] if opts[:drop_dups]
529
- field_spec = parse_index_spec(spec)
530
- opts = opts.dup
531
- name = opts.delete(:name) || generate_index_name(field_spec)
532
- name = name.to_s if name
529
+ opts[:dropDups] = opts[:drop_dups] if opts[:drop_dups]
530
+ opts[:bucketSize] = opts[:bucket_size] if opts[:bucket_size]
531
+ field_spec = parse_index_spec(spec)
532
+ opts = opts.dup
533
+ name = opts.delete(:name) || generate_index_name(field_spec)
534
+ name = name.to_s if name
533
535
  generate_indexes(field_spec, name, opts)
534
536
  name
535
537
  end
@@ -551,11 +553,12 @@ module Mongo
551
553
  #
552
554
  # @return [String] the name of the index.
553
555
  def ensure_index(spec, opts={})
554
- now = Time.now.utc.to_i
555
- opts[:dropDups] = opts[:drop_dups] if opts[:drop_dups]
556
- field_spec = parse_index_spec(spec)
557
- name = opts[:name] || generate_index_name(field_spec)
558
- name = name.to_s if name
556
+ now = Time.now.utc.to_i
557
+ opts[:dropDups] = opts[:drop_dups] if opts[:drop_dups]
558
+ opts[:bucketSize] = opts[:bucket_size] if opts[:bucket_size]
559
+ field_spec = parse_index_spec(spec)
560
+ name = opts[:name] || generate_index_name(field_spec)
561
+ name = name.to_s if name
559
562
 
560
563
  if !@cache[name] || @cache[name] <= now
561
564
  generate_indexes(field_spec, name, opts)
@@ -626,7 +629,7 @@ module Mongo
626
629
  #
627
630
  # @param [Array] pipeline Should be a single array of pipeline operator hashes.
628
631
  #
629
- # '$project' Reshapes a document stream by including fields, excluding fields, inserting computed fields,
632
+ # '$project' Reshapes a document stream by including fields, excluding fields, inserting computed fields,
630
633
  # renaming fields,or creating/populating fields that hold sub-documents.
631
634
  #
632
635
  # '$match' Query-like interface for filtering documents out of the aggregation pipeline.
@@ -1017,11 +1020,13 @@ module Mongo
1017
1020
  end
1018
1021
  elsif spec.is_a?(Array) && spec.all? {|field| field.is_a?(Array) }
1019
1022
  spec.each do |f|
1020
- if [Mongo::ASCENDING, Mongo::DESCENDING, Mongo::GEO2D, Mongo::GEOHAYSTACK].include?(f[1])
1023
+ if Mongo::INDEX_TYPES.include?(f[1])
1021
1024
  field_spec[f[0].to_s] = f[1]
1022
1025
  else
1023
1026
  raise MongoArgumentError, "Invalid index field #{f[1].inspect}; " +
1024
- "should be one of Mongo::ASCENDING (1), Mongo::DESCENDING (-1) or Mongo::GEO2D ('2d')."
1027
+ "should be one of Mongo::ASCENDING (#{Mongo::ASCENDING}), Mongo::DESCENDING (#{Mongo::DESCENDING}), " +
1028
+ "Mongo::GEOHAYSTACK ('#{Mongo::GEOHAYSTACK}'), Mongo::GEO2DSPHERE ('#{Mongo::GEO2DSPHERE}'), " +
1029
+ "Mongo::TEXT ('#{Mongo::TEXT}'), or Mongo::HASHED ('#{Mongo::HASHED}')"
1025
1030
  end
1026
1031
  end
1027
1032
  else
@@ -1109,8 +1114,8 @@ module Mongo
1109
1114
 
1110
1115
  def generate_index_name(spec)
1111
1116
  indexes = []
1112
- spec.each_pair do |field, direction|
1113
- indexes.push("#{field}_#{direction}")
1117
+ spec.each_pair do |field, type|
1118
+ indexes.push("#{field}_#{type}")
1114
1119
  end
1115
1120
  indexes.join("_")
1116
1121
  end
@@ -6,12 +6,13 @@ module Mongo
6
6
  include Mongo::Constants
7
7
  include Mongo::Conversions
8
8
  include Mongo::Logging
9
+ include Mongo::ReadPreference
9
10
 
10
11
  attr_reader :collection, :selector, :fields,
11
12
  :order, :hint, :snapshot, :timeout,
12
13
  :full_collection_name, :transformer,
13
14
  :options, :cursor_id, :show_disk_loc,
14
- :comment, :read, :tag_sets
15
+ :comment, :read, :tag_sets, :acceptable_latency
15
16
 
16
17
  # Create a new cursor.
17
18
  #
@@ -471,6 +472,7 @@ module Mongo
471
472
  nil, @options & OP_QUERY_EXHAUST != 0)
472
473
  rescue ConnectionFailure => ex
473
474
  socket.close if socket
475
+ @connection.unpin_pool
474
476
  @connection.refresh
475
477
  if tries < 3 && !@socket && (!@command || Mongo::Support::secondary_ok?(@selector))
476
478
  tries += 1
@@ -483,6 +485,9 @@ module Mongo
483
485
  ensure
484
486
  socket.checkin unless @socket || socket.nil?
485
487
  end
488
+ if !@socket && !@command
489
+ @connection.pin_pool(socket.pool, read_preference)
490
+ end
486
491
  @returned += @n_received
487
492
  @cache += results
488
493
  @query_run = true
@@ -530,16 +535,15 @@ module Mongo
530
535
  if @pool
531
536
  socket = @pool.checkout
532
537
  elsif @command && !Mongo::Support::secondary_ok?(@selector)
533
- socket = @connection.checkout_reader(:primary)
538
+ socket = @connection.checkout_reader({:mode => :primary})
534
539
  else
535
- socket = @connection.checkout_reader(@read, @tag_sets, @acceptable_latency)
540
+ socket = @connection.checkout_reader(read_preference)
536
541
  end
537
542
  rescue SystemStackError, NoMemoryError, SystemCallError => ex
538
543
  @connection.close
539
544
  raise ex
540
545
  end
541
546
  @pool = socket.pool
542
- #puts "checkout_socket_from_connection caller:#{caller[0][/:in `([^']+)'/,1]} self:#{self.object_id} @pool.port:#{@pool.port}"
543
547
  socket
544
548
  end
545
549
 
@@ -14,6 +14,12 @@ module Mongo
14
14
  SYSTEM_JS_COLLECTION = 'system.js'
15
15
  SYSTEM_COMMAND_COLLECTION = '$cmd'
16
16
 
17
+ PROFILE_LEVEL = {
18
+ :off => 0,
19
+ :slow_only => 1,
20
+ :all => 2
21
+ }
22
+
17
23
  # Counter for generating unique request ids.
18
24
  @@current_request_id = 0
19
25
 
@@ -22,10 +28,24 @@ module Mongo
22
28
  # collection that already exists, raises an error.
23
29
  #
24
30
  # Strict mode is disabled by default, but enabled (+true+) at any time.
25
- attr_writer :strict
31
+ #
32
+ # @deprecated Support for strict mode has been deprecated and will be
33
+ # removed in version 2.0 of the driver.
34
+ def strict=(value)
35
+ unless ENV['TEST_MODE']
36
+ warn "Support for strict mode has been deprecated and will be " +
37
+ "removed in version 2.0 of the driver."
38
+ end
39
+ @strict = value
40
+ end
26
41
 
27
42
  # Returns the value of the +strict+ flag.
28
- def strict?; @strict; end
43
+ #
44
+ # @deprecated Support for strict mode has been deprecated and will be
45
+ # removed in version 2.0 of the driver.
46
+ def strict?
47
+ @strict
48
+ end
29
49
 
30
50
  # The name of the database and the local write concern options.
31
51
  attr_reader :name, :write_concern
@@ -45,8 +65,9 @@ module Mongo
45
65
  # @param [Mongo::MongoClient] client a connection object pointing to MongoDB. Note
46
66
  # that databases are usually instantiated via the MongoClient class. See the examples below.
47
67
  #
48
- # @option opts [Boolean] :strict (False) If true, collections must exist to be accessed and must
49
- # not exist to be created. See DB#collection and DB#create_collection.
68
+ # @option opts [Boolean] :strict (False) [DEPRECATED] If true, collections existence checks are
69
+ # performed during a number of relevant operations. See DB#collection, DB#create_collection and
70
+ # DB#drop_collection.
50
71
  #
51
72
  # @option opts [Object, #create_pk(doc)] :pk (BSON::ObjectId) A primary key factory object,
52
73
  # which should take a hash and return a hash which merges the original hash with any primary key
@@ -99,10 +120,8 @@ module Mongo
99
120
  #
100
121
  # @core authenticate authenticate-instance_method
101
122
  def authenticate(username, password, save_auth=true)
102
- if @connection.pool_size > 1
103
- if !save_auth
104
- raise MongoArgumentError, "If using connection pooling, :save_auth must be set to true."
105
- end
123
+ if @connection.pool_size > 1 && !save_auth
124
+ raise MongoArgumentError, "If using connection pooling, :save_auth must be set to true."
106
125
  end
107
126
 
108
127
  begin
@@ -126,17 +145,15 @@ module Mongo
126
145
  auth['nonce'] = nonce
127
146
  auth['key'] = Mongo::Support.auth_key(username, password, nonce)
128
147
  if ok?(doc = self.command(auth, :check_response => false, :socket => opts[:socket]))
129
- if save_auth
130
- @connection.add_auth(@name, username, password)
131
- end
132
- true
148
+ @connection.add_auth(@name, username, password) if save_auth
133
149
  else
134
150
  message = "Failed to authenticate user '#{username}' on db '#{self.name}'"
135
151
  raise Mongo::AuthenticationError.new(message, doc['code'], doc)
136
152
  end
153
+ true
137
154
  end
138
155
 
139
- # Adds a stored Javascript function to the database which can executed
156
+ # Adds a stored Javascript function to the database which can executed
140
157
  # server-side in map_reduce, db.eval and $where clauses.
141
158
  #
142
159
  # @param [String] function_name
@@ -146,7 +163,7 @@ module Mongo
146
163
  def add_stored_function(function_name, code)
147
164
  self[SYSTEM_JS_COLLECTION].save(
148
165
  {
149
- "_id" => function_name,
166
+ "_id" => function_name,
150
167
  :value => BSON::Code.new(code)
151
168
  }
152
169
  )
@@ -159,11 +176,8 @@ module Mongo
159
176
  #
160
177
  # @return [Boolean]
161
178
  def remove_stored_function(function_name)
162
- if self[SYSTEM_JS_COLLECTION].find_one({"_id" => function_name})
163
- self[SYSTEM_JS_COLLECTION].remove({"_id" => function_name}, :w => 1)
164
- else
165
- return false
166
- end
179
+ return false unless self[SYSTEM_JS_COLLECTION].find_one({"_id" => function_name})
180
+ self[SYSTEM_JS_COLLECTION].remove({"_id" => function_name}, :w => 1)
167
181
  end
168
182
 
169
183
  # Adds a user to this database for use with authentication. If the user already
@@ -181,7 +195,7 @@ module Mongo
181
195
  user['pwd'] = Mongo::Support.hash_password(username, password)
182
196
  user['readOnly'] = true if read_only;
183
197
  users.save(user)
184
- return user
198
+ user
185
199
  end
186
200
 
187
201
  # Remove the given user from this database. Returns false if the user
@@ -194,7 +208,7 @@ module Mongo
194
208
  if self[SYSTEM_USER_COLLECTION].find_one({:user => username})
195
209
  self[SYSTEM_USER_COLLECTION].remove({:user => username}, :w => 1)
196
210
  else
197
- return false
211
+ false
198
212
  end
199
213
  end
200
214
 
@@ -206,21 +220,17 @@ module Mongo
206
220
  #
207
221
  # @return [Boolean]
208
222
  def logout(opts={})
209
- if @connection.pool_size > 1
210
- @connection.logout_pools(@name)
211
- end
212
-
223
+ @connection.logout_pools(@name) if @connection.pool_size > 1
213
224
  issue_logout(opts)
214
225
  end
215
226
 
216
227
  def issue_logout(opts={})
217
- doc = command({:logout => 1}, :socket => opts[:socket])
218
- if ok?(doc)
228
+ if ok?(doc = command({:logout => 1}, :socket => opts[:socket]))
219
229
  @connection.remove_auth(@name)
220
- true
221
230
  else
222
- raise MongoDBError, "error logging out: #{doc.inspect}"
231
+ raise MongoDBError, "Error logging out: #{doc.inspect}"
223
232
  end
233
+ true
224
234
  end
225
235
 
226
236
  # Get an array of collection names in this database.
@@ -278,20 +288,19 @@ module Mongo
278
288
  # @return [Mongo::Collection]
279
289
  def create_collection(name, opts={})
280
290
  name = name.to_s
281
- if collection_names.include?(name)
282
- if strict?
283
- raise MongoDBError, "Collection #{name} already exists. " +
284
- "Currently in strict mode."
285
- else
286
- return Collection.new(name, self, opts)
287
- end
291
+ if strict? && collection_names.include?(name)
292
+ raise MongoDBError, "Collection '#{name}' already exists. (strict=true)"
288
293
  end
289
294
 
290
- # Create a new collection.
291
- oh = BSON::OrderedHash.new
292
- oh[:create] = name
293
- doc = command(oh.merge(opts || {}))
294
- return Collection.new(name, self, :pk => @pk_factory) if ok?(doc)
295
+ begin
296
+ cmd = BSON::OrderedHash.new
297
+ cmd[:create] = name
298
+ doc = command(cmd.merge(opts || {}))
299
+ return Collection.new(name, self, :pk => @pk_factory) if ok?(doc)
300
+ rescue OperationFailure => e
301
+ return Collection.new(name, self, :pk => @pk_factory) if e.message =~ /exists/
302
+ raise e
303
+ end
295
304
  raise MongoDBError, "Error creating collection: #{doc.inspect}"
296
305
  end
297
306
 
@@ -306,8 +315,7 @@ module Mongo
306
315
  # @return [Mongo::Collection]
307
316
  def collection(name, opts={})
308
317
  if strict? && !collection_names.include?(name.to_s)
309
- raise Mongo::MongoDBError, "Collection #{name} doesn't exist. " +
310
- "Currently in strict mode."
318
+ raise MongoDBError, "Collection '#{name}' doesn't exist. (strict=true)"
311
319
  else
312
320
  opts = opts.dup
313
321
  opts.merge!(:pk => @pk_factory) unless opts[:pk]
@@ -322,9 +330,12 @@ module Mongo
322
330
  #
323
331
  # @return [Boolean] +true+ on success or +false+ if the collection name doesn't exist.
324
332
  def drop_collection(name)
325
- return true unless collection_names.include?(name.to_s)
326
-
327
- ok?(command(:drop => name))
333
+ return false if strict? && !collection_names.include?(name.to_s)
334
+ begin
335
+ ok?(command(:drop => name))
336
+ rescue OperationFailure => e
337
+ false
338
+ end
328
339
  end
329
340
 
330
341
  # Run the getlasterror command with the specified replication options.
@@ -342,7 +353,7 @@ module Mongo
342
353
  cmd[:getlasterror] = 1
343
354
  cmd.merge!(opts)
344
355
  doc = command(cmd, :check_response => false)
345
- raise MongoDBError, "error retrieving last error: #{doc.inspect}" unless ok?(doc)
356
+ raise MongoDBError, "Error retrieving last error: #{doc.inspect}" unless ok?(doc)
346
357
  doc
347
358
  end
348
359
 
@@ -362,11 +373,7 @@ module Mongo
362
373
  # @return [String, Nil] the text of the error or +nil+ if no error has occurred.
363
374
  def previous_error
364
375
  error = command(:getpreverror => 1)
365
- if error["err"]
366
- error
367
- else
368
- nil
369
- end
376
+ error["err"] ? error : nil
370
377
  end
371
378
 
372
379
  # Reset the error history of this database
@@ -393,19 +400,19 @@ module Mongo
393
400
  # Evaluate a JavaScript expression in MongoDB.
394
401
  #
395
402
  # @param [String, Code] code a JavaScript expression to evaluate server-side.
396
- # @param [Integer, Hash] args any additional argument to be passed to the +code+ expression when
403
+ # @param [Integer, Hash] args any additional argument to be passed to the +code+ expression when
397
404
  # it's run on the server.
398
405
  #
399
406
  # @return [String] the return value of the function.
400
407
  def eval(code, *args)
401
- if not code.is_a? BSON::Code
408
+ unless code.is_a?(BSON::Code)
402
409
  code = BSON::Code.new(code)
403
410
  end
404
411
 
405
- oh = BSON::OrderedHash.new
406
- oh[:$eval] = code
407
- oh[:args] = args
408
- doc = command(oh)
412
+ cmd = BSON::OrderedHash.new
413
+ cmd[:$eval] = code
414
+ cmd[:args] = args
415
+ doc = command(cmd)
409
416
  doc['retval']
410
417
  end
411
418
 
@@ -418,10 +425,10 @@ module Mongo
418
425
  #
419
426
  # @raise MongoDBError if there's an error renaming the collection.
420
427
  def rename_collection(from, to)
421
- oh = BSON::OrderedHash.new
422
- oh[:renameCollection] = "#{@name}.#{from}"
423
- oh[:to] = "#{@name}.#{to}"
424
- doc = DB.new('admin', @connection).command(oh, :check_response => false)
428
+ cmd = BSON::OrderedHash.new
429
+ cmd[:renameCollection] = "#{@name}.#{from}"
430
+ cmd[:to] = "#{@name}.#{to}"
431
+ doc = DB.new('admin', @connection).command(cmd, :check_response => false)
425
432
  ok?(doc) || raise(MongoDBError, "Error renaming collection: #{doc.inspect}")
426
433
  end
427
434
 
@@ -435,10 +442,10 @@ module Mongo
435
442
  #
436
443
  # @raise MongoDBError if there's an error dropping the index.
437
444
  def drop_index(collection_name, index_name)
438
- oh = BSON::OrderedHash.new
439
- oh[:deleteIndexes] = collection_name
440
- oh[:index] = index_name.to_s
441
- doc = command(oh, :check_response => false)
445
+ cmd = BSON::OrderedHash.new
446
+ cmd[:deleteIndexes] = collection_name
447
+ cmd[:index] = index_name.to_s
448
+ doc = command(cmd, :check_response => false)
442
449
  ok?(doc) || raise(MongoDBError, "Error with drop_index command: #{doc.inspect}")
443
450
  end
444
451
 
@@ -447,7 +454,7 @@ module Mongo
447
454
  #
448
455
  # @param [String] collection_name
449
456
  #
450
- # @return [Hash] keys are index names and the values are lists of [key, direction] pairs
457
+ # @return [Hash] keys are index names and the values are lists of [key, type] pairs
451
458
  # defining the index.
452
459
  def index_information(collection_name)
453
460
  sel = {:ns => full_collection_name(collection_name)}
@@ -499,8 +506,9 @@ module Mongo
499
506
  # @core commands command_instance-method
500
507
  def command(selector, opts={})
501
508
  check_response = opts.fetch(:check_response, true)
502
- socket = opts[:socket]
503
- raise MongoArgumentError, "command must be given a selector" unless selector.is_a?(Hash) && !selector.empty?
509
+ socket = opts[:socket]
510
+ raise MongoArgumentError, "Command must be given a selector" unless selector.is_a?(Hash) && !selector.empty?
511
+
504
512
  if selector.keys.length > 1 && RUBY_VERSION < '1.9' && selector.class != BSON::OrderedHash
505
513
  raise MongoArgumentError, "DB#command requires an OrderedHash when hash contains multiple keys"
506
514
  end
@@ -513,19 +521,21 @@ module Mongo
513
521
  end
514
522
 
515
523
  begin
516
- result = Cursor.new(system_command_collection,
517
- :limit => -1,
518
- :selector => selector,
519
- :socket => socket,
520
- :read => read_pref,
521
- :comment => opts[:comment]).next_document
524
+ result = Cursor.new(
525
+ system_command_collection,
526
+ :limit => -1,
527
+ :selector => selector,
528
+ :socket => socket,
529
+ :read => read_pref,
530
+ :comment => opts[:comment]).next_document
522
531
  rescue OperationFailure => ex
523
532
  raise OperationFailure, "Database command '#{selector.keys.first}' failed: #{ex.message}"
524
533
  end
525
534
 
526
- if result.nil?
527
- raise OperationFailure, "Database command '#{selector.keys.first}' failed: returned null."
528
- elsif (check_response && !ok?(result))
535
+ raise OperationFailure,
536
+ "Database command '#{selector.keys.first}' failed: returned null." unless result
537
+
538
+ if check_response && !ok?(result)
529
539
  message = "Database command '#{selector.keys.first}' failed: ("
530
540
  message << result.map do |key, value|
531
541
  "#{key}: '#{value}'"
@@ -533,9 +543,9 @@ module Mongo
533
543
  message << ').'
534
544
  code = result['code'] || result['assertionCode']
535
545
  raise OperationFailure.new(message, code, result)
536
- else
537
- result
538
546
  end
547
+
548
+ result
539
549
  end
540
550
 
541
551
  # A shortcut returning db plus dot plus collection name.
@@ -558,9 +568,8 @@ module Mongo
558
568
  #
559
569
  # @raise [MongoArgumentError] if the primary key factory has already been set.
560
570
  def pk_factory=(pk_factory)
561
- if @pk_factory
562
- raise MongoArgumentError, "Cannot change primary key factory once it's been set"
563
- end
571
+ raise MongoArgumentError,
572
+ "Cannot change primary key factory once it's been set" if @pk_factory
564
573
 
565
574
  @pk_factory = pk_factory
566
575
  end
@@ -572,20 +581,15 @@ module Mongo
572
581
  #
573
582
  # @core profiling profiling_level-instance_method
574
583
  def profiling_level
575
- oh = BSON::OrderedHash.new
576
- oh[:profile] = -1
577
- doc = command(oh, :check_response => false)
578
- raise "Error with profile command: #{doc.inspect}" unless ok?(doc) && doc['was'].kind_of?(Numeric)
579
- case doc['was'].to_i
580
- when 0
581
- :off
582
- when 1
583
- :slow_only
584
- when 2
585
- :all
586
- else
587
- raise "Error: illegal profiling level value #{doc['was']}"
588
- end
584
+ cmd = BSON::OrderedHash.new
585
+ cmd[:profile] = -1
586
+ doc = command(cmd, :check_response => false)
587
+
588
+ raise "Error with profile command: #{doc.inspect}" unless ok?(doc)
589
+
590
+ level_sym = PROFILE_LEVEL.invert[doc['was'].to_i]
591
+ raise "Error: illegal profiling level value #{doc['was']}" unless level_sym
592
+ level_sym
589
593
  end
590
594
 
591
595
  # Set this database's profiling level. If profiling is enabled, you can
@@ -593,18 +597,9 @@ module Mongo
593
597
  #
594
598
  # @param [Symbol] level acceptable options are +:off+, +:slow_only+, or +:all+.
595
599
  def profiling_level=(level)
596
- oh = BSON::OrderedHash.new
597
- oh[:profile] = case level
598
- when :off
599
- 0
600
- when :slow_only
601
- 1
602
- when :all
603
- 2
604
- else
605
- raise "Error: illegal profiling level value #{level}"
606
- end
607
- doc = command(oh, :check_response => false)
600
+ cmd = BSON::OrderedHash.new
601
+ cmd[:profile] = PROFILE_LEVEL[level]
602
+ doc = command(cmd, :check_response => false)
608
603
  ok?(doc) || raise(MongoDBError, "Error with profile command: #{doc.inspect}")
609
604
  end
610
605
 
@@ -628,9 +623,9 @@ module Mongo
628
623
  cmd[:validate] = name
629
624
  cmd[:full] = true
630
625
  doc = command(cmd, :check_response => false)
631
- if !ok?(doc)
632
- raise MongoDBError, "Error with validate command: #{doc.inspect}"
633
- end
626
+
627
+ raise MongoDBError, "Error with validate command: #{doc.inspect}" unless ok?(doc)
628
+
634
629
  if (doc.has_key?('valid') && !doc['valid']) || (doc['result'] =~ /\b(exception|corrupt)\b/i)
635
630
  raise MongoDBError, "Error: invalid collection #{name}: #{doc.inspect}"
636
631
  end