mongo 1.8.6 → 1.12.5

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.
Files changed (129) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/LICENSE +1 -1
  4. data/README.md +114 -282
  5. data/Rakefile +18 -4
  6. data/VERSION +1 -1
  7. data/bin/mongo_console +27 -5
  8. data/lib/mongo/bulk_write_collection_view.rb +387 -0
  9. data/lib/mongo/collection.rb +283 -222
  10. data/lib/mongo/collection_writer.rb +364 -0
  11. data/lib/mongo/{util → connection}/node.rb +58 -6
  12. data/lib/mongo/{util → connection}/pool.rb +61 -37
  13. data/lib/mongo/{util → connection}/pool_manager.rb +72 -22
  14. data/lib/mongo/{util → connection}/sharding_pool_manager.rb +13 -0
  15. data/lib/mongo/connection/socket/socket_util.rb +37 -0
  16. data/lib/mongo/connection/socket/ssl_socket.rb +95 -0
  17. data/lib/mongo/connection/socket/tcp_socket.rb +87 -0
  18. data/lib/mongo/connection/socket/unix_socket.rb +39 -0
  19. data/lib/mongo/connection/socket.rb +18 -0
  20. data/lib/mongo/connection.rb +19 -0
  21. data/lib/mongo/cursor.rb +183 -57
  22. data/lib/mongo/db.rb +302 -138
  23. data/lib/mongo/exception.rb +145 -0
  24. data/lib/mongo/functional/authentication.rb +455 -0
  25. data/lib/mongo/{util → functional}/logging.rb +23 -7
  26. data/lib/mongo/functional/read_preference.rb +183 -0
  27. data/lib/mongo/functional/scram.rb +556 -0
  28. data/lib/mongo/functional/uri_parser.rb +409 -0
  29. data/lib/mongo/{util → functional}/write_concern.rb +21 -9
  30. data/lib/mongo/functional.rb +20 -0
  31. data/lib/mongo/gridfs/grid.rb +19 -8
  32. data/lib/mongo/gridfs/grid_ext.rb +14 -0
  33. data/lib/mongo/gridfs/grid_file_system.rb +17 -4
  34. data/lib/mongo/gridfs/grid_io.rb +21 -9
  35. data/lib/mongo/gridfs.rb +18 -0
  36. data/lib/mongo/legacy.rb +76 -7
  37. data/lib/mongo/mongo_client.rb +246 -206
  38. data/lib/mongo/mongo_replica_set_client.rb +65 -15
  39. data/lib/mongo/mongo_sharded_client.rb +18 -3
  40. data/lib/mongo/networking.rb +47 -18
  41. data/lib/mongo/{util → utils}/conversions.rb +18 -3
  42. data/lib/mongo/{util → utils}/core_ext.rb +15 -32
  43. data/lib/mongo/{util → utils}/server_version.rb +15 -0
  44. data/lib/mongo/{util → utils}/support.rb +22 -55
  45. data/lib/mongo/utils/thread_local_variable_manager.rb +25 -0
  46. data/lib/mongo/utils.rb +19 -0
  47. data/lib/mongo.rb +44 -26
  48. data/mongo.gemspec +2 -2
  49. data/test/functional/authentication_test.rb +31 -10
  50. data/test/functional/bulk_api_stress_test.rb +133 -0
  51. data/test/functional/bulk_write_collection_view_test.rb +1198 -0
  52. data/test/functional/client_test.rb +627 -0
  53. data/test/functional/collection_test.rb +1419 -654
  54. data/test/functional/collection_writer_test.rb +83 -0
  55. data/test/functional/conversions_test.rb +46 -2
  56. data/test/functional/cursor_fail_test.rb +17 -9
  57. data/test/functional/cursor_message_test.rb +28 -15
  58. data/test/functional/cursor_test.rb +300 -165
  59. data/test/functional/db_api_test.rb +294 -264
  60. data/test/functional/db_connection_test.rb +15 -3
  61. data/test/functional/db_test.rb +165 -99
  62. data/test/functional/grid_file_system_test.rb +124 -112
  63. data/test/functional/grid_io_test.rb +17 -3
  64. data/test/functional/grid_test.rb +16 -2
  65. data/test/functional/pool_test.rb +99 -10
  66. data/test/functional/safe_test.rb +18 -4
  67. data/test/functional/ssl_test.rb +29 -0
  68. data/test/functional/support_test.rb +14 -0
  69. data/test/functional/timeout_test.rb +27 -27
  70. data/test/functional/uri_test.rb +268 -22
  71. data/test/functional/write_concern_test.rb +19 -5
  72. data/test/helpers/general.rb +50 -0
  73. data/test/helpers/test_unit.rb +476 -0
  74. data/test/replica_set/authentication_test.rb +28 -11
  75. data/test/replica_set/basic_test.rb +79 -23
  76. data/test/replica_set/client_test.rb +253 -124
  77. data/test/replica_set/connection_test.rb +59 -37
  78. data/test/replica_set/count_test.rb +18 -2
  79. data/test/replica_set/cursor_test.rb +30 -8
  80. data/test/replica_set/insert_test.rb +109 -2
  81. data/test/replica_set/max_values_test.rb +85 -10
  82. data/test/replica_set/pinning_test.rb +66 -2
  83. data/test/replica_set/query_test.rb +17 -3
  84. data/test/replica_set/read_preference_test.rb +115 -96
  85. data/test/replica_set/refresh_test.rb +59 -9
  86. data/test/replica_set/replication_ack_test.rb +32 -11
  87. data/test/replica_set/ssl_test.rb +32 -0
  88. data/test/sharded_cluster/basic_test.rb +73 -25
  89. data/test/shared/authentication/basic_auth_shared.rb +260 -0
  90. data/test/shared/authentication/bulk_api_auth_shared.rb +249 -0
  91. data/test/shared/authentication/gssapi_shared.rb +176 -0
  92. data/test/shared/authentication/sasl_plain_shared.rb +96 -0
  93. data/test/shared/authentication/scram_shared.rb +92 -0
  94. data/test/shared/ssl_shared.rb +235 -0
  95. data/test/test_helper.rb +47 -196
  96. data/test/threading/basic_test.rb +42 -2
  97. data/test/tools/mongo_config.rb +175 -35
  98. data/test/tools/mongo_config_test.rb +15 -1
  99. data/test/unit/client_test.rb +186 -57
  100. data/test/unit/collection_test.rb +44 -54
  101. data/test/unit/connection_test.rb +160 -71
  102. data/test/unit/cursor_test.rb +37 -3
  103. data/test/unit/db_test.rb +38 -14
  104. data/test/unit/grid_test.rb +15 -1
  105. data/test/unit/mongo_sharded_client_test.rb +30 -14
  106. data/test/unit/node_test.rb +16 -1
  107. data/test/unit/pool_manager_test.rb +21 -4
  108. data/test/unit/read_pref_test.rb +386 -1
  109. data/test/unit/read_test.rb +27 -13
  110. data/test/unit/safe_test.rb +22 -8
  111. data/test/unit/sharding_pool_manager_test.rb +25 -4
  112. data/test/unit/write_concern_test.rb +23 -9
  113. data.tar.gz.sig +0 -0
  114. metadata +80 -54
  115. metadata.gz.sig +0 -0
  116. data/lib/mongo/exceptions.rb +0 -65
  117. data/lib/mongo/util/read_preference.rb +0 -112
  118. data/lib/mongo/util/socket_util.rb +0 -20
  119. data/lib/mongo/util/ssl_socket.rb +0 -51
  120. data/lib/mongo/util/tcp_socket.rb +0 -62
  121. data/lib/mongo/util/thread_local_variable_manager.rb +0 -11
  122. data/lib/mongo/util/unix_socket.rb +0 -23
  123. data/lib/mongo/util/uri_parser.rb +0 -337
  124. data/test/functional/connection_test.rb +0 -449
  125. data/test/functional/threading_test.rb +0 -95
  126. data/test/replica_set/complex_connect_test.rb +0 -64
  127. data/test/shared/authentication.rb +0 -66
  128. data/test/unit/pool_test.rb +0 -9
  129. data/test/unit/util_test.rb +0 -55
@@ -1,23 +0,0 @@
1
- require 'socket'
2
-
3
- module Mongo
4
- # Wrapper class for Socket
5
- #
6
- # Emulates UNIXSocket with operation and connection timeout
7
- # sans Timeout::timeout
8
- #
9
- class UNIXSocket < TCPSocket
10
- def initialize(socket_path, port=:socket, op_timeout=nil, connect_timeout=nil)
11
- @op_timeout = op_timeout
12
- @connect_timeout = connect_timeout
13
-
14
- @address = socket_path
15
- @port = :socket # purposely override input
16
-
17
- @socket_address = Socket.pack_sockaddr_un(@address)
18
- @socket = Socket.new(Socket::AF_UNIX, Socket::SOCK_STREAM, 0)
19
- connect
20
- end
21
- end
22
- end
23
-
@@ -1,337 +0,0 @@
1
- require 'cgi'
2
-
3
- module Mongo
4
- class URIParser
5
-
6
- USER_REGEX = /([-.\w:]+)/
7
- PASS_REGEX = /([^@,]+)/
8
- AUTH_REGEX = /(#{USER_REGEX}:#{PASS_REGEX}@)?/
9
-
10
- HOST_REGEX = /([-.\w]+)/
11
- PORT_REGEX = /(?::(\w+))?/
12
- NODE_REGEX = /((#{HOST_REGEX}#{PORT_REGEX},?)+)/
13
-
14
- PATH_REGEX = /(?:\/([-\w]+))?/
15
-
16
- MONGODB_URI_MATCHER = /#{AUTH_REGEX}#{NODE_REGEX}#{PATH_REGEX}/
17
- MONGODB_URI_SPEC = "mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]"
18
-
19
- SPEC_ATTRS = [:nodes, :auths]
20
-
21
- READ_PREFERENCES = {
22
- "primary" => :primary,
23
- "primarypreferred" => :primary_preferred,
24
- "secondary" => :secondary,
25
- "secondarypreferred" => :secondary_preferred,
26
- "nearest" => :nearest
27
- }
28
-
29
- OPT_ATTRS = [
30
- :connect,
31
- :connecttimeoutms,
32
- :fsync,
33
- :journal,
34
- :pool_size,
35
- :readpreference,
36
- :replicaset,
37
- :safe,
38
- :slaveok,
39
- :sockettimeoutms,
40
- :ssl,
41
- :w,
42
- :wtimeout,
43
- :wtimeoutms
44
- ]
45
-
46
- OPT_VALID = {
47
- :connect => lambda { |arg| [ 'direct', 'replicaset', 'true', 'false', true, false ].include?(arg) },
48
- :connecttimeoutms => lambda { |arg| arg =~ /^\d+$/ },
49
- :fsync => lambda { |arg| ['true', 'false'].include?(arg) },
50
- :journal => lambda { |arg| ['true', 'false'].include?(arg) },
51
- :pool_size => lambda { |arg| arg.to_i > 0 },
52
- :readpreference => lambda { |arg| READ_PREFERENCES.keys.include?(arg) },
53
- :replicaset => lambda { |arg| arg.length > 0 },
54
- :safe => lambda { |arg| ['true', 'false'].include?(arg) },
55
- :slaveok => lambda { |arg| ['true', 'false'].include?(arg) },
56
- :sockettimeoutms => lambda { |arg| arg =~ /^\d+$/ },
57
- :ssl => lambda { |arg| ['true', 'false'].include?(arg) },
58
- :w => lambda { |arg| arg =~ /^\w+$/ },
59
- :wtimeout => lambda { |arg| arg =~ /^\d+$/ },
60
- :wtimeoutms => lambda { |arg| arg =~ /^\d+$/ }
61
- }
62
-
63
- OPT_ERR = {
64
- :connect => "must be 'direct', 'replicaset', 'true', or 'false'",
65
- :connecttimeoutms => "must be an integer specifying milliseconds",
66
- :fsync => "must be 'true' or 'false'",
67
- :journal => "must be 'true' or 'false'",
68
- :pool_size => "must be an integer greater than zero",
69
- :readpreference => "must be on of #{READ_PREFERENCES.keys.map(&:inspect).join(",")}",
70
- :replicaset => "must be a string containing the name of the replica set to connect to",
71
- :safe => "must be 'true' or 'false'",
72
- :slaveok => "must be 'true' or 'false'",
73
- :sockettimeoutms => "must be an integer specifying milliseconds",
74
- :ssl => "must be 'true' or 'false'",
75
- :w => "must be an integer indicating number of nodes to replicate to or a string " +
76
- "specifying that replication is required to the majority or nodes with a " +
77
- "particilar getLastErrorMode.",
78
- :wtimeout => "must be an integer specifying milliseconds",
79
- :wtimeoutms => "must be an integer specifying milliseconds"
80
- }
81
-
82
- OPT_CONV = {
83
- :connect => lambda { |arg| arg == 'false' ? false : arg }, # convert 'false' to FalseClass
84
- :connecttimeoutms => lambda { |arg| arg.to_f / 1000 }, # stored as seconds
85
- :fsync => lambda { |arg| arg == 'true' ? true : false },
86
- :journal => lambda { |arg| arg == 'true' ? true : false },
87
- :pool_size => lambda { |arg| arg.to_i },
88
- :readpreference => lambda { |arg| READ_PREFERENCES[arg] },
89
- :replicaset => lambda { |arg| arg },
90
- :safe => lambda { |arg| arg == 'true' ? true : false },
91
- :slaveok => lambda { |arg| arg == 'true' ? true : false },
92
- :sockettimeoutms => lambda { |arg| arg.to_f / 1000 }, # stored as seconds
93
- :ssl => lambda { |arg| arg == 'true' ? true : false },
94
- :w => lambda { |arg| Mongo::Support.is_i?(arg) ? arg.to_i : arg.to_sym },
95
- :wtimeout => lambda { |arg| arg.to_i },
96
- :wtimeoutms => lambda { |arg| arg.to_i }
97
- }
98
-
99
- attr_reader :auths,
100
- :connect,
101
- :connecttimeoutms,
102
- :fsync,
103
- :journal,
104
- :nodes,
105
- :pool_size,
106
- :readpreference,
107
- :replicaset,
108
- :safe,
109
- :slaveok,
110
- :sockettimeoutms,
111
- :ssl,
112
- :w,
113
- :wtimeout,
114
- :wtimeoutms
115
-
116
- # Parse a MongoDB URI. This method is used by MongoClient.from_uri.
117
- # Returns an array of nodes and an array of db authorizations, if applicable.
118
- #
119
- # @note Passwords can contain any character except for ','
120
- #
121
- # @param [String] uri The MongoDB URI string.
122
- # @param [Hash,nil] extra_opts Extra options. Will override anything already specified in the URI.
123
- #
124
- # @core connections
125
- def initialize(uri)
126
- if uri.start_with?('mongodb://')
127
- uri = uri[10..-1]
128
- else
129
- raise MongoArgumentError, "MongoDB URI must match this spec: #{MONGODB_URI_SPEC}"
130
- end
131
-
132
- hosts, opts = uri.split('?')
133
- parse_hosts(hosts)
134
- parse_options(opts)
135
- validate_connect
136
- end
137
-
138
- # Create a Mongo::MongoClient or a Mongo::MongoReplicaSetClient based on the URI.
139
- #
140
- # @note Don't confuse this with attribute getter method #connect.
141
- #
142
- # @return [MongoClient,MongoReplicaSetClient]
143
- def connection(extra_opts, legacy = false, sharded = false)
144
- opts = connection_options.merge!(extra_opts)
145
- if(legacy)
146
- if replicaset?
147
- ReplSetConnection.new(node_strings, opts)
148
- else
149
- Connection.new(host, port, opts)
150
- end
151
- else
152
- if sharded
153
- MongoShardedClient.new(node_strings, opts)
154
- elsif replicaset?
155
- MongoReplicaSetClient.new(node_strings, opts)
156
- else
157
- MongoClient.new(host, port, opts)
158
- end
159
- end
160
- end
161
-
162
- # Whether this represents a replica set.
163
- # @return [true,false]
164
- def replicaset?
165
- replicaset.is_a?(String) || nodes.length > 1
166
- end
167
-
168
- # Whether to immediately connect to the MongoDB node[s]. Defaults to true.
169
- # @return [true, false]
170
- def connect?
171
- connect != false
172
- end
173
-
174
- # Whether this represents a direct connection.
175
- #
176
- # @note Specifying :connect => 'direct' has no effect... other than to raise an exception if other variables suggest a replicaset.
177
- #
178
- # @return [true,false]
179
- def direct?
180
- !replicaset?
181
- end
182
-
183
- # For direct connections, the host of the (only) node.
184
- # @return [String]
185
- def host
186
- nodes[0][0]
187
- end
188
-
189
- # For direct connections, the port of the (only) node.
190
- # @return [Integer]
191
- def port
192
- nodes[0][1].to_i
193
- end
194
-
195
- # Options that can be passed to MongoClient.new or MongoReplicaSetClient.new
196
- # @return [Hash]
197
- def connection_options
198
- opts = {}
199
-
200
- if @wtimeout
201
- warn "Using wtimeout in a URI is deprecated, please use wtimeoutMS. It will be removed in v2.0."
202
- opts[:wtimeout] = @wtimeout
203
- end
204
- opts[:wtimeout] = @wtimeoutms
205
-
206
- opts[:w] = 1 if @safe
207
- opts[:w] = @w if @w
208
- opts[:j] = @journal
209
- opts[:fsync] = @fsync
210
-
211
- if @connecttimeoutms
212
- opts[:connect_timeout] = @connecttimeoutms
213
- end
214
-
215
- if @sockettimeoutms
216
- opts[:op_timeout] = @sockettimeoutms
217
- end
218
-
219
- if @pool_size
220
- opts[:pool_size] = @pool_size
221
- end
222
-
223
- if @readpreference
224
- opts[:read] = @readpreference
225
- end
226
-
227
- if @slaveok && !@readpreference
228
- if direct?
229
- opts[:slave_ok] = true
230
- else
231
- opts[:read] = :secondary_preferred
232
- end
233
- end
234
-
235
- opts[:ssl] = @ssl
236
-
237
- if direct?
238
- opts[:auths] = auths
239
- end
240
-
241
- if replicaset.is_a?(String)
242
- opts[:name] = replicaset
243
- end
244
-
245
- opts[:connect] = connect?
246
-
247
- opts
248
- end
249
-
250
- def node_strings
251
- nodes.map { |node| node.join(':') }
252
- end
253
-
254
- private
255
-
256
- def parse_hosts(uri_without_proto)
257
- @nodes = []
258
- @auths = []
259
-
260
- matches = MONGODB_URI_MATCHER.match(uri_without_proto)
261
-
262
- if !matches
263
- raise MongoArgumentError, "MongoDB URI must match this spec: #{MONGODB_URI_SPEC}"
264
- end
265
-
266
- uname = matches[2]
267
- pwd = matches[3]
268
- hosturis = matches[4].split(',')
269
- db = matches[8]
270
-
271
- hosturis.each do |hosturi|
272
- # If port is present, use it, otherwise use default port
273
- host, port = hosturi.split(':') + [MongoClient::DEFAULT_PORT]
274
-
275
- if !(port.to_s =~ /^\d+$/)
276
- raise MongoArgumentError, "Invalid port #{port}; port must be specified as digits."
277
- end
278
-
279
- port = port.to_i
280
- @nodes << [host, port]
281
- end
282
-
283
- if @nodes.empty?
284
- raise MongoArgumentError, "No nodes specified. Please ensure that you've provided at least one node."
285
- end
286
-
287
- if uname && pwd && db
288
- auths << {:db_name => db, :username => uname, :password => pwd}
289
- elsif uname || pwd
290
- raise MongoArgumentError, "MongoDB URI must include username, password, "
291
- "and db if username and password are specified."
292
- end
293
-
294
- # The auths are repeated for each host in a replica set
295
- @auths *= hosturis.length
296
- end
297
-
298
- # This method uses the lambdas defined in OPT_VALID and OPT_CONV to validate
299
- # and convert the given options.
300
- def parse_options(string_opts)
301
- # initialize instance variables for available options
302
- OPT_VALID.keys.each { |k| instance_variable_set("@#{k}", nil) }
303
-
304
- string_opts ||= ''
305
-
306
- return if string_opts.empty?
307
-
308
- if string_opts.include?(';') and string_opts.include?('&')
309
- raise MongoArgumentError, "must not mix URL separators ; and &"
310
- end
311
-
312
- opts = CGI.parse(string_opts).inject({}) do |memo, (key, value)|
313
- value = value.first
314
- memo[key.downcase.to_sym] = value.strip.downcase
315
- memo
316
- end
317
-
318
- opts.each do |key, value|
319
- if !OPT_ATTRS.include?(key)
320
- raise MongoArgumentError, "Invalid Mongo URI option #{key}"
321
- end
322
- if OPT_VALID[key].call(value)
323
- instance_variable_set("@#{key}", OPT_CONV[key].call(value))
324
- else
325
- raise MongoArgumentError, "Invalid value #{value.inspect} for #{key}: #{OPT_ERR[key]}"
326
- end
327
- end
328
- end
329
-
330
- def validate_connect
331
- if replicaset? and @connect == 'direct'
332
- # Make sure the user doesn't specify something contradictory
333
- raise MongoArgumentError, "connect=direct conflicts with setting a replicaset name"
334
- end
335
- end
336
- end
337
- end