mongo 2.1.0.rc0 → 2.1.0

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 (110) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +5 -2
  3. data.tar.gz.sig +0 -0
  4. data/Rakefile +2 -2
  5. data/lib/mongo.rb +2 -1
  6. data/lib/mongo/address.rb +11 -5
  7. data/lib/mongo/address/ipv4.rb +6 -1
  8. data/lib/mongo/auth/cr/conversation.rb +1 -1
  9. data/lib/mongo/auth/ldap/conversation.rb +1 -1
  10. data/lib/mongo/auth/scram/conversation.rb +1 -1
  11. data/lib/mongo/auth/user/view.rb +2 -2
  12. data/lib/mongo/auth/x509/conversation.rb +1 -1
  13. data/lib/mongo/bulk_write.rb +12 -9
  14. data/lib/mongo/bulk_write/transformable.rb +20 -5
  15. data/lib/mongo/client.rb +11 -11
  16. data/lib/mongo/cluster.rb +2 -2
  17. data/lib/mongo/collection.rb +21 -8
  18. data/lib/mongo/collection/view.rb +1 -0
  19. data/lib/mongo/collection/view/aggregation.rb +11 -5
  20. data/lib/mongo/collection/view/iterable.rb +6 -2
  21. data/lib/mongo/collection/view/map_reduce.rb +39 -5
  22. data/lib/mongo/collection/view/readable.rb +35 -30
  23. data/lib/mongo/collection/view/writable.rb +26 -18
  24. data/lib/mongo/database.rb +12 -2
  25. data/lib/mongo/database/view.rb +4 -3
  26. data/lib/mongo/dbref.rb +4 -4
  27. data/lib/mongo/grid/fs_bucket.rb +8 -1
  28. data/lib/mongo/grid/stream/read.rb +1 -1
  29. data/lib/mongo/index.rb +5 -0
  30. data/lib/mongo/index/view.rb +2 -2
  31. data/lib/mongo/monitoring/command_log_subscriber.rb +9 -3
  32. data/lib/mongo/monitoring/event.rb +1 -0
  33. data/lib/mongo/monitoring/event/command_started.rb +2 -1
  34. data/lib/mongo/monitoring/event/command_succeeded.rb +6 -3
  35. data/lib/mongo/monitoring/event/secure.rb +58 -0
  36. data/lib/mongo/operation.rb +31 -1
  37. data/lib/mongo/operation/commands/collections_info.rb +2 -0
  38. data/lib/mongo/operation/commands/collections_info/result.rb +39 -0
  39. data/lib/mongo/operation/commands/list_indexes/result.rb +2 -1
  40. data/lib/mongo/operation/commands/map_reduce/result.rb +1 -1
  41. data/lib/mongo/operation/read/query.rb +2 -0
  42. data/lib/mongo/operation/read/query/result.rb +40 -0
  43. data/lib/mongo/operation/result.rb +13 -1
  44. data/lib/mongo/operation/write/bulk/delete.rb +2 -2
  45. data/lib/mongo/operation/write/bulk/update.rb +3 -3
  46. data/lib/mongo/operation/write/delete.rb +2 -2
  47. data/lib/mongo/operation/write/update.rb +9 -4
  48. data/lib/mongo/options.rb +1 -0
  49. data/lib/mongo/options/redacted.rb +156 -0
  50. data/lib/mongo/protocol/insert.rb +25 -6
  51. data/lib/mongo/protocol/query.rb +45 -31
  52. data/lib/mongo/protocol/reply.rb +29 -6
  53. data/lib/mongo/protocol/serializers.rb +1 -1
  54. data/lib/mongo/retryable.rb +83 -0
  55. data/lib/mongo/server.rb +16 -3
  56. data/lib/mongo/server/connectable.rb +21 -3
  57. data/lib/mongo/server/connection.rb +38 -4
  58. data/lib/mongo/server/connection_pool.rb +12 -0
  59. data/lib/mongo/server/connection_pool/queue.rb +15 -0
  60. data/lib/mongo/server/monitor/connection.rb +2 -2
  61. data/lib/mongo/server_selector.rb +5 -0
  62. data/lib/mongo/server_selector/selectable.rb +16 -9
  63. data/lib/mongo/socket.rb +6 -2
  64. data/lib/mongo/uri.rb +1 -1
  65. data/lib/mongo/version.rb +1 -1
  66. data/spec/mongo/bulk_write/ordered_combiner_spec.rb +11 -11
  67. data/spec/mongo/bulk_write/unordered_combiner_spec.rb +10 -10
  68. data/spec/mongo/client_spec.rb +101 -18
  69. data/spec/mongo/collection_spec.rb +44 -0
  70. data/spec/mongo/connection_string_spec.rb +36 -58
  71. data/spec/mongo/database_spec.rb +20 -0
  72. data/spec/mongo/grid/fs_bucket_spec.rb +1 -1
  73. data/spec/mongo/grid/stream/write_spec.rb +2 -2
  74. data/spec/mongo/monitoring/event/command_started_spec.rb +26 -0
  75. data/spec/mongo/monitoring/event/command_succeeded_spec.rb +26 -0
  76. data/spec/mongo/monitoring/event/secure_spec.rb +57 -0
  77. data/spec/mongo/operation/commands/aggregate_spec.rb +0 -16
  78. data/spec/mongo/operation/commands/command_spec.rb +0 -18
  79. data/spec/mongo/operation/kill_cursors_spec.rb +0 -16
  80. data/spec/mongo/operation/read/get_more_spec.rb +0 -16
  81. data/spec/mongo/operation/read/query_spec.rb +19 -16
  82. data/spec/mongo/operation/write/bulk/delete_spec.rb +16 -16
  83. data/spec/mongo/operation/write/bulk/update_spec.rb +6 -6
  84. data/spec/mongo/operation/write/command/delete_spec.rb +0 -16
  85. data/spec/mongo/operation/write/command/insert_spec.rb +0 -16
  86. data/spec/mongo/operation/write/command/update_spec.rb +0 -16
  87. data/spec/mongo/operation/write/delete_spec.rb +3 -3
  88. data/spec/mongo/operation/write/update_spec.rb +6 -6
  89. data/spec/mongo/options/redacted_spec.rb +350 -0
  90. data/spec/mongo/protocol/query_spec.rb +15 -1
  91. data/spec/mongo/retryable_spec.rb +147 -0
  92. data/spec/mongo/server/connection_pool/queue_spec.rb +16 -0
  93. data/spec/mongo/server/connection_pool_spec.rb +32 -0
  94. data/spec/mongo/server/connection_spec.rb +37 -0
  95. data/spec/mongo/server_discovery_and_monitoring_spec.rb +24 -59
  96. data/spec/mongo/server_selection_rtt_spec.rb +37 -57
  97. data/spec/mongo/server_selection_spec.rb +2 -0
  98. data/spec/mongo/server_selector/nearest_spec.rb +1 -0
  99. data/spec/mongo/server_selector/primary_preferred_spec.rb +1 -0
  100. data/spec/mongo/server_selector/primary_spec.rb +8 -2
  101. data/spec/mongo/server_selector/secondary_preferred_spec.rb +1 -0
  102. data/spec/mongo/server_selector/secondary_spec.rb +1 -0
  103. data/spec/mongo/server_spec.rb +68 -1
  104. data/spec/mongo/socket/ssl_spec.rb +29 -5
  105. data/spec/mongo/uri_spec.rb +20 -20
  106. data/spec/support/crud.rb +7 -1
  107. data/spec/support/matchers.rb +1 -1
  108. data/spec/support/shared/server_selector.rb +58 -2
  109. metadata +20 -5
  110. metadata.gz.sig +0 -0
@@ -21,6 +21,11 @@ module Mongo
21
21
  # @since 2.0.0
22
22
  module Index
23
23
 
24
+ # Wildcard constant for all.
25
+ #
26
+ # @since 2.1.0
27
+ ALL = '*'.freeze
28
+
24
29
  # Specify ascending order for an index.
25
30
  #
26
31
  # @since 2.0.0
@@ -76,7 +76,7 @@ module Mongo
76
76
  #
77
77
  # @since 2.0.0
78
78
  def drop_one(name)
79
- raise Error::MultiIndexDrop.new if name == '*'
79
+ raise Error::MultiIndexDrop.new if name == Index::ALL
80
80
  drop_by_name(name)
81
81
  end
82
82
 
@@ -89,7 +89,7 @@ module Mongo
89
89
  #
90
90
  # @since 2.0.0
91
91
  def drop_all
92
- drop_by_name('*')
92
+ drop_by_name(Index::ALL)
93
93
  end
94
94
 
95
95
  # Creates an index on the collection.
@@ -53,7 +53,9 @@ module Mongo
53
53
  #
54
54
  # @since 2.1.0
55
55
  def started(event)
56
- log_debug("#{prefix(event)} | STARTED | #{format_command(event.command)}")
56
+ if logger.debug?
57
+ log_debug("#{prefix(event)} | STARTED | #{format_command(event.command)}")
58
+ end
57
59
  end
58
60
 
59
61
  # Handle the command succeeded event.
@@ -65,7 +67,9 @@ module Mongo
65
67
  #
66
68
  # @since 2.1.0
67
69
  def succeeded(event)
68
- log_debug("#{prefix(event)} | SUCCEEDED | #{event.duration}s")
70
+ if logger.debug?
71
+ log_debug("#{prefix(event)} | SUCCEEDED | #{event.duration}s")
72
+ end
69
73
  end
70
74
 
71
75
  # Handle the command failed event.
@@ -77,7 +81,9 @@ module Mongo
77
81
  #
78
82
  # @since 2.1.0
79
83
  def failed(event)
80
- log_debug("#{prefix(event)} | FAILED | #{event.message} | #{event.duration}s")
84
+ if logger.debug?
85
+ log_debug("#{prefix(event)} | FAILED | #{event.message} | #{event.duration}s")
86
+ end
81
87
  end
82
88
 
83
89
  private
@@ -12,6 +12,7 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ require 'mongo/monitoring/event/secure'
15
16
  require 'mongo/monitoring/event/command_started'
16
17
  require 'mongo/monitoring/event/command_succeeded'
17
18
  require 'mongo/monitoring/event/command_failed'
@@ -20,6 +20,7 @@ module Mongo
20
20
  #
21
21
  # @since 2.1.0
22
22
  class CommandStarted
23
+ include Secure
23
24
 
24
25
  # @return [ Server::Address ] address The server address.
25
26
  attr_reader :address
@@ -57,7 +58,7 @@ module Mongo
57
58
  @address = address
58
59
  @request_id = request_id
59
60
  @operation_id = operation_id
60
- @command = command
61
+ @command = redacted(command_name, command)
61
62
  end
62
63
 
63
64
  # Create the event from a wire protocol message payload.
@@ -20,6 +20,7 @@ module Mongo
20
20
  #
21
21
  # @since 2.1.0
22
22
  class CommandSucceeded
23
+ include Secure
23
24
 
24
25
  # @return [ Server::Address ] address The server address.
25
26
  attr_reader :address
@@ -61,7 +62,7 @@ module Mongo
61
62
  @address = address
62
63
  @request_id = request_id
63
64
  @operation_id = operation_id
64
- @reply = reply
65
+ @reply = redacted(command_name, reply)
65
66
  @duration = duration
66
67
  end
67
68
 
@@ -97,11 +98,13 @@ module Mongo
97
98
  if reply_payload
98
99
  reply = reply_payload[:reply]
99
100
  if cursor = reply[:cursor]
100
- reply = reply.merge(cursor: cursor.merge(ns: namespace(command_payload)))
101
+ if !cursor.key?(Collection::NS)
102
+ cursor.merge!(Collection::NS => namespace(command_payload))
103
+ end
101
104
  end
102
105
  reply
103
106
  else
104
- BSON::Document.new(ok: 1)
107
+ BSON::Document.new(Operation::Result::OK => 1)
105
108
  end
106
109
  end
107
110
 
@@ -0,0 +1,58 @@
1
+ # Copyright (C) 2015 MongoDB, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the 'License');
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an 'AS IS' BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ module Mongo
16
+ class Monitoring
17
+ module Event
18
+
19
+ # Provides behaviour to redact sensitive information from commands and
20
+ # replies.
21
+ #
22
+ # @since 2.1.0
23
+ module Secure
24
+
25
+ # The list of commands that has the data redacted for security.
26
+ #
27
+ # @since 2.1.0
28
+ REDACTED_COMMANDS = [
29
+ 'authenticate',
30
+ 'saslStart',
31
+ 'saslContinue',
32
+ 'getnonce',
33
+ 'createUser',
34
+ 'updateUser',
35
+ 'copydbgetnonce',
36
+ 'copydbsaslstart',
37
+ 'copydb'
38
+ ].freeze
39
+
40
+ # Redact secure information from the document if it's command is in the
41
+ # list.
42
+ #
43
+ # @example Get the redacted document.
44
+ # secure.redacted(command_name, document)
45
+ #
46
+ # @param [ String, Symbol ] command_name The command name.
47
+ # @param [ BSON::Document ] document The document.
48
+ #
49
+ # @return [ BSON::Document ] The redacted document.
50
+ #
51
+ # @since 2.1.0
52
+ def redacted(command_name, document)
53
+ REDACTED_COMMANDS.include?(command_name.to_s) ? BSON::Document.new : document
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -20,4 +20,34 @@ require 'mongo/operation/read_preference'
20
20
  require 'mongo/operation/read'
21
21
  require 'mongo/operation/write'
22
22
  require 'mongo/operation/commands'
23
- require 'mongo/operation/kill_cursors'
23
+ require 'mongo/operation/kill_cursors'
24
+
25
+ module Mongo
26
+ module Operation
27
+
28
+ # The q field constant.
29
+ #
30
+ # @since 2.1.0
31
+ Q = 'q'.freeze
32
+
33
+ # The u field constant.
34
+ #
35
+ # @since 2.1.0
36
+ U = 'u'.freeze
37
+
38
+ # The limit field constant.
39
+ #
40
+ # @since 2.1.0
41
+ LIMIT = 'limit'.freeze
42
+
43
+ # The multi field constant.
44
+ #
45
+ # @since 2.1.0
46
+ MULTI = 'multi'.freeze
47
+
48
+ # The upsert field constant.
49
+ #
50
+ # @since 2.1.0
51
+ UPSERT = 'upsert'.freeze
52
+ end
53
+ end
@@ -12,6 +12,8 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ require 'mongo/operation/commands/collections_info/result'
16
+
15
17
  module Mongo
16
18
  module Operation
17
19
 
@@ -0,0 +1,39 @@
1
+ # Copyright (C) 2014-2015 MongoDB, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ module Mongo
16
+ module Operation
17
+ class CollectionsInfo
18
+
19
+ # Defines custom behaviour of results when query the system.namespaces
20
+ # collection.
21
+ #
22
+ # @since 2.1.0
23
+ class Result < Operation::Result
24
+
25
+ # Get the namespace for the cursor.
26
+ #
27
+ # @example Get the namespace.
28
+ # result.namespace
29
+ #
30
+ # @return [ String ] The namespace.
31
+ #
32
+ # @since 2.1.0
33
+ def namespace
34
+ Database::NAMESPACES
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -110,6 +110,7 @@ module Mongo
110
110
  def first_document
111
111
  @first_document ||= reply.documents[0]
112
112
  end
113
- end end
113
+ end
114
+ end
114
115
  end
115
116
  end
@@ -16,7 +16,7 @@ module Mongo
16
16
  module Operation
17
17
  class MapReduce
18
18
 
19
- # Defines custom behaviour of results in an aggregation context.
19
+ # Defines custom behaviour of results for a map reduce operation.
20
20
  #
21
21
  # @since 2.0.0
22
22
  class Result < Operation::Result
@@ -12,6 +12,8 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ require 'mongo/operation/read/query/result'
16
+
15
17
  module Mongo
16
18
  module Operation
17
19
  module Read
@@ -0,0 +1,40 @@
1
+ # Copyright (C) 2014-2015 MongoDB, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ module Mongo
16
+ module Operation
17
+ module Read
18
+ class Query
19
+
20
+ # Defines custom behaviour of results for a query.
21
+ #
22
+ # @since 2.1.0
23
+ class Result < Operation::Result
24
+
25
+ # Determine if the query was a success.
26
+ #
27
+ # @example Was the query successful?
28
+ # result.successful?
29
+ #
30
+ # @return [ true, false ] If the query was successful.
31
+ #
32
+ # @since 2.0.0
33
+ def successful?
34
+ !query_failure?
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -190,12 +190,24 @@ module Mongo
190
190
  def successful?
191
191
  return true if !acknowledged?
192
192
  if first_document.has_key?(OK)
193
- first_document[OK] == 1 && parser.message.empty?
193
+ ok? && parser.message.empty?
194
194
  else
195
195
  !query_failure? && parser.message.empty?
196
196
  end
197
197
  end
198
198
 
199
+ # Check the first document's ok field.
200
+ #
201
+ # @example Check the ok field.
202
+ # result.ok?
203
+ #
204
+ # @return [ true, false ] If the command returned ok.
205
+ #
206
+ # @since 2.1.0
207
+ def ok?
208
+ first_document[OK] == 1
209
+ end
210
+
199
211
  # Validate the result by checking for any errors.
200
212
  #
201
213
  # @note This only checks for errors with writes since authentication is
@@ -60,8 +60,8 @@ module Mongo
60
60
 
61
61
  def messages
62
62
  deletes.collect do |del|
63
- opts = ( del[:limit] || 0 ) <= 0 ? {} : { :flags => [ :single_remove ] }
64
- Protocol::Delete.new(db_name, coll_name, del[:q], opts)
63
+ opts = ( del[Operation::LIMIT] || 0 ) <= 0 ? {} : { :flags => [ :single_remove ] }
64
+ Protocol::Delete.new(db_name, coll_name, del[Operation::Q], opts)
65
65
  end
66
66
  end
67
67
  end
@@ -69,9 +69,9 @@ module Mongo
69
69
  def messages
70
70
  updates.collect do |u|
71
71
  opts = { :flags => [] }
72
- opts[:flags] << :multi_update if !!u[:multi]
73
- opts[:flags] << :upsert if !!u[:upsert]
74
- Protocol::Update.new(db_name, coll_name, u[:q], u[:u], opts)
72
+ opts[:flags] << :multi_update if !!u[Operation::MULTI]
73
+ opts[:flags] << :upsert if !!u[Operation::UPSERT]
74
+ Protocol::Update.new(db_name, coll_name, u[Operation::Q], u[Operation::U], opts)
75
75
  end
76
76
  end
77
77
  end
@@ -61,8 +61,8 @@ module Mongo
61
61
  end
62
62
 
63
63
  def message
64
- selector = delete[:q]
65
- opts = (delete[:limit] || 0) <= 0 ? {} : { :flags => [ :single_remove ] }
64
+ selector = delete[Operation::Q]
65
+ opts = (delete[Operation::LIMIT] || 0) <= 0 ? {} : { :flags => [ :single_remove ] }
66
66
  Protocol::Delete.new(db_name, coll_name, selector, opts)
67
67
  end
68
68
  end
@@ -65,10 +65,15 @@ module Mongo
65
65
 
66
66
  def message
67
67
  flags = []
68
- flags << :multi_update if update[:multi]
69
- flags << :upsert if update[:upsert]
70
- Protocol::Update.new(db_name, coll_name, update[:q], update[:u],
71
- flags.empty? ? {} : { flags: flags })
68
+ flags << :multi_update if update[Operation::MULTI]
69
+ flags << :upsert if update[Operation::UPSERT]
70
+ Protocol::Update.new(
71
+ db_name,
72
+ coll_name,
73
+ update[Operation::Q],
74
+ update[Operation::U],
75
+ flags.empty? ? {} : { flags: flags }
76
+ )
72
77
  end
73
78
  end
74
79
  end
@@ -13,3 +13,4 @@
13
13
  # limitations under the License.
14
14
 
15
15
  require 'mongo/options/mapper'
16
+ require 'mongo/options/redacted'
@@ -0,0 +1,156 @@
1
+ # Copyright (C) 2015 MongoDB, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ module Mongo
16
+ module Options
17
+
18
+ # Class for wrapping options that could be sensitive.
19
+ # When printed, the sensitive values will be redacted.
20
+ #
21
+ # @since 2.1.0
22
+ class Redacted < BSON::Document
23
+
24
+ # The options whose values will be redacted.
25
+ #
26
+ # @since 2.1.0
27
+ SENSITIVE_OPTIONS = [ :password,
28
+ :pwd ].freeze
29
+
30
+ # The replacement string used in place of the value for sensitive keys.
31
+ #
32
+ # @since 2.1.0
33
+ STRING_REPLACEMENT = '<REDACTED>'.freeze
34
+
35
+ # Get a string representation of the options.
36
+ #
37
+ # @return [ String ] The string representation of the options.
38
+ #
39
+ # @since 2.1.0
40
+ def inspect
41
+ redacted_string(:inspect)
42
+ end
43
+
44
+ # Get a string representation of the options.
45
+ #
46
+ # @return [ String ] The string representation of the options.
47
+ #
48
+ # @since 2.1.0
49
+ def to_s
50
+ redacted_string(:to_s)
51
+ end
52
+
53
+ # Whether these options contain a given key.
54
+ #
55
+ # @example Determine if the options contain a given key.
56
+ # options.has_key?(:name)
57
+ #
58
+ # @param [ String, Symbol ] key The key to check for existence.
59
+ #
60
+ # @return [ true, false ] If the options contain the given key.
61
+ #
62
+ # @since 2.1.0
63
+ def has_key?(key)
64
+ super(convert_key(key))
65
+ end
66
+ alias_method :key?, :has_key?
67
+
68
+ # Returns a new options object consisting of pairs for which the block returns false.
69
+ #
70
+ # @example Get a new options object with pairs for which the block returns false.
71
+ # new_options = options.reject { |k, v| k == 'database' }
72
+ #
73
+ # @yieldparam [ String, Object ] The key as a string and its value.
74
+ #
75
+ # @return [ Options::Redacted ] A new options object.
76
+ #
77
+ # @since 2.1.0
78
+ def reject(&block)
79
+ new_options = dup
80
+ new_options.reject!(&block) || new_options
81
+ end
82
+
83
+ # Only keeps pairs for which the block returns false.
84
+ #
85
+ # @example Remove pairs from this object for which the block returns true.
86
+ # options.reject! { |k, v| k == 'database' }
87
+ #
88
+ # @yieldparam [ String, Object ] The key as a string and its value.
89
+ #
90
+ # @return [ Options::Redacted, nil ] This object or nil if no changes were made.
91
+ #
92
+ # @since 2.1.0
93
+ def reject!
94
+ if block_given?
95
+ n_keys = keys.size
96
+ keys.each do |key|
97
+ delete(key) if yield(key, self[key])
98
+ end
99
+ n_keys == keys.size ? nil : self
100
+ else
101
+ to_enum
102
+ end
103
+ end
104
+
105
+ # Returns a new options object consisting of pairs for which the block returns true.
106
+ #
107
+ # @example Get a new options object with pairs for which the block returns true.
108
+ # ssl_options = options.select { |k, v| k =~ /ssl/ }
109
+ #
110
+ # @yieldparam [ String, Object ] The key as a string and its value.
111
+ #
112
+ # @return [ Options::Redacted ] A new options object.
113
+ #
114
+ # @since 2.1.0
115
+ def select(&block)
116
+ new_options = dup
117
+ new_options.select!(&block) || new_options
118
+ end
119
+
120
+ # Only keeps pairs for which the block returns true.
121
+ #
122
+ # @example Remove pairs from this object for which the block does not return true.
123
+ # options.select! { |k, v| k =~ /ssl/ }
124
+ #
125
+ # @yieldparam [ String, Object ] The key as a string and its value.
126
+ #
127
+ # @return [ Options::Redacted, nil ] This object or nil if no changes were made.
128
+ #
129
+ # @since 2.1.0
130
+ def select!
131
+ if block_given?
132
+ n_keys = keys.size
133
+ keys.each do |key|
134
+ delete(key) unless yield(key, self[key])
135
+ end
136
+ n_keys == keys.size ? nil : self
137
+ else
138
+ to_enum
139
+ end
140
+ end
141
+
142
+ private
143
+
144
+ def redacted_string(method)
145
+ '{' + reduce([]) do |list, (k, v)|
146
+ list << "#{k.send(method)}=>#{redact(k, v, method)}"
147
+ end.join(', ') + '}'
148
+ end
149
+
150
+ def redact(k, v, method)
151
+ return STRING_REPLACEMENT if SENSITIVE_OPTIONS.include?(k.to_sym)
152
+ v.send(method)
153
+ end
154
+ end
155
+ end
156
+ end