mongo 1.9.1 → 1.9.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a3f417c324be178d788cf734301a7bfbdd14c1ea
4
- data.tar.gz: 59dfb78c4a1f4c04d6e326bfa81e42e1858166ff
3
+ metadata.gz: 0373b5b1e6c7a4e81fa022f379ed2ee17cffde80
4
+ data.tar.gz: 681a86c1b120260262b2f77f6133c7a7497a0f34
5
5
  SHA512:
6
- metadata.gz: 099774d6c9f4b1ffdb24942372349dab0c75001af769317e9b0b586bad8931683d116c93c7dc6eba42b55595a8bad13588ac72c2381c68764161384e3d6787d2
7
- data.tar.gz: 1ad9f8b646a40006e606b0da6318beb21c0dd87559d81bf7dcbab49659789f1a952df51a4843c215667f042494aa45f678ffc440b2dc131b7f26820446a034a2
6
+ metadata.gz: e192fa80088c0151f75b40fbb0649b356c3ac781be003985d753b9fa2e6af08371bcda2061c2a1a3e088fcfdd4896987845edcdca9a5af59ce01ef604311c749
7
+ data.tar.gz: 67cff259cc85729e4c16ae706ae4cef3e3e5a747895deae699ea0cdace0eb416b5c522e3dc41fd8e92aab4b39b3cb4c30c8b3e5c6c99be4b25b965922aabf95f
Binary file
data.tar.gz.sig CHANGED
Binary file
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.9.1
1
+ 1.9.2
@@ -616,25 +616,36 @@ module Mongo
616
616
 
617
617
  # Atomically update and return a document using MongoDB's findAndModify command. (MongoDB > 1.3.0)
618
618
  #
619
- # @option opts [Hash] :query ({}) a query selector document for matching the desired document.
620
- # @option opts [Hash] :update (nil) the update operation to perform on the matched document.
621
- # @option opts [Array, String, OrderedHash] :sort ({}) specify a sort option for the query using any
622
- # of the sort options available for Cursor#sort. Sort order is important if the query will be matching
623
- # multiple documents since only the first matching document will be updated and returned.
624
- # @option opts [Boolean] :remove (false) If true, removes the the returned document from the collection.
625
- # @option opts [Boolean] :new (false) If true, returns the updated document; otherwise, returns the document
626
- # prior to update.
619
+ # @option opts [Hash] :query ({}) a query selector document for matching
620
+ # the desired document.
621
+ # @option opts [Hash] :update (nil) the update operation to perform on the
622
+ # matched document.
623
+ # @option opts [Array, String, OrderedHash] :sort ({}) specify a sort
624
+ # option for the query using any
625
+ # of the sort options available for Cursor#sort. Sort order is important
626
+ # if the query will be matching multiple documents since only the first
627
+ # matching document will be updated and returned.
628
+ # @option opts [Boolean] :remove (false) If true, removes the the returned
629
+ # document from the collection.
630
+ # @option opts [Boolean] :new (false) If true, returns the updated
631
+ # document; otherwise, returns the document prior to update.
632
+ # @option opts [Boolean] :full_response (false) If true, returns the entire
633
+ # response object from the server including 'ok' and 'lastErrorObject'.
627
634
  #
628
635
  # @return [Hash] the matched document.
629
636
  #
630
637
  # @core findandmodify find_and_modify-instance_method
631
638
  def find_and_modify(opts={})
639
+ full_response = opts.delete(:full_response)
640
+
632
641
  cmd = BSON::OrderedHash.new
633
642
  cmd[:findandmodify] = @name
634
643
  cmd.merge!(opts)
635
- cmd[:sort] = Mongo::Support.format_order_clause(opts[:sort]) if opts[:sort]
636
644
 
637
- @db.command(cmd)['value']
645
+ cmd[:sort] =
646
+ Mongo::Support.format_order_clause(opts[:sort]) if opts[:sort]
647
+
648
+ full_response ? @db.command(cmd) : @db.command(cmd)['value']
638
649
  end
639
650
 
640
651
  # Perform an aggregation using the aggregation framework on the current collection.
@@ -1098,8 +1109,7 @@ module Mongo
1098
1109
  def insert_batch(message, documents, write_concern, continue_on_error, errors, collection_name=@name)
1099
1110
  begin
1100
1111
  send_insert_message(message, documents, collection_name, write_concern)
1101
- rescue ConnectionFailure, OperationFailure, OperationTimeout, SystemStackError,
1102
- NoMemoryError, SystemCallError => ex
1112
+ rescue OperationFailure => ex
1103
1113
  raise ex unless continue_on_error
1104
1114
  errors << ex
1105
1115
  end
@@ -1159,7 +1169,7 @@ module Mongo
1159
1169
  insert_batch(message, docs_to_insert, write_concern, continue_on_error, errors, collection_name)
1160
1170
  # insert_batch collects errors if w > 0 and continue_on_error is true,
1161
1171
  # so raise the error here, as this is the last or only msg sent
1162
- raise errors.first unless errors.empty?
1172
+ raise errors.last unless errors.empty?
1163
1173
  end
1164
1174
 
1165
1175
  collect_on_error ? [inserted_ids, error_docs] : inserted_ids
@@ -117,7 +117,7 @@ module Mongo
117
117
  # @return [Hash, Nil] the next document or Nil if no documents remain.
118
118
  def next
119
119
  if @cache.length == 0
120
- if @query_run && (@options & OP_QUERY_EXHAUST != 0)
120
+ if @query_run && exhaust?
121
121
  close
122
122
  return nil
123
123
  else
@@ -224,6 +224,11 @@ module Mongo
224
224
  def limit(number_to_return=nil)
225
225
  return @limit unless number_to_return
226
226
  check_modifiable
227
+
228
+ if (number_to_return != 0) && exhaust?
229
+ raise MongoArgumentError, "Limit is incompatible with exhaust option."
230
+ end
231
+
227
232
  @limit = number_to_return
228
233
  self
229
234
  end
@@ -381,6 +386,14 @@ module Mongo
381
386
  def add_option(opt)
382
387
  check_modifiable
383
388
 
389
+ if exhaust?(opt)
390
+ if @limit != 0
391
+ raise MongoArgumentError, "Exhaust is incompatible with limit."
392
+ elsif @connection.mongos?
393
+ raise MongoArgumentError, "Exhaust is incompatible with mongos."
394
+ end
395
+ end
396
+
384
397
  @options |= opt
385
398
  @options
386
399
  end
@@ -447,7 +460,7 @@ module Mongo
447
460
  # Return the number of documents remaining for this cursor.
448
461
  def num_remaining
449
462
  if @cache.length == 0
450
- if @query_run && (@options & OP_QUERY_EXHAUST != 0)
463
+ if @query_run && exhaust?
451
464
  close
452
465
  return 0
453
466
  else
@@ -483,7 +496,7 @@ module Mongo
483
496
  socket = @socket || checkout_socket_from_connection
484
497
  results, @n_received, @cursor_id = @connection.receive_message(
485
498
  Mongo::Constants::OP_QUERY, message, nil, socket, @command,
486
- nil, @options & OP_QUERY_EXHAUST != 0)
499
+ nil, exhaust?)
487
500
  rescue ConnectionFailure => ex
488
501
  socket.close if socket
489
502
  @pool = nil
@@ -621,6 +634,13 @@ module Mongo
621
634
  end
622
635
  end
623
636
 
637
+ # Check whether the exhaust option is set
638
+ #
639
+ # @return [true, false] The state of the exhaust flag.
640
+ def exhaust?(opts = options)
641
+ !(opts & OP_QUERY_EXHAUST).zero?
642
+ end
643
+
624
644
  def check_modifiable
625
645
  if @query_run || @closed
626
646
  raise InvalidOperation, "Cannot modify the query once it has been run or closed."
@@ -30,7 +30,7 @@ module Mongo
30
30
  DEFAULT_HOST = 'localhost'
31
31
  DEFAULT_PORT = 27017
32
32
  DEFAULT_DB_NAME = 'test'
33
- GENERIC_OPTS = [:auths, :logger, :connect]
33
+ GENERIC_OPTS = [:auths, :logger, :connect, :default_db]
34
34
  TIMEOUT_OPTS = [:timeout, :op_timeout, :connect_timeout]
35
35
  SSL_OPTS = [:ssl, :ssl_key, :ssl_cert, :ssl_verify, :ssl_ca_cert]
36
36
  POOL_OPTS = [:pool_size, :pool_timeout]
@@ -199,7 +199,7 @@ module Mongo
199
199
  #
200
200
  # @return [Mongo::MongoClient, Mongo::MongoReplicaSetClient]
201
201
  def self.from_uri(uri = ENV['MONGODB_URI'], extra_opts={})
202
- parser = URIParser.new uri
202
+ parser = URIParser.new(uri)
203
203
  parser.connection(extra_opts)
204
204
  end
205
205
 
@@ -210,7 +210,7 @@ module Mongo
210
210
  raise MongoArgumentError,
211
211
  "ENV['MONGODB_URI'] implies a replica set."
212
212
  end
213
- opts.merge! parser.connection_options
213
+ opts.merge!(parser.connection_options)
214
214
  [parser.host, parser.port]
215
215
  else
216
216
  [host || DEFAULT_HOST, port || DEFAULT_PORT]
@@ -358,13 +358,7 @@ module Mongo
358
358
  # @return [Mongo::DB]
359
359
  #
360
360
  # @core databases db-instance_method
361
- def db(db_name=nil, opts={})
362
- if !db_name && uri = ENV['MONGODB_URI']
363
- db_name = uri[%r{/([^/\?]+)(\?|$)}, 1]
364
- end
365
-
366
- db_name ||= DEFAULT_DB_NAME
367
-
361
+ def db(db_name = @default_db, opts = {})
368
362
  DB.new(db_name, self, opts)
369
363
  end
370
364
 
@@ -689,6 +683,7 @@ module Mongo
689
683
  end
690
684
  Mongo::ReadPreference::validate(@read)
691
685
 
686
+ @default_db = opts.delete(:default_db) || DEFAULT_DB_NAME
692
687
  @tag_sets = opts.delete(:tag_sets) || []
693
688
  @acceptable_latency = opts.delete(:secondary_acceptable_latency_ms) || 15
694
689
 
@@ -208,7 +208,7 @@ module Mongo
208
208
  raise Mongo::OperationFailure, "Query response returned CURSOR_NOT_FOUND. " +
209
209
  "Either an invalid cursor was specified, or the cursor may have timed out on the server."
210
210
  elsif flags & Mongo::Constants::REPLY_QUERY_FAILURE != 0
211
- # Getting odd failures when a exception is raised here.
211
+ # Mongo query reply failures are handled in Cursor#next.
212
212
  end
213
213
  end
214
214
 
@@ -105,7 +105,14 @@ module Mongo
105
105
  @last_state = @config['ismaster'] ? :primary : :other
106
106
  end
107
107
 
108
- @config = @client['admin'].command({:ismaster => 1}, :socket => @socket)
108
+ if @client.connect_timeout
109
+ Timeout::timeout(@client.connect_timeout, OperationTimeout) do
110
+ @config = @client['admin'].command({:ismaster => 1}, :socket => @socket)
111
+ end
112
+ else
113
+ @config = @client['admin'].command({:ismaster => 1}, :socket => @socket)
114
+ end
115
+
109
116
  update_max_sizes
110
117
 
111
118
  if @config['msg']
@@ -13,11 +13,12 @@
13
13
  # limitations under the License.
14
14
 
15
15
  require 'cgi'
16
+ require 'uri'
16
17
 
17
18
  module Mongo
18
19
  class URIParser
19
20
 
20
- USER_REGEX = /([-.\w:]+)/
21
+ USER_REGEX = /(.+)/
21
22
  PASS_REGEX = /([^@,]+)/
22
23
  AUTH_REGEX = /(#{USER_REGEX}:#{PASS_REGEX}@)?/
23
24
 
@@ -108,7 +109,7 @@ module Mongo
108
109
  :w => lambda { |arg| Mongo::Support.is_i?(arg) ? arg.to_i : arg.to_sym },
109
110
  :wtimeout => lambda { |arg| arg.to_i },
110
111
  :wtimeoutms => lambda { |arg| arg.to_i }
111
- }
112
+ }
112
113
 
113
114
  attr_reader :auths,
114
115
  :connect,
@@ -253,6 +254,7 @@ module Mongo
253
254
  opts[:name] = replicaset
254
255
  end
255
256
 
257
+ opts[:default_db] = @db
256
258
  opts[:connect] = connect?
257
259
 
258
260
  opts
@@ -277,7 +279,7 @@ module Mongo
277
279
  uname = matches[2]
278
280
  pwd = matches[3]
279
281
  hosturis = matches[4].split(',')
280
- db = matches[8]
282
+ @db = matches[8]
281
283
 
282
284
  hosturis.each do |hosturi|
283
285
  # If port is present, use it, otherwise use default port
@@ -295,11 +297,16 @@ module Mongo
295
297
  raise MongoArgumentError, "No nodes specified. Please ensure that you've provided at least one node."
296
298
  end
297
299
 
298
- if uname && pwd && db
299
- auths << {:db_name => db, :username => uname, :password => pwd}
300
+ if uname && pwd && @db
301
+ auths << {
302
+ :db_name => @db,
303
+ :username => URI.unescape(uname),
304
+ :password => URI.unescape(pwd)
305
+ }
300
306
  elsif uname || pwd
301
- raise MongoArgumentError, "MongoDB URI must include username, password, "
302
- "and db if username and password are specified."
307
+ raise MongoArgumentError, 'MongoDB URI must include username, ' +
308
+ 'password, and db if username and ' +
309
+ 'password are specified.'
303
310
  end
304
311
  end
305
312
 
@@ -292,6 +292,18 @@ class TestCollection < Test::Unit::TestCase
292
292
  return conn.db(MONGO_TEST_DB)["test"]
293
293
  end
294
294
 
295
+ def test_non_operation_failure_halts_insertion_with_continue_on_error
296
+ coll = limited_collection
297
+ coll.stubs(:send_insert_message).raises(OperationTimeout).times(1)
298
+ docs = []
299
+ 10.times do
300
+ docs << {'foo' => 'a' * 950}
301
+ end
302
+ assert_raise OperationTimeout do
303
+ coll.insert(docs, :continue_on_error => true)
304
+ end
305
+ end
306
+
295
307
  def test_chunking_batch_insert
296
308
  docs = []
297
309
  10.times do
@@ -955,7 +967,9 @@ class TestCollection < Test::Unit::TestCase
955
967
  @@test << { :a => 2, :processed => false }
956
968
  @@test << { :a => 3, :processed => false }
957
969
 
958
- @@test.find_and_modify(:query => {}, :sort => [['a', -1]], :update => {"$set" => {:processed => true}})
970
+ @@test.find_and_modify(:query => {},
971
+ :sort => [['a', -1]],
972
+ :update => {"$set" => {:processed => true}})
959
973
 
960
974
  assert @@test.find_one({:a => 3})['processed']
961
975
  end
@@ -969,6 +983,21 @@ class TestCollection < Test::Unit::TestCase
969
983
  @@test.find_and_modify(:blimey => {})
970
984
  end
971
985
  end
986
+
987
+ def test_find_and_modify_with_full_response
988
+ @@test << { :a => 1, :processed => false }
989
+ @@test << { :a => 2, :processed => false }
990
+ @@test << { :a => 3, :processed => false }
991
+
992
+ doc = @@test.find_and_modify(:query => {},
993
+ :sort => [['a', -1]],
994
+ :update => {"$set" => {:processed => true}},
995
+ :full_response => true,
996
+ :new => true)
997
+
998
+ assert doc['value']['processed']
999
+ assert ['ok', 'value', 'lastErrorObject'].all? { |key| doc.key?(key) }
1000
+ end
972
1001
  end
973
1002
 
974
1003
  if @@version >= "1.3.5"
@@ -122,12 +122,24 @@ class TestConnection < Test::Unit::TestCase
122
122
  ENV['MONGODB_URI'] = "mongodb://#{host_port}/"
123
123
  con = MongoClient.from_uri
124
124
  db = con.db
125
- assert_equal db.name, Mongo::MongoClient::DEFAULT_DB_NAME
125
+ assert_equal db.name, MongoClient::DEFAULT_DB_NAME
126
126
  ensure
127
127
  ENV['MONGODB_URI'] = old_mongodb_uri
128
128
  end
129
129
  end
130
130
 
131
+ def test_db_from_uri_from_string_param
132
+ db_name = "_database"
133
+ db = MongoClient.from_uri("mongodb://#{host_port}/#{db_name}").db
134
+ assert_equal db.name, db_name
135
+ end
136
+
137
+ def test_db_from_uri_from_string_param_no_db_name
138
+ db = MongoClient.from_uri("mongodb://#{host_port}").db
139
+ assert_equal db.name, MongoClient::DEFAULT_DB_NAME
140
+ end
141
+
142
+
131
143
  def test_server_version
132
144
  assert_match(/\d\.\d+(\.\d+)?/, @client.server_version.to_s)
133
145
  end
@@ -91,6 +91,34 @@ class CursorTest < Test::Unit::TestCase
91
91
  end
92
92
  end
93
93
 
94
+ def test_exhaust_after_limit_error
95
+ c = Cursor.new(@@coll, :limit => 17)
96
+ assert_raise MongoArgumentError do
97
+ c.add_option(OP_QUERY_EXHAUST)
98
+ end
99
+
100
+ assert_raise MongoArgumentError do
101
+ c.add_option(OP_QUERY_EXHAUST + OP_QUERY_SLAVE_OK)
102
+ end
103
+ end
104
+
105
+ def test_limit_after_exhaust_error
106
+ c = Cursor.new(@@coll)
107
+ c.add_option(OP_QUERY_EXHAUST)
108
+ assert_raise MongoArgumentError do
109
+ c.limit(17)
110
+ end
111
+ end
112
+
113
+ def test_exhaust_with_mongos
114
+ @@connection.expects(:mongos?).returns(:true)
115
+ c = Cursor.new(@@coll)
116
+
117
+ assert_raise MongoArgumentError do
118
+ c.add_option(OP_QUERY_EXHAUST)
119
+ end
120
+ end
121
+
94
122
  def test_inspect
95
123
  selector = {:a => 1}
96
124
  cursor = @@coll.find(selector)
@@ -53,6 +53,18 @@ class URITest < Test::Unit::TestCase
53
53
  assert_equal "b:ob", parser.auths[0][:username]
54
54
  end
55
55
 
56
+ def test_username_with_encoded_symbol
57
+ parser = Mongo::URIParser.new('mongodb://f%40o:bar@localhost/admin')
58
+ username = parser.auths.first[:username]
59
+ assert_equal 'f@o', username
60
+ end
61
+
62
+ def test_password_with_encoded_symbol
63
+ parser = Mongo::URIParser.new('mongodb://foo:b%40r@localhost/admin')
64
+ password = parser.auths.first[:password]
65
+ assert_equal 'b@r', password
66
+ end
67
+
56
68
  def test_passwords_contain_no_commas
57
69
  assert_raise MongoArgumentError do
58
70
  Mongo::URIParser.new('mongodb://bob:a,b@a.example.com:27018/test')
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongo
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.9.1
4
+ version: 1.9.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tyler Brock
@@ -33,7 +33,7 @@ cert_chain:
33
33
  8v7zLF2XliYbfurYIwkcXs8yPn8ggApBIy9bX6VJxRs/l2+UvqzaHIFaFy/F8/GP
34
34
  RNTuXsVG5NDACo7Q
35
35
  -----END CERTIFICATE-----
36
- date: 2013-07-09 00:00:00.000000000 Z
36
+ date: 2013-08-21 00:00:00.000000000 Z
37
37
  dependencies:
38
38
  - !ruby/object:Gem::Dependency
39
39
  name: bson
@@ -41,14 +41,14 @@ dependencies:
41
41
  requirements:
42
42
  - - ~>
43
43
  - !ruby/object:Gem::Version
44
- version: 1.9.1
44
+ version: 1.9.2
45
45
  type: :runtime
46
46
  prerelease: false
47
47
  version_requirements: !ruby/object:Gem::Requirement
48
48
  requirements:
49
49
  - - ~>
50
50
  - !ruby/object:Gem::Version
51
- version: 1.9.1
51
+ version: 1.9.2
52
52
  description: A Ruby driver for MongoDB. For more information about Mongo, see http://www.mongodb.org.
53
53
  email: mongodb-dev@googlegroups.com
54
54
  executables:
@@ -171,7 +171,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
171
171
  version: '0'
172
172
  requirements: []
173
173
  rubyforge_project: mongo
174
- rubygems_version: 2.0.3
174
+ rubygems_version: 2.0.7
175
175
  signing_key:
176
176
  specification_version: 4
177
177
  summary: Ruby driver for MongoDB
metadata.gz.sig CHANGED
@@ -1 +1,2 @@
1
- tH�k#D�R&ۚ7�� 2�b��q�M���H��YT{���(7]�+�J���P�'3����[�����#R��-�hr�w�����VІii� 0�m�|��ŷR$��z�R�;���SL?����rW,o�*�Q�N��R ��=��WC|G`���
1
+ ����d��
2
+ ;5����ʼn_�]d�e��41E�.HR�g��v�鸁\