mongo 2.1.0.beta → 2.1.0.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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/Rakefile +2 -2
- data/lib/mongo.rb +2 -3
- data/lib/mongo/address.rb +7 -5
- data/lib/mongo/address/unix.rb +2 -2
- data/lib/mongo/auth/ldap/conversation.rb +6 -2
- data/lib/mongo/auth/scram/conversation.rb +8 -2
- data/lib/mongo/auth/user/view.rb +21 -0
- data/lib/mongo/bulk_write.rb +155 -23
- data/lib/mongo/bulk_write/combineable.rb +51 -0
- data/lib/mongo/bulk_write/ordered_combiner.rb +55 -0
- data/lib/mongo/bulk_write/result.rb +61 -8
- data/lib/mongo/bulk_write/result_combiner.rb +117 -0
- data/lib/mongo/bulk_write/transformable.rb +117 -0
- data/lib/mongo/bulk_write/unordered_combiner.rb +52 -0
- data/lib/mongo/bulk_write/validatable.rb +62 -0
- data/lib/mongo/client.rb +7 -3
- data/lib/mongo/cluster.rb +3 -3
- data/lib/mongo/cluster/topology/replica_set.rb +8 -6
- data/lib/mongo/cluster/topology/unknown.rb +5 -2
- data/lib/mongo/collection.rb +75 -4
- data/lib/mongo/collection/view.rb +1 -2
- data/lib/mongo/collection/view/aggregation.rb +13 -8
- data/lib/mongo/collection/view/immutable.rb +6 -6
- data/lib/mongo/collection/view/iterable.rb +13 -4
- data/lib/mongo/collection/view/map_reduce.rb +22 -17
- data/lib/mongo/collection/view/readable.rb +121 -70
- data/lib/mongo/cursor.rb +5 -1
- data/lib/mongo/database.rb +3 -3
- data/lib/mongo/database/view.rb +1 -1
- data/lib/mongo/error.rb +7 -0
- data/lib/mongo/{bulk_write/unordered_bulk_write.rb → error/closed_stream.rb} +12 -21
- data/lib/mongo/{bulk_write/ordered_bulk_write.rb → error/extra_file_chunk.rb} +13 -27
- data/lib/mongo/error/file_not_found.rb +37 -0
- data/lib/mongo/error/invalid_file.rb +2 -2
- data/lib/mongo/error/invalid_file_revision.rb +37 -0
- data/lib/mongo/error/invalid_uri.rb +5 -4
- data/lib/mongo/error/missing_file_chunk.rb +38 -0
- data/lib/mongo/error/operation_failure.rb +1 -1
- data/lib/mongo/error/unchangeable_collection_option.rb +38 -0
- data/lib/mongo/error/unexpected_chunk_length.rb +39 -0
- data/lib/mongo/grid.rb +2 -1
- data/lib/mongo/grid/file.rb +12 -9
- data/lib/mongo/grid/file/chunk.rb +6 -6
- data/lib/mongo/grid/file/{metadata.rb → info.rb} +41 -39
- data/lib/mongo/grid/fs_bucket.rb +441 -0
- data/lib/mongo/grid/stream.rb +64 -0
- data/lib/mongo/grid/stream/read.rb +208 -0
- data/lib/mongo/grid/stream/write.rb +187 -0
- data/lib/mongo/index/view.rb +1 -1
- data/lib/mongo/loggable.rb +34 -57
- data/lib/mongo/logger.rb +16 -78
- data/lib/mongo/monitoring.rb +1 -5
- data/lib/mongo/monitoring/command_log_subscriber.rb +35 -17
- data/lib/mongo/monitoring/event/command_succeeded.rb +20 -1
- data/lib/mongo/monitoring/publishable.rb +22 -12
- data/lib/mongo/operation.rb +3 -6
- data/lib/mongo/operation/commands.rb +24 -0
- data/lib/mongo/operation/{aggregate.rb → commands/aggregate.rb} +3 -41
- data/lib/mongo/operation/{aggregate → commands/aggregate}/result.rb +0 -0
- data/lib/mongo/operation/commands/collections_info.rb +66 -0
- data/lib/mongo/operation/{command.rb → commands/command.rb} +2 -18
- data/lib/mongo/operation/commands/indexes.rb +70 -0
- data/lib/mongo/operation/commands/list_collections.rb +54 -0
- data/lib/mongo/operation/commands/list_collections/result.rb +112 -0
- data/lib/mongo/operation/commands/list_indexes.rb +56 -0
- data/lib/mongo/operation/commands/list_indexes/result.rb +115 -0
- data/lib/mongo/operation/{map_reduce.rb → commands/map_reduce.rb} +3 -41
- data/lib/mongo/operation/{map_reduce → commands/map_reduce}/result.rb +0 -0
- data/lib/mongo/operation/{parallel_scan.rb → commands/parallel_scan.rb} +3 -23
- data/lib/mongo/operation/{parallel_scan → commands/parallel_scan}/result.rb +0 -0
- data/lib/mongo/operation/commands/user_query.rb +69 -0
- data/lib/mongo/operation/commands/users_info.rb +53 -0
- data/lib/mongo/operation/commands/users_info/result.rb +36 -0
- data/lib/mongo/operation/executable.rb +4 -68
- data/lib/mongo/operation/kill_cursors.rb +3 -3
- data/lib/mongo/operation/read.rb +0 -4
- data/lib/mongo/operation/read/get_more.rb +2 -22
- data/lib/mongo/operation/read/query.rb +2 -21
- data/lib/mongo/operation/{read_preferrable.rb → read_preference.rb} +3 -2
- data/lib/mongo/operation/specifiable.rb +24 -0
- data/lib/mongo/operation/write.rb +2 -0
- data/lib/mongo/operation/write/bulk.rb +6 -3
- data/lib/mongo/operation/write/bulk/bulkable.rb +82 -0
- data/lib/mongo/operation/write/bulk/delete.rb +71 -0
- data/lib/mongo/operation/write/bulk/delete/result.rb +74 -0
- data/lib/mongo/operation/write/bulk/insert.rb +96 -0
- data/lib/mongo/operation/write/bulk/insert/result.rb +129 -0
- data/lib/mongo/operation/write/bulk/legacy_mergable.rb +87 -0
- data/lib/mongo/operation/write/bulk/mergable.rb +71 -0
- data/lib/mongo/operation/write/bulk/update.rb +81 -0
- data/lib/mongo/operation/write/bulk/update/result.rb +174 -0
- data/lib/mongo/operation/write/command/create_index.rb +0 -1
- data/lib/mongo/operation/write/command/create_user.rb +0 -1
- data/lib/mongo/operation/write/command/delete.rb +0 -1
- data/lib/mongo/operation/write/command/drop_index.rb +0 -1
- data/lib/mongo/operation/write/command/insert.rb +0 -1
- data/lib/mongo/operation/write/command/remove_user.rb +0 -1
- data/lib/mongo/operation/write/command/update.rb +0 -1
- data/lib/mongo/operation/write/command/update_user.rb +0 -1
- data/lib/mongo/operation/write/command/writable.rb +13 -18
- data/lib/mongo/operation/write/create_index.rb +4 -27
- data/lib/mongo/operation/write/create_user.rb +4 -30
- data/lib/mongo/operation/write/delete.rb +5 -28
- data/lib/mongo/operation/write/drop_index.rb +3 -3
- data/lib/mongo/operation/write/gle.rb +48 -0
- data/lib/mongo/operation/write/idable.rb +5 -0
- data/lib/mongo/operation/write/insert.rb +2 -24
- data/lib/mongo/operation/write/remove_user.rb +4 -27
- data/lib/mongo/operation/write/update.rb +4 -32
- data/lib/mongo/operation/write/update_user.rb +4 -30
- data/lib/mongo/operation/write/write_command_enabled.rb +53 -0
- data/lib/mongo/options/mapper.rb +4 -2
- data/lib/mongo/protocol/delete.rb +68 -3
- data/lib/mongo/protocol/get_more.rb +54 -2
- data/lib/mongo/protocol/insert.rb +59 -1
- data/lib/mongo/protocol/kill_cursors.rb +53 -4
- data/lib/mongo/protocol/message.rb +12 -12
- data/lib/mongo/protocol/query.rb +139 -65
- data/lib/mongo/protocol/reply.rb +69 -1
- data/lib/mongo/protocol/update.rb +70 -1
- data/lib/mongo/server/connection.rb +11 -3
- data/lib/mongo/server/description.rb +29 -0
- data/lib/mongo/server/description/features.rb +2 -1
- data/lib/mongo/server/monitor.rb +2 -2
- data/lib/mongo/server_selector.rb +14 -10
- data/lib/mongo/server_selector/selectable.rb +24 -22
- data/lib/mongo/socket.rb +6 -3
- data/lib/mongo/socket/tcp.rb +2 -2
- data/lib/mongo/socket/unix.rb +5 -8
- data/lib/mongo/uri.rb +243 -139
- data/lib/mongo/version.rb +1 -1
- data/spec/mongo/address/unix_spec.rb +1 -1
- data/spec/mongo/address_spec.rb +25 -0
- data/spec/mongo/auth/ldap/conversation_spec.rb +43 -0
- data/spec/mongo/auth/user/view_spec.rb +26 -1
- data/spec/mongo/bulk_write/ordered_combiner_spec.rb +271 -0
- data/spec/mongo/bulk_write/unordered_combiner_spec.rb +239 -0
- data/spec/mongo/bulk_write_spec.rb +332 -166
- data/spec/mongo/client_spec.rb +25 -0
- data/spec/mongo/cluster/topology/replica_set_spec.rb +2 -0
- data/spec/mongo/collection/view/aggregation_spec.rb +65 -0
- data/spec/mongo/collection/view/immutable_spec.rb +103 -0
- data/spec/mongo/collection/view/map_reduce_spec.rb +98 -3
- data/spec/mongo/collection/view/readable_spec.rb +17 -30
- data/spec/mongo/collection/view_spec.rb +233 -7
- data/spec/mongo/collection_spec.rb +360 -18
- data/spec/mongo/command_monitoring_spec.rb +51 -0
- data/spec/mongo/connection_string_spec.rb +137 -0
- data/spec/mongo/database_spec.rb +27 -11
- data/spec/mongo/grid/file/chunk_spec.rb +5 -5
- data/spec/mongo/grid/file/{metadata_spec.rb → info_spec.rb} +29 -17
- data/spec/mongo/grid/file_spec.rb +8 -8
- data/spec/mongo/grid/fs_bucket_spec.rb +1020 -0
- data/spec/mongo/grid/stream/read_spec.rb +275 -0
- data/spec/mongo/grid/stream/write_spec.rb +440 -0
- data/spec/mongo/grid/stream_spec.rb +48 -0
- data/spec/mongo/gridfs_spec.rb +50 -0
- data/spec/mongo/logger_spec.rb +0 -40
- data/spec/mongo/monitoring/command_log_subscriber_spec.rb +76 -0
- data/spec/mongo/operation/{aggregate_spec.rb → commands/aggregate_spec.rb} +0 -42
- data/spec/mongo/operation/{read → commands}/collections_info_spec.rb +1 -1
- data/spec/mongo/operation/{command_spec.rb → commands/command_spec.rb} +0 -0
- data/spec/mongo/operation/{read → commands}/indexes_spec.rb +1 -1
- data/spec/mongo/operation/{map_reduce_spec.rb → commands/map_reduce_spec.rb} +0 -18
- data/spec/mongo/operation/kill_cursors_spec.rb +1 -1
- data/spec/mongo/operation/{read_preferrable_spec.rb → read_preference_spec.rb} +11 -11
- data/spec/mongo/operation/write/bulk/{bulk_delete_spec.rb → delete_spec.rb} +1 -12
- data/spec/mongo/operation/write/bulk/{bulk_insert_spec.rb → insert_spec.rb} +1 -12
- data/spec/mongo/operation/write/bulk/{bulk_update_spec.rb → update_spec.rb} +1 -12
- data/spec/mongo/operation/write/insert_spec.rb +0 -11
- data/spec/mongo/protocol/kill_cursors_spec.rb +5 -3
- data/spec/mongo/server/description_spec.rb +42 -0
- data/spec/mongo/server/monitor_spec.rb +21 -0
- data/spec/mongo/server_discovery_and_monitoring_spec.rb +1 -0
- data/spec/mongo/server_selection_spec.rb +3 -3
- data/spec/mongo/server_selector/nearest_spec.rb +34 -27
- data/spec/mongo/server_selector/primary_preferred_spec.rb +31 -30
- data/spec/mongo/server_selector/primary_spec.rb +14 -13
- data/spec/mongo/server_selector/secondary_preferred_spec.rb +27 -26
- data/spec/mongo/server_selector/secondary_spec.rb +23 -22
- data/spec/mongo/server_selector_spec.rb +87 -24
- data/spec/mongo/socket/unix_spec.rb +52 -0
- data/spec/mongo/uri_spec.rb +251 -39
- data/spec/spec_helper.rb +11 -4
- data/spec/support/authorization.rb +4 -5
- data/spec/support/command_monitoring.rb +365 -0
- data/spec/support/command_monitoring/bulkWrite.yml +73 -0
- data/spec/support/command_monitoring/command.yml +42 -0
- data/spec/support/command_monitoring/deleteMany.yml +55 -0
- data/spec/support/command_monitoring/deleteOne.yml +55 -0
- data/spec/support/command_monitoring/find.yml +219 -0
- data/spec/support/command_monitoring/insertMany.yml +81 -0
- data/spec/support/command_monitoring/insertOne.yml +51 -0
- data/spec/support/command_monitoring/updateMany.yml +67 -0
- data/spec/support/command_monitoring/updateOne.yml +95 -0
- data/spec/support/connection_string.rb +228 -0
- data/spec/support/connection_string_tests/invalid-uris.yml +193 -0
- data/spec/support/connection_string_tests/valid-auth.yml +256 -0
- data/spec/support/connection_string_tests/valid-host_identifiers.yml +121 -0
- data/spec/support/connection_string_tests/valid-options.yml +30 -0
- data/spec/support/connection_string_tests/valid-unix_socket-absolute.yml +197 -0
- data/spec/support/connection_string_tests/valid-unix_socket-relative.yml +213 -0
- data/spec/support/connection_string_tests/valid-warnings.yml +55 -0
- data/spec/support/crud.rb +3 -1
- data/spec/support/crud/read.rb +14 -10
- data/spec/support/crud/write.rb +36 -9
- data/spec/support/gridfs.rb +637 -0
- data/spec/support/gridfs_tests/delete.yml +157 -0
- data/spec/support/gridfs_tests/download.yml +210 -0
- data/spec/support/gridfs_tests/download_by_name.yml +113 -0
- data/spec/support/gridfs_tests/upload.yml +158 -0
- data/spec/support/sdam/rs/equal_electionids.yml +1 -2
- data/spec/support/sdam/rs/new_primary_new_electionid.yml +0 -3
- data/spec/support/sdam/rs/primary_mismatched_me.yml +37 -0
- data/spec/support/sdam/rs/primary_to_no_primary_mismatched_me.yml +75 -0
- data/spec/support/sdam/rs/secondary_mismatched_me.yml +37 -0
- data/spec/support/sdam/single/direct_connection_rsarbiter.yml +1 -1
- data/spec/support/sdam/single/direct_connection_rsprimary.yml +1 -1
- data/spec/support/sdam/single/direct_connection_rssecondary.yml +1 -1
- data/spec/support/sdam/single/direct_connection_slave.yml +1 -1
- data/spec/support/sdam/single/direct_connection_standalone.yml +1 -1
- data/spec/support/sdam/single/not_ok_response.yml +0 -1
- data/spec/support/server_discovery_and_monitoring.rb +3 -1
- data/spec/support/server_selection.rb +3 -1
- data/spec/support/shared/bulk_write.rb +192 -0
- data/spec/support/shared/server_selector.rb +21 -12
- metadata +147 -57
- metadata.gz.sig +0 -0
- data/lib/mongo/bulk_write/bulk_writable.rb +0 -252
- data/lib/mongo/bulk_write/deletable.rb +0 -57
- data/lib/mongo/bulk_write/insertable.rb +0 -49
- data/lib/mongo/bulk_write/replacable.rb +0 -58
- data/lib/mongo/bulk_write/updatable.rb +0 -69
- data/lib/mongo/grid/fs.rb +0 -146
- data/lib/mongo/operation/list_collections/result.rb +0 -114
- data/lib/mongo/operation/list_indexes/result.rb +0 -118
- data/lib/mongo/operation/read/collections_info.rb +0 -68
- data/lib/mongo/operation/read/indexes.rb +0 -69
- data/lib/mongo/operation/read/list_collections.rb +0 -76
- data/lib/mongo/operation/read/list_indexes.rb +0 -78
- data/lib/mongo/operation/write/bulk/bulk_delete.rb +0 -145
- data/lib/mongo/operation/write/bulk/bulk_delete/result.rb +0 -75
- data/lib/mongo/operation/write/bulk/bulk_insert.rb +0 -132
- data/lib/mongo/operation/write/bulk/bulk_insert/result.rb +0 -130
- data/lib/mongo/operation/write/bulk/bulk_mergable.rb +0 -67
- data/lib/mongo/operation/write/bulk/bulk_update.rb +0 -154
- data/lib/mongo/operation/write/bulk/bulk_update/result.rb +0 -174
- data/lib/mongo/operation/write/bulk/legacy_bulk_mergable.rb +0 -83
- data/spec/mongo/grid/fs_spec.rb +0 -160
- data/spec/mongo/loggable_spec.rb +0 -63
@@ -105,9 +105,12 @@ module Mongo
|
|
105
105
|
#
|
106
106
|
# @since 2.0.0
|
107
107
|
def dispatch(messages, operation_id = nil)
|
108
|
-
|
109
|
-
|
110
|
-
|
108
|
+
if monitoring.subscribers?(Monitoring::COMMAND)
|
109
|
+
publish_command(messages, operation_id || Monitoring.next_operation_id) do |msgs|
|
110
|
+
deliver(msgs)
|
111
|
+
end
|
112
|
+
else
|
113
|
+
deliver(messages)
|
111
114
|
end
|
112
115
|
end
|
113
116
|
|
@@ -138,6 +141,11 @@ module Mongo
|
|
138
141
|
|
139
142
|
private
|
140
143
|
|
144
|
+
def deliver(messages)
|
145
|
+
write(messages)
|
146
|
+
messages.last.replyable? ? read : nil
|
147
|
+
end
|
148
|
+
|
141
149
|
def setup_authentication!
|
142
150
|
if options[:user]
|
143
151
|
default_mechanism = @server.features.scram_sha_1_enabled? ? :scram : :mongodb_cr
|
@@ -84,6 +84,11 @@ module Mongo
|
|
84
84
|
# @since 2.0.0
|
85
85
|
MAX_WRITE_BATCH_SIZE = 'maxWriteBatchSize'.freeze
|
86
86
|
|
87
|
+
# Constant for reading the me field.
|
88
|
+
#
|
89
|
+
# @since 2.1.0
|
90
|
+
ME = 'me'.freeze
|
91
|
+
|
87
92
|
# Default max write batch size.
|
88
93
|
#
|
89
94
|
# @since 2.0.0
|
@@ -302,6 +307,18 @@ module Mongo
|
|
302
307
|
config[MIN_WIRE_VERSION] || LEGACY_WIRE_VERSION
|
303
308
|
end
|
304
309
|
|
310
|
+
# Get the me field value.
|
311
|
+
#
|
312
|
+
# @example Get the me field value.
|
313
|
+
# description.me
|
314
|
+
#
|
315
|
+
# @return [ String ] The me field.
|
316
|
+
#
|
317
|
+
# @since 2.1.0
|
318
|
+
def me
|
319
|
+
config[ME]
|
320
|
+
end
|
321
|
+
|
305
322
|
# Get the tags configured for the server.
|
306
323
|
#
|
307
324
|
# @example Get the tags.
|
@@ -511,6 +528,18 @@ module Mongo
|
|
511
528
|
!(standalone? || mongos?)
|
512
529
|
end
|
513
530
|
|
531
|
+
# Check if there is a mismatch between the address host and the me field.
|
532
|
+
#
|
533
|
+
# @example Check if there is a mismatch.
|
534
|
+
# description.me_mismatch?
|
535
|
+
#
|
536
|
+
# @return [ true, false ] If there is a mismatch between the me field and the address host.
|
537
|
+
#
|
538
|
+
# @since 2.0.6
|
539
|
+
def me_mismatch?
|
540
|
+
!!(address.to_s != me if me)
|
541
|
+
end
|
542
|
+
|
514
543
|
# Check equality of two descriptions.
|
515
544
|
#
|
516
545
|
# @example Check description equality.
|
data/lib/mongo/server/monitor.rb
CHANGED
@@ -140,7 +140,7 @@ module Mongo
|
|
140
140
|
#
|
141
141
|
# @since 2.0.0
|
142
142
|
def stop!
|
143
|
-
@thread.kill && @thread.stop?
|
143
|
+
connection.disconnect! && @thread.kill && @thread.stop?
|
144
144
|
end
|
145
145
|
|
146
146
|
# Restarts the server monitor unless the current thread is alive.
|
@@ -173,7 +173,7 @@ module Mongo
|
|
173
173
|
result = connection.dispatch([ ISMASTER ]).documents[0]
|
174
174
|
return result, calculate_average_round_trip_time(start)
|
175
175
|
rescue Exception => e
|
176
|
-
log_debug(
|
176
|
+
log_debug(e.message)
|
177
177
|
return {}, calculate_average_round_trip_time(start)
|
178
178
|
end
|
179
179
|
end
|
@@ -27,6 +27,17 @@ module Mongo
|
|
27
27
|
module ServerSelector
|
28
28
|
extend self
|
29
29
|
|
30
|
+
# The max latency in seconds between the closest server and other servers
|
31
|
+
# considered for selection.
|
32
|
+
#
|
33
|
+
# @since 2.0.0
|
34
|
+
LOCAL_THRESHOLD = 0.015.freeze
|
35
|
+
|
36
|
+
# How long to block for server selection before throwing an exception.
|
37
|
+
#
|
38
|
+
# @since 2.0.0
|
39
|
+
SERVER_SELECTION_TIMEOUT = 30.freeze
|
40
|
+
|
30
41
|
# Hash lookup for the selector classes based off the symbols
|
31
42
|
# provided in configuration.
|
32
43
|
#
|
@@ -43,20 +54,13 @@ module Mongo
|
|
43
54
|
#
|
44
55
|
# @example Get a server selector object for selecting a secondary with
|
45
56
|
# specific tag sets.
|
46
|
-
# Mongo::ServerSelector.get(
|
57
|
+
# Mongo::ServerSelector.get(:mode => :secondary, :tag_sets => [{'dc' => 'nyc'}])
|
47
58
|
#
|
48
59
|
# @param [ Hash ] preference The server preference.
|
49
|
-
# @param [ Hash ] options The preference options.
|
50
|
-
#
|
51
|
-
# @option preference :mode [ Symbol ] The preference mode.
|
52
|
-
# @option preference :tag_sets [ Array<Hash> ] The tag sets.
|
53
60
|
#
|
54
61
|
# @since 2.0.0
|
55
|
-
def get(preference = {}
|
56
|
-
PREFERENCES.fetch(preference[:mode] || :primary).new(
|
57
|
-
preference[:tag_sets] || [],
|
58
|
-
options
|
59
|
-
)
|
62
|
+
def get(preference = {})
|
63
|
+
PREFERENCES.fetch(preference[:mode] || :primary).new(preference)
|
60
64
|
end
|
61
65
|
end
|
62
66
|
end
|
@@ -20,17 +20,6 @@ module Mongo
|
|
20
20
|
# @since 2.0.0
|
21
21
|
module Selectable
|
22
22
|
|
23
|
-
# The max latency in seconds between the closest server and other servers
|
24
|
-
# considered for selection.
|
25
|
-
#
|
26
|
-
# @since 2.0.0
|
27
|
-
LOCAL_THRESHOLD = 0.015.freeze
|
28
|
-
|
29
|
-
# How long to block for server selection before throwing an exception.
|
30
|
-
#
|
31
|
-
# @since 2.0.0
|
32
|
-
SERVER_SELECTION_TIMEOUT = 30.freeze
|
33
|
-
|
34
23
|
# @return [ Hash ] options The options.
|
35
24
|
attr_reader :options
|
36
25
|
|
@@ -53,22 +42,27 @@ module Mongo
|
|
53
42
|
|
54
43
|
# Initialize the server selector.
|
55
44
|
#
|
56
|
-
# @example Initialize the
|
57
|
-
# Mongo::ServerSelector::Secondary.new([{
|
45
|
+
# @example Initialize the selector.
|
46
|
+
# Mongo::ServerSelector::Secondary.new(:tag_sets => [{'dc' => 'nyc'}])
|
58
47
|
#
|
59
48
|
# @example Initialize the preference with no options.
|
60
49
|
# Mongo::ServerSelector::Secondary.new
|
61
50
|
#
|
62
|
-
# @param [
|
51
|
+
# @param [ Hash ] options The server preference options.
|
52
|
+
#
|
53
|
+
# @option options [ Integer ] :server_selection_timeout The timeout in seconds
|
54
|
+
# for selecting a server.
|
63
55
|
#
|
64
|
-
# @
|
65
|
-
#
|
56
|
+
# @option options [ Integer ] :local_threshold The local threshold boundary for
|
57
|
+
# nearest selection in seconds.
|
58
|
+
#
|
59
|
+
# @raise [ Error::InvalidServerPreference ] If tag sets are specified
|
60
|
+
# but not allowed.
|
66
61
|
#
|
67
62
|
# @since 2.0.0
|
68
|
-
def initialize(
|
69
|
-
|
70
|
-
|
71
|
-
end
|
63
|
+
def initialize(options = {})
|
64
|
+
tag_sets = options[:tag_sets] || []
|
65
|
+
validate_tag_sets!(tag_sets)
|
72
66
|
@tag_sets = tag_sets
|
73
67
|
@options = options
|
74
68
|
end
|
@@ -109,7 +103,7 @@ module Mongo
|
|
109
103
|
# @since 2.0.0
|
110
104
|
def server_selection_timeout
|
111
105
|
@server_selection_timeout ||=
|
112
|
-
(options[:server_selection_timeout] || SERVER_SELECTION_TIMEOUT)
|
106
|
+
(options[:server_selection_timeout] || ServerSelector::SERVER_SELECTION_TIMEOUT)
|
113
107
|
end
|
114
108
|
|
115
109
|
# Get the local threshold boundary for nearest selection in seconds.
|
@@ -121,7 +115,7 @@ module Mongo
|
|
121
115
|
#
|
122
116
|
# @since 2.0.0
|
123
117
|
def local_threshold
|
124
|
-
@local_threshold ||= (options[:local_threshold] || LOCAL_THRESHOLD)
|
118
|
+
@local_threshold ||= (options[:local_threshold] || ServerSelector::LOCAL_THRESHOLD)
|
125
119
|
end
|
126
120
|
|
127
121
|
private
|
@@ -186,6 +180,14 @@ module Mongo
|
|
186
180
|
end
|
187
181
|
matches || []
|
188
182
|
end
|
183
|
+
|
184
|
+
private
|
185
|
+
|
186
|
+
def validate_tag_sets!(tag_sets)
|
187
|
+
if !tag_sets.all? { |set| set.empty? } && !tags_allowed?
|
188
|
+
raise Error::InvalidServerPreference.new(name)
|
189
|
+
end
|
190
|
+
end
|
189
191
|
end
|
190
192
|
end
|
191
193
|
end
|
data/lib/mongo/socket.rb
CHANGED
@@ -173,10 +173,13 @@ module Mongo
|
|
173
173
|
end
|
174
174
|
|
175
175
|
def set_socket_options(sock)
|
176
|
-
encoded_timeout = [ timeout, 0 ].pack(TIMEOUT_PACK)
|
177
176
|
sock.set_encoding(BSON::BINARY)
|
178
|
-
|
179
|
-
sock.
|
177
|
+
|
178
|
+
unless sock.is_a?(UNIXSocket) && BSON::Environment.jruby?
|
179
|
+
encoded_timeout = [ timeout, 0 ].pack(TIMEOUT_PACK)
|
180
|
+
sock.setsockopt(SOL_SOCKET, SO_RCVTIMEO, encoded_timeout)
|
181
|
+
sock.setsockopt(SOL_SOCKET, SO_SNDTIMEO, encoded_timeout)
|
182
|
+
end
|
180
183
|
end
|
181
184
|
|
182
185
|
def handle_errors
|
data/lib/mongo/socket/tcp.rb
CHANGED
@@ -51,8 +51,8 @@ module Mongo
|
|
51
51
|
# Initializes a new TCP socket.
|
52
52
|
#
|
53
53
|
# @example Create the TCP socket.
|
54
|
-
# TCP.new('::1', 27017, 30)
|
55
|
-
# TCP.new('127.0.0.1', 27017, 30)
|
54
|
+
# TCP.new('::1', 27017, 30, Socket::PF_INET)
|
55
|
+
# TCP.new('127.0.0.1', 27017, 30, Socket::PF_INET)
|
56
56
|
#
|
57
57
|
# @param [ String ] host The hostname or IP address.
|
58
58
|
# @param [ Integer ] port The port number.
|
data/lib/mongo/socket/unix.rb
CHANGED
@@ -38,25 +38,22 @@ module Mongo
|
|
38
38
|
#
|
39
39
|
# @since 2.0.0
|
40
40
|
def connect!
|
41
|
-
|
42
|
-
handle_errors { socket.connect(path) }
|
43
|
-
self
|
44
|
-
end
|
41
|
+
self
|
45
42
|
end
|
46
43
|
|
47
44
|
# Initializes a new Unix socket.
|
48
45
|
#
|
49
46
|
# @example Create the Unix socket.
|
50
|
-
# Unix.new('/path/to.sock',
|
47
|
+
# Unix.new('/path/to.sock', 5)
|
51
48
|
#
|
52
49
|
# @param [ String ] path The path.
|
53
50
|
# @param [ Float ] timeout The socket timeout value.
|
54
|
-
# @param [ Integer ] family The socket family.
|
55
51
|
#
|
56
52
|
# @since 2.0.0
|
57
|
-
def initialize(path, timeout
|
53
|
+
def initialize(path, timeout)
|
58
54
|
@path, @timeout = path, timeout
|
59
|
-
|
55
|
+
@socket = ::UNIXSocket.new(path)
|
56
|
+
set_socket_options(@socket)
|
60
57
|
end
|
61
58
|
end
|
62
59
|
end
|
data/lib/mongo/uri.rb
CHANGED
@@ -29,58 +29,116 @@ module Mongo
|
|
29
29
|
class URI
|
30
30
|
include Loggable
|
31
31
|
|
32
|
-
#
|
32
|
+
# The uri parser object options.
|
33
33
|
#
|
34
34
|
# @since 2.0.0
|
35
|
-
|
35
|
+
attr_reader :options
|
36
36
|
|
37
|
-
#
|
37
|
+
# The options specified in the uri.
|
38
38
|
#
|
39
|
-
# @since 2.
|
40
|
-
|
39
|
+
# @since 2.1.0
|
40
|
+
attr_reader :uri_options
|
41
41
|
|
42
|
-
#
|
42
|
+
# The servers specified in the uri.
|
43
43
|
#
|
44
44
|
# @since 2.0.0
|
45
|
-
|
45
|
+
attr_reader :servers
|
46
46
|
|
47
|
-
#
|
47
|
+
# Unsafe characters that must be urlencoded.
|
48
48
|
#
|
49
|
-
# @since 2.
|
50
|
-
|
49
|
+
# @since 2.1.0
|
50
|
+
UNSAFE = /[\:\/\+\@]/
|
51
51
|
|
52
|
-
#
|
52
|
+
# Unix socket suffix.
|
53
53
|
#
|
54
|
-
# @since 2.
|
55
|
-
|
54
|
+
# @since 2.1.0
|
55
|
+
UNIX_SOCKET = /.sock/
|
56
56
|
|
57
|
-
#
|
57
|
+
# The mongodb connection string scheme.
|
58
58
|
#
|
59
59
|
# @since 2.0.0
|
60
|
-
|
60
|
+
SCHEME = 'mongodb://'.freeze
|
61
61
|
|
62
|
-
#
|
62
|
+
# The character delimiting hosts.
|
63
63
|
#
|
64
|
-
# @since 2.
|
65
|
-
|
64
|
+
# @since 2.1.0
|
65
|
+
HOST_DELIM = ','.freeze
|
66
66
|
|
67
|
-
#
|
68
|
-
# be part of any MongoDB database name.
|
67
|
+
# The character separating a host and port.
|
69
68
|
#
|
70
|
-
# @since 2.
|
71
|
-
|
69
|
+
# @since 2.1.0
|
70
|
+
HOST_PORT_DELIM = ':'.freeze
|
72
71
|
|
73
|
-
#
|
74
|
-
# not allow for semicolon to be used to separate options.
|
72
|
+
# The character delimiting a database.
|
75
73
|
#
|
76
|
-
# @since 2.
|
77
|
-
|
74
|
+
# @since 2.1.0
|
75
|
+
DATABASE_DELIM = '/'.freeze
|
78
76
|
|
79
|
-
#
|
77
|
+
# The character delimiting options.
|
80
78
|
#
|
81
|
-
# @since 2.
|
82
|
-
|
79
|
+
# @since 2.1.0
|
80
|
+
URI_OPTS_DELIM = '?'.freeze
|
81
|
+
|
82
|
+
# The character delimiting multiple options.
|
83
|
+
#
|
84
|
+
# @since 2.1.0
|
85
|
+
INDIV_URI_OPTS_DELIM = '&'.freeze
|
86
|
+
|
87
|
+
# The character delimiting an option and its value.
|
88
|
+
#
|
89
|
+
# @since 2.1.0
|
90
|
+
URI_OPTS_VALUE_DELIM = '='.freeze
|
83
91
|
|
92
|
+
# The character separating a username from the password.
|
93
|
+
#
|
94
|
+
# @since 2.1.0
|
95
|
+
AUTH_USER_PWD_DELIM = ':'.freeze
|
96
|
+
|
97
|
+
# The character delimiting auth credentials.
|
98
|
+
#
|
99
|
+
# @since 2.1.0
|
100
|
+
AUTH_DELIM = '@'.freeze
|
101
|
+
|
102
|
+
# Error details for an invalid scheme.
|
103
|
+
#
|
104
|
+
# @since 2.1.0
|
105
|
+
INVALID_SCHEME = "Invalid scheme. Scheme must be '#{SCHEME}'".freeze
|
106
|
+
|
107
|
+
# Error details for an invalid options format.
|
108
|
+
#
|
109
|
+
# @since 2.1.0
|
110
|
+
INVALID_OPTS_VALUE_DELIM = "Options and their values must be delimited" +
|
111
|
+
" by '#{URI_OPTS_VALUE_DELIM}'".freeze
|
112
|
+
|
113
|
+
# Error details for an non-urlencoded user name or password.
|
114
|
+
#
|
115
|
+
# @since 2.1.0
|
116
|
+
UNESCAPED_USER_PWD = "User name and password must be urlencoded.".freeze
|
117
|
+
|
118
|
+
# Error details for a non-urlencoded unix socket path.
|
119
|
+
#
|
120
|
+
# @since 2.1.0
|
121
|
+
UNESCAPED_UNIX_SOCKET = "UNIX domain sockets must be urlencoded.".freeze
|
122
|
+
|
123
|
+
# Error details for a non-urlencoded auth databsae name.
|
124
|
+
#
|
125
|
+
# @since 2.1.0
|
126
|
+
UNESCAPED_DATABASE = "Auth database must be urlencoded.".freeze
|
127
|
+
|
128
|
+
# Error details for providing options without a database delimiter.
|
129
|
+
#
|
130
|
+
# @since 2.1.0
|
131
|
+
INVALID_OPTS_DELIM = "Database delimiter '#{DATABASE_DELIM}' must be present if options are specified.".freeze
|
132
|
+
|
133
|
+
# Error details for a missing host.
|
134
|
+
#
|
135
|
+
# @since 2.1.0
|
136
|
+
INVALID_HOST = "Missing host; at least one must be provided.".freeze
|
137
|
+
|
138
|
+
# Error details for an invalid port.
|
139
|
+
#
|
140
|
+
# @since 2.1.0
|
141
|
+
INVALID_PORT = "Invalid port. Port must be an integer greater than 0 and less than 65536".freeze
|
84
142
|
|
85
143
|
# MongoDB URI format specification.
|
86
144
|
#
|
@@ -113,32 +171,28 @@ module Mongo
|
|
113
171
|
'GSSAPI' => :gssapi
|
114
172
|
}.freeze
|
115
173
|
|
174
|
+
# Options that are allowed to appear more than once in the uri.
|
175
|
+
#
|
176
|
+
# @since 2.1.0
|
177
|
+
REPEATABLE_OPTIONS = [ :tag_sets ]
|
178
|
+
|
116
179
|
# Create the new uri from the provided string.
|
117
180
|
#
|
118
181
|
# @example Create the new URI.
|
119
182
|
# URI.new('mongodb://localhost:27017')
|
120
183
|
#
|
121
184
|
# @param [ String ] string The uri string.
|
185
|
+
# @param [ Hash ] options The options.
|
122
186
|
#
|
123
|
-
# @raise [
|
187
|
+
# @raise [ Error::InvalidURI ] If the uri does not match the spec.
|
124
188
|
#
|
125
189
|
# @since 2.0.0
|
126
|
-
def initialize(string)
|
190
|
+
def initialize(string, options = {})
|
127
191
|
@string = string
|
128
|
-
@
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
# Get the servers provided in the URI.
|
133
|
-
#
|
134
|
-
# @example Get the servers.
|
135
|
-
# uri.servers
|
136
|
-
#
|
137
|
-
# @return [ Array<String> ] The servers.
|
138
|
-
#
|
139
|
-
# @since 2.0.0
|
140
|
-
def servers
|
141
|
-
@match[3].split(',')
|
192
|
+
@options = options
|
193
|
+
empty, scheme, remaining = @string.partition(SCHEME)
|
194
|
+
raise_invalid_error!(INVALID_SCHEME) unless scheme == SCHEME
|
195
|
+
setup!(remaining)
|
142
196
|
end
|
143
197
|
|
144
198
|
# Gets the options hash that needs to be passed to a Mongo::Client on
|
@@ -152,8 +206,8 @@ module Mongo
|
|
152
206
|
#
|
153
207
|
# @since 2.0.0
|
154
208
|
def client_options
|
155
|
-
opts =
|
156
|
-
user ? opts.merge(credentials) : opts
|
209
|
+
opts = uri_options.merge(:database => database)
|
210
|
+
@user ? opts.merge(credentials) : opts
|
157
211
|
end
|
158
212
|
|
159
213
|
# Get the credentials provided in the URI.
|
@@ -167,7 +221,7 @@ module Mongo
|
|
167
221
|
#
|
168
222
|
# @since 2.0.0
|
169
223
|
def credentials
|
170
|
-
{ :user => user, :password => password }
|
224
|
+
{ :user => @user, :password => @password }
|
171
225
|
end
|
172
226
|
|
173
227
|
# Get the database provided in the URI.
|
@@ -179,115 +233,161 @@ module Mongo
|
|
179
233
|
#
|
180
234
|
# @since 2.0.0
|
181
235
|
def database
|
182
|
-
@
|
236
|
+
@database ? @database : Database::ADMIN
|
183
237
|
end
|
184
238
|
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
def
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
239
|
+
private
|
240
|
+
|
241
|
+
def setup!(remaining)
|
242
|
+
creds_hosts, db_opts = extract_db_opts!(remaining)
|
243
|
+
parse_creds_hosts!(creds_hosts)
|
244
|
+
parse_db_opts!(db_opts)
|
245
|
+
end
|
246
|
+
|
247
|
+
def extract_db_opts!(string)
|
248
|
+
db_opts, d, creds_hosts = string.reverse.partition(DATABASE_DELIM)
|
249
|
+
db_opts, creds_hosts = creds_hosts, db_opts if creds_hosts.empty?
|
250
|
+
if db_opts.empty? && creds_hosts.include?(URI_OPTS_DELIM)
|
251
|
+
raise_invalid_error!(INVALID_OPTS_DELIM)
|
252
|
+
end
|
253
|
+
[ creds_hosts, db_opts ].map { |s| s.reverse }
|
254
|
+
end
|
255
|
+
|
256
|
+
def parse_creds_hosts!(string)
|
257
|
+
hosts, creds = split_creds_hosts(string)
|
258
|
+
@servers = parse_servers!(hosts)
|
259
|
+
@user = parse_user!(creds)
|
260
|
+
@password = parse_password!(creds)
|
261
|
+
end
|
262
|
+
|
263
|
+
def split_creds_hosts(string)
|
264
|
+
hosts, d, creds = string.reverse.partition(AUTH_DELIM)
|
265
|
+
hosts, creds = creds, hosts if hosts.empty?
|
266
|
+
[ hosts, creds ].map { |s| s.reverse }
|
267
|
+
end
|
268
|
+
|
269
|
+
def parse_db_opts!(string)
|
270
|
+
auth_db, d, uri_opts = string.partition(URI_OPTS_DELIM)
|
271
|
+
@uri_options = parse_uri_options!(uri_opts)
|
272
|
+
@database = parse_database!(auth_db)
|
273
|
+
end
|
274
|
+
|
275
|
+
def parse_uri_options!(string)
|
276
|
+
return {} unless string
|
277
|
+
string.split(INDIV_URI_OPTS_DELIM).reduce({}) do |uri_options, opt|
|
278
|
+
raise_invalid_error!(INVALID_OPTS_VALUE_DELIM) unless opt.index(URI_OPTS_VALUE_DELIM)
|
279
|
+
key, value = opt.split(URI_OPTS_VALUE_DELIM)
|
280
|
+
strategy = URI_OPTION_MAP[key.downcase]
|
215
281
|
if strategy.nil?
|
216
|
-
log_warn(
|
217
|
-
"Unsupported URI option '#{key}' on URI '#{@string}'. It will be ignored."
|
218
|
-
])
|
282
|
+
log_warn("Unsupported URI option '#{key}' on URI '#{@string}'. It will be ignored.")
|
219
283
|
else
|
220
|
-
|
284
|
+
add_uri_option(strategy, value, uri_options)
|
221
285
|
end
|
222
|
-
|
286
|
+
uri_options
|
223
287
|
end
|
224
288
|
end
|
225
289
|
|
226
|
-
|
290
|
+
def parse_user!(string)
|
291
|
+
if (string && user = string.partition(AUTH_USER_PWD_DELIM)[0])
|
292
|
+
raise_invalid_error!(UNESCAPED_USER_PWD) if user =~ UNSAFE
|
293
|
+
decode(user) if user.length > 0
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
def parse_password!(string)
|
298
|
+
if (string && pwd = string.partition(AUTH_USER_PWD_DELIM)[2])
|
299
|
+
raise_invalid_error!(UNESCAPED_USER_PWD) if pwd =~ UNSAFE
|
300
|
+
decode(pwd) if pwd.length > 0
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
def parse_database!(string)
|
305
|
+
raise_invalid_error!(UNESCAPED_DATABASE) if string =~ UNSAFE
|
306
|
+
decode(string) if string.length > 0
|
307
|
+
end
|
308
|
+
|
309
|
+
def validate_port_string!(port)
|
310
|
+
unless port.nil? || (port.length > 0 && port.to_i > 0 && port.to_i <= 65535)
|
311
|
+
raise_invalid_error!(INVALID_PORT)
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
315
|
+
def parse_servers!(string)
|
316
|
+
raise_invalid_error!(INVALID_HOST) unless string.size > 0
|
317
|
+
string.split(HOST_DELIM).reduce([]) do |servers, host|
|
318
|
+
if host[0] == '['
|
319
|
+
if host.index(']:')
|
320
|
+
h, p = host.split(']:')
|
321
|
+
validate_port_string!(p)
|
322
|
+
end
|
323
|
+
elsif host.index(HOST_PORT_DELIM)
|
324
|
+
h, d, p = host.partition(HOST_PORT_DELIM)
|
325
|
+
raise_invalid_error!(INVALID_HOST) unless h.size > 0
|
326
|
+
validate_port_string!(p)
|
327
|
+
elsif host =~ UNIX_SOCKET
|
328
|
+
raise_invalid_error!(UNESCAPED_UNIX_SOCKET) if host =~ UNSAFE
|
329
|
+
end
|
330
|
+
servers << host
|
331
|
+
end
|
332
|
+
end
|
333
|
+
|
334
|
+
def raise_invalid_error!(details)
|
335
|
+
raise Error::InvalidURI.new(@string, details)
|
336
|
+
end
|
337
|
+
|
338
|
+
def decode(value)
|
339
|
+
::URI.decode(value)
|
340
|
+
end
|
227
341
|
|
228
342
|
# Hash for storing map of URI option parameters to conversion strategies
|
229
|
-
|
343
|
+
URI_OPTION_MAP = {}
|
230
344
|
|
231
|
-
# Simple internal dsl to register a MongoDB URI option in the
|
345
|
+
# Simple internal dsl to register a MongoDB URI option in the URI_OPTION_MAP.
|
232
346
|
#
|
233
347
|
# @param uri_key [String] The MongoDB URI option to register.
|
234
348
|
# @param name [Symbol] The name of the option in the driver.
|
235
349
|
# @param extra [Hash] Extra options.
|
236
350
|
# * :group [Symbol] Nested hash where option will go.
|
237
351
|
# * :type [Symbol] Name of function to transform value.
|
238
|
-
def self.
|
239
|
-
|
352
|
+
def self.uri_option(uri_key, name, extra = {})
|
353
|
+
URI_OPTION_MAP[uri_key] = { :name => name }.merge(extra)
|
240
354
|
end
|
241
355
|
|
242
356
|
# Replica Set Options
|
243
|
-
|
357
|
+
uri_option 'replicaset', :replica_set, :type => :replica_set
|
244
358
|
|
245
359
|
# Timeout Options
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
360
|
+
uri_option 'connecttimeoutms', :connect_timeout, :type => :ms_convert
|
361
|
+
uri_option 'sockettimeoutms', :socket_timeout, :type => :ms_convert
|
362
|
+
uri_option 'serverselectiontimeoutms', :server_selection_timeout, :type => :ms_convert
|
363
|
+
uri_option 'localthresholdms', :local_threshold, :type => :ms_convert
|
250
364
|
|
251
365
|
# Write Options
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
366
|
+
uri_option 'w', :w, :group => :write
|
367
|
+
uri_option 'journal', :j, :group => :write
|
368
|
+
uri_option 'fsync', :fsync, :group => :write
|
369
|
+
uri_option 'wtimeoutms', :timeout, :group => :write
|
256
370
|
|
257
371
|
# Read Options
|
258
|
-
|
259
|
-
|
372
|
+
uri_option 'readpreference', :mode, :group => :read, :type => :read_mode
|
373
|
+
uri_option 'readpreferencetags', :tag_sets, :group => :read, :type => :read_tags
|
260
374
|
|
261
375
|
# Pool options
|
262
|
-
|
263
|
-
|
264
|
-
|
376
|
+
uri_option 'minpoolsize', :min_pool_size
|
377
|
+
uri_option 'maxpoolsize', :max_pool_size
|
378
|
+
uri_option 'waitqueuetimeoutms', :wait_queue_timeout, :type => :ms_convert
|
265
379
|
|
266
380
|
# Security Options
|
267
|
-
|
381
|
+
uri_option 'ssl', :ssl
|
268
382
|
|
269
383
|
# Topology options
|
270
|
-
|
384
|
+
uri_option 'connect', :connect
|
271
385
|
|
272
386
|
# Auth Options
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
# Gets the user provided in the URI
|
279
|
-
#
|
280
|
-
# @return [String] The user.
|
281
|
-
def user
|
282
|
-
@match[1]
|
283
|
-
end
|
284
|
-
|
285
|
-
# Gets the password provided in the URI
|
286
|
-
#
|
287
|
-
# @return [String] The password.
|
288
|
-
def password
|
289
|
-
@match[2]
|
290
|
-
end
|
387
|
+
uri_option 'authsource', :source, :group => :auth, :type => :auth_source
|
388
|
+
uri_option 'authmechanism', :auth_mech, :type => :auth_mech
|
389
|
+
uri_option 'authmechanismproperties', :auth_mech_properties, :group => :auth,
|
390
|
+
:type => :auth_mech_props
|
291
391
|
|
292
392
|
# Casts option values that do not have a specifically provided
|
293
393
|
# transofrmation to the appropriate type.
|
@@ -303,7 +403,7 @@ module Mongo
|
|
303
403
|
elsif value =~ /[\d]/
|
304
404
|
value.to_i
|
305
405
|
else
|
306
|
-
value.to_sym
|
406
|
+
decode(value).to_sym
|
307
407
|
end
|
308
408
|
end
|
309
409
|
|
@@ -322,15 +422,15 @@ module Mongo
|
|
322
422
|
|
323
423
|
# Selects the output destination for an option.
|
324
424
|
#
|
325
|
-
# @param
|
326
|
-
# @param
|
425
|
+
# @param [Hash] uri_options The base target.
|
426
|
+
# @param [Symbol] group Group subtarget.
|
327
427
|
#
|
328
428
|
# @return [Hash] The target for the option.
|
329
|
-
def select_target(
|
429
|
+
def select_target(uri_options, group = nil)
|
330
430
|
if group
|
331
|
-
|
431
|
+
uri_options[group] ||= {}
|
332
432
|
else
|
333
|
-
|
433
|
+
uri_options
|
334
434
|
end
|
335
435
|
end
|
336
436
|
|
@@ -345,15 +445,19 @@ module Mongo
|
|
345
445
|
# @param target [Hash] The destination.
|
346
446
|
# @param value [Object] The value to be merged.
|
347
447
|
# @param name [Symbol] The name of the option.
|
348
|
-
def
|
448
|
+
def merge_uri_option(target, value, name)
|
349
449
|
if target.key?(name)
|
350
|
-
|
450
|
+
if REPEATABLE_OPTIONS.include?(name)
|
451
|
+
target[name] += value
|
452
|
+
else
|
453
|
+
log_warn("Repeated option key: #{name}.")
|
454
|
+
end
|
351
455
|
else
|
352
456
|
target.merge!(name => value)
|
353
457
|
end
|
354
458
|
end
|
355
459
|
|
356
|
-
# Adds an option to the options hash via the supplied strategy.
|
460
|
+
# Adds an option to the uri options hash via the supplied strategy.
|
357
461
|
#
|
358
462
|
# Acquires a target for the option based on group.
|
359
463
|
# Transforms the value.
|
@@ -361,11 +465,11 @@ module Mongo
|
|
361
465
|
#
|
362
466
|
# @param strategy [Symbol] The strategy for this option.
|
363
467
|
# @param value [String] The value of the option.
|
364
|
-
# @param
|
365
|
-
def
|
366
|
-
target = select_target(
|
468
|
+
# @param uri_options [Hash] The base option target.
|
469
|
+
def add_uri_option(strategy, value, uri_options)
|
470
|
+
target = select_target(uri_options, strategy[:group])
|
367
471
|
value = apply_transform(value, strategy[:type])
|
368
|
-
|
472
|
+
merge_uri_option(target, value, strategy[:name])
|
369
473
|
end
|
370
474
|
|
371
475
|
# Replica set transformation, avoid converting to Symbol.
|
@@ -374,7 +478,7 @@ module Mongo
|
|
374
478
|
#
|
375
479
|
# @return [String] Same value to avoid cast to Symbol.
|
376
480
|
def replica_set(value)
|
377
|
-
value
|
481
|
+
decode(value)
|
378
482
|
end
|
379
483
|
|
380
484
|
# Auth source transformation, either db string or :external.
|
@@ -384,7 +488,7 @@ module Mongo
|
|
384
488
|
# @return [String] If auth source is database name.
|
385
489
|
# @return [:external] If auth source is external authentication.
|
386
490
|
def auth_source(value)
|
387
|
-
value == '$external' ? :external : value
|
491
|
+
value == '$external' ? :external : decode(value)
|
388
492
|
end
|
389
493
|
|
390
494
|
# Authentication mechanism transformation.
|
@@ -458,7 +562,7 @@ module Mongo
|
|
458
562
|
def hash_extractor(value)
|
459
563
|
value.split(',').reduce({}) do |set, tag|
|
460
564
|
k, v = tag.split(':')
|
461
|
-
set.merge(k.downcase.to_sym => v)
|
565
|
+
set.merge(decode(k).downcase.to_sym => decode(v))
|
462
566
|
end
|
463
567
|
end
|
464
568
|
end
|