mongo 1.8.3 → 1.8.4.rc0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +14 -6
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/VERSION +1 -1
- data/lib/mongo.rb +11 -0
- data/lib/mongo/collection.rb +54 -49
- data/lib/mongo/cursor.rb +8 -4
- data/lib/mongo/db.rb +107 -112
- data/lib/mongo/mongo_client.rb +18 -14
- data/lib/mongo/mongo_replica_set_client.rb +17 -10
- data/lib/mongo/util/pool.rb +0 -19
- data/lib/mongo/util/pool_manager.rb +0 -21
- data/lib/mongo/util/read_preference.rb +40 -12
- data/lib/mongo/util/uri_parser.rb +2 -2
- data/mongo.gemspec +1 -0
- data/test/auxillary/pool_reuse_test.rb +0 -0
- data/test/bson/object_id_test.rb +7 -1
- data/test/functional/collection_test.rb +24 -1
- data/test/functional/connection_test.rb +7 -7
- data/test/functional/db_api_test.rb +5 -6
- data/test/functional/uri_test.rb +16 -16
- data/test/replica_set/basic_test.rb +1 -1
- data/test/replica_set/pinning_test.rb +41 -0
- data/test/replica_set/refresh_test.rb +0 -0
- data/test/sharded_cluster/basic_test.rb +0 -0
- data/test/unit/client_test.rb +2 -2
- data/test/unit/collection_test.rb +1 -1
- data/test/unit/connection_test.rb +2 -2
- data/test/unit/db_test.rb +0 -1
- data/test/unit/pool_manager_test.rb +0 -0
- metadata +41 -30
- metadata.gz.sig +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,15 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
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=
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.8.
|
1
|
+
1.8.4.rc0
|
data/lib/mongo.rb
CHANGED
@@ -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
|
data/lib/mongo/collection.rb
CHANGED
@@ -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
|
-
|
61
|
-
|
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
|
-
|
69
|
-
|
70
|
-
|
71
|
-
if name.include?
|
72
|
-
raise Mongo::InvalidNSName,
|
73
|
-
|
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
|
-
|
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?
|
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,
|
487
|
-
# as Mongo::ASCENDING, Mongo::DESCENDING,
|
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]
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
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
|
555
|
-
opts[:dropDups]
|
556
|
-
|
557
|
-
|
558
|
-
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
|
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 (
|
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,
|
1113
|
-
indexes.push("#{field}_#{
|
1117
|
+
spec.each_pair do |field, type|
|
1118
|
+
indexes.push("#{field}_#{type}")
|
1114
1119
|
end
|
1115
1120
|
indexes.join("_")
|
1116
1121
|
end
|
data/lib/mongo/cursor.rb
CHANGED
@@ -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(
|
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
|
|
data/lib/mongo/db.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
49
|
-
#
|
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
|
-
|
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
|
-
|
163
|
-
|
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
|
-
|
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
|
-
|
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, "
|
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
|
-
|
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
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
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
|
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
|
326
|
-
|
327
|
-
|
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, "
|
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
|
-
|
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
|
-
|
408
|
+
unless code.is_a?(BSON::Code)
|
402
409
|
code = BSON::Code.new(code)
|
403
410
|
end
|
404
411
|
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
doc = command(
|
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
|
-
|
422
|
-
|
423
|
-
|
424
|
-
doc = DB.new('admin', @connection).command(
|
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
|
-
|
439
|
-
|
440
|
-
|
441
|
-
doc = command(
|
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,
|
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
|
503
|
-
raise MongoArgumentError, "
|
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(
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
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
|
-
|
527
|
-
|
528
|
-
|
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
|
-
|
562
|
-
|
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
|
-
|
576
|
-
|
577
|
-
doc = command(
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
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
|
-
|
597
|
-
|
598
|
-
|
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
|
-
|
632
|
-
|
633
|
-
|
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
|