mongo 2.9.2 → 2.10.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.
Files changed (227) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/lib/mongo.rb +1 -0
  5. data/lib/mongo/auth/user/view.rb +4 -4
  6. data/lib/mongo/bulk_write.rb +14 -8
  7. data/lib/mongo/bulk_write/result.rb +1 -1
  8. data/lib/mongo/bulk_write/result_combiner.rb +2 -2
  9. data/lib/mongo/bulk_write/transformable.rb +17 -9
  10. data/lib/mongo/client.rb +107 -16
  11. data/lib/mongo/cluster.rb +47 -25
  12. data/lib/mongo/cluster/topology/replica_set_no_primary.rb +1 -1
  13. data/lib/mongo/cluster_time.rb +139 -0
  14. data/lib/mongo/collection.rb +84 -25
  15. data/lib/mongo/collection/view.rb +7 -3
  16. data/lib/mongo/collection/view/aggregation.rb +4 -4
  17. data/lib/mongo/collection/view/builder/aggregation.rb +31 -6
  18. data/lib/mongo/collection/view/builder/find_command.rb +4 -1
  19. data/lib/mongo/collection/view/builder/map_reduce.rb +4 -1
  20. data/lib/mongo/collection/view/change_stream.rb +54 -66
  21. data/lib/mongo/collection/view/iterable.rb +2 -2
  22. data/lib/mongo/collection/view/map_reduce.rb +6 -4
  23. data/lib/mongo/collection/view/readable.rb +36 -16
  24. data/lib/mongo/collection/view/writable.rb +68 -22
  25. data/lib/mongo/cursor.rb +87 -20
  26. data/lib/mongo/database.rb +47 -43
  27. data/lib/mongo/database/view.rb +54 -11
  28. data/lib/mongo/error.rb +13 -4
  29. data/lib/mongo/error/invalid_write_concern.rb +2 -2
  30. data/lib/mongo/error/operation_failure.rb +65 -11
  31. data/lib/mongo/error/parser.rb +41 -8
  32. data/lib/mongo/grid/fs_bucket.rb +26 -6
  33. data/lib/mongo/grid/stream/read.rb +9 -2
  34. data/lib/mongo/grid/stream/write.rb +21 -5
  35. data/lib/mongo/index/view.rb +3 -3
  36. data/lib/mongo/lint.rb +10 -3
  37. data/lib/mongo/operation.rb +2 -0
  38. data/lib/mongo/operation/aggregate/result.rb +19 -6
  39. data/lib/mongo/operation/collections_info.rb +1 -1
  40. data/lib/mongo/operation/get_more/result.rb +9 -0
  41. data/lib/mongo/operation/list_collections/command.rb +1 -3
  42. data/lib/mongo/operation/list_collections/op_msg.rb +1 -2
  43. data/lib/mongo/operation/parallel_scan/command.rb +4 -1
  44. data/lib/mongo/operation/parallel_scan/op_msg.rb +4 -1
  45. data/lib/mongo/operation/result.rb +27 -4
  46. data/lib/mongo/operation/shared/executable.rb +19 -5
  47. data/lib/mongo/operation/shared/executable_no_validate.rb +1 -2
  48. data/lib/mongo/operation/shared/executable_transaction_label.rb +0 -9
  49. data/lib/mongo/operation/shared/polymorphic_result.rb +9 -1
  50. data/lib/mongo/operation/shared/result/aggregatable.rb +2 -2
  51. data/lib/mongo/operation/shared/sessions_supported.rb +42 -32
  52. data/lib/mongo/operation/shared/specifiable.rb +40 -0
  53. data/lib/mongo/operation/shared/unpinnable.rb +39 -0
  54. data/lib/mongo/operation/shared/write.rb +1 -1
  55. data/lib/mongo/protocol/update.rb +6 -2
  56. data/lib/mongo/retryable.rb +79 -39
  57. data/lib/mongo/server/connection.rb +10 -3
  58. data/lib/mongo/server/description.rb +25 -1
  59. data/lib/mongo/server/monitor/connection.rb +1 -1
  60. data/lib/mongo/server_selector.rb +10 -0
  61. data/lib/mongo/server_selector/selectable.rb +172 -32
  62. data/lib/mongo/session.rb +654 -581
  63. data/lib/mongo/session/session_pool.rb +1 -1
  64. data/lib/mongo/socket.rb +7 -28
  65. data/lib/mongo/socket/ssl.rb +26 -1
  66. data/lib/mongo/socket/tcp.rb +3 -0
  67. data/lib/mongo/socket/unix.rb +3 -0
  68. data/lib/mongo/uri.rb +112 -265
  69. data/lib/mongo/uri/srv_protocol.rb +4 -1
  70. data/lib/mongo/version.rb +1 -1
  71. data/lib/mongo/write_concern.rb +10 -29
  72. data/lib/mongo/write_concern/acknowledged.rb +12 -0
  73. data/lib/mongo/write_concern/base.rb +17 -13
  74. data/lib/mongo/write_concern/unacknowledged.rb +12 -0
  75. data/spec/atlas/atlas_connectivity_spec.rb +7 -37
  76. data/spec/atlas/operations_spec.rb +25 -0
  77. data/spec/integration/change_stream_examples_spec.rb +45 -31
  78. data/spec/integration/change_stream_spec.rb +305 -5
  79. data/spec/integration/client_spec.rb +44 -0
  80. data/spec/integration/command_monitoring_spec.rb +1 -0
  81. data/spec/integration/command_spec.rb +7 -1
  82. data/spec/integration/mmapv1_spec.rb +28 -0
  83. data/spec/integration/mongos_pinning_spec.rb +34 -0
  84. data/spec/integration/operation_failure_code_spec.rb +2 -2
  85. data/spec/integration/{read_concern.rb → read_concern_spec.rb} +7 -1
  86. data/spec/integration/read_preference_spec.rb +485 -0
  87. data/spec/integration/retryable_writes_spec.rb +8 -19
  88. data/spec/integration/sdam_error_handling_spec.rb +1 -1
  89. data/spec/integration/sdam_events_spec.rb +2 -2
  90. data/spec/integration/server_description_spec.rb +14 -17
  91. data/spec/integration/server_selector_spec.rb +7 -3
  92. data/spec/integration/server_spec.rb +48 -0
  93. data/spec/integration/ssl_uri_options_spec.rb +1 -1
  94. data/spec/integration/step_down_spec.rb +10 -4
  95. data/spec/integration/transactions_examples_spec.rb +11 -10
  96. data/spec/lite_spec_helper.rb +19 -16
  97. data/spec/mongo/auth/scram/negotiation_spec.rb +11 -8
  98. data/spec/mongo/bulk_write/ordered_combiner_spec.rb +6 -6
  99. data/spec/mongo/bulk_write/unordered_combiner_spec.rb +4 -4
  100. data/spec/mongo/bulk_write_spec.rb +12 -2
  101. data/spec/mongo/client_construction_spec.rb +160 -8
  102. data/spec/mongo/client_spec.rb +5 -4
  103. data/spec/mongo/cluster_spec.rb +6 -6
  104. data/spec/mongo/cluster_time_spec.rb +148 -0
  105. data/spec/mongo/collection/view/aggregation_spec.rb +34 -15
  106. data/spec/mongo/collection/view/change_stream_spec.rb +62 -3
  107. data/spec/mongo/collection/view/map_reduce_spec.rb +7 -5
  108. data/spec/mongo/collection/view/readable_spec.rb +4 -4
  109. data/spec/mongo/collection_spec.rb +331 -14
  110. data/spec/mongo/cursor_spec.rb +117 -5
  111. data/spec/mongo/database_spec.rb +240 -8
  112. data/spec/mongo/error/operation_failure_spec.rb +47 -1
  113. data/spec/mongo/error/parser_spec.rb +160 -23
  114. data/spec/mongo/operation/insert/bulk_spec.rb +2 -1
  115. data/spec/mongo/operation/result_spec.rb +27 -0
  116. data/spec/mongo/operation/update/bulk_spec.rb +1 -0
  117. data/spec/mongo/retryable_spec.rb +2 -0
  118. data/spec/mongo/server/app_metadata_spec.rb +2 -2
  119. data/spec/mongo/server/connection_spec.rb +13 -17
  120. data/spec/mongo/server/monitor/connection_spec.rb +13 -10
  121. data/spec/mongo/server_selector_spec.rb +34 -2
  122. data/spec/mongo/session/session_pool_spec.rb +14 -3
  123. data/spec/mongo/session_spec.rb +3 -3
  124. data/spec/mongo/session_transaction_spec.rb +4 -3
  125. data/spec/mongo/socket/ssl_spec.rb +19 -5
  126. data/spec/mongo/socket_spec.rb +1 -62
  127. data/spec/mongo/uri/srv_protocol_spec.rb +14 -20
  128. data/spec/mongo/uri_option_parsing_spec.rb +94 -8
  129. data/spec/mongo/uri_spec.rb +23 -10
  130. data/spec/mongo/write_concern_spec.rb +56 -3
  131. data/spec/spec_tests/change_streams_spec.rb +2 -1
  132. data/spec/spec_tests/cmap_spec.rb +1 -1
  133. data/spec/spec_tests/crud_spec.rb +12 -2
  134. data/spec/spec_tests/data/change_streams/change-streams-errors.yml +24 -1
  135. data/spec/spec_tests/data/change_streams/change-streams.yml +172 -3
  136. data/spec/spec_tests/data/command_monitoring/bulkWrite.yml +1 -1
  137. data/spec/spec_tests/data/command_monitoring/updateMany.yml +0 -2
  138. data/spec/spec_tests/data/command_monitoring/updateOne.yml +0 -5
  139. data/spec/spec_tests/data/crud/read/aggregate-out.yml +0 -6
  140. data/spec/spec_tests/data/crud/read/count-empty.yml +29 -0
  141. data/spec/spec_tests/data/crud/write/bulkWrite-arrayFilters.yml +1 -0
  142. data/spec/spec_tests/data/crud/write/bulkWrite-collation.yml +101 -0
  143. data/spec/spec_tests/data/crud/write/bulkWrite.yml +401 -0
  144. data/spec/spec_tests/data/crud/write/insertMany.yml +58 -2
  145. data/spec/spec_tests/data/crud/write/updateMany-arrayFilters.yml +3 -0
  146. data/spec/spec_tests/data/crud/write/updateOne-arrayFilters.yml +6 -1
  147. data/spec/spec_tests/data/crud_v2/aggregate-merge.yml +103 -0
  148. data/spec/spec_tests/data/crud_v2/aggregate-out-readConcern.yml +110 -0
  149. data/spec/spec_tests/data/crud_v2/bulkWrite-arrayFilters.yml +81 -0
  150. data/spec/spec_tests/data/crud_v2/db-aggregate.yml +38 -0
  151. data/spec/spec_tests/data/crud_v2/updateWithPipelines.yml +92 -0
  152. data/spec/spec_tests/data/retryable_writes/insertOne-serverErrors.yml +2 -2
  153. data/spec/spec_tests/data/transactions/abort.yml +3 -0
  154. data/spec/spec_tests/data/transactions/bulk.yml +3 -8
  155. data/spec/spec_tests/data/transactions/causal-consistency.yml +3 -8
  156. data/spec/spec_tests/data/transactions/commit.yml +3 -1
  157. data/spec/spec_tests/data/transactions/count.yml +3 -0
  158. data/spec/spec_tests/data/transactions/delete.yml +3 -0
  159. data/spec/spec_tests/data/transactions/error-labels.yml +4 -1
  160. data/spec/spec_tests/data/transactions/errors-client.yml +56 -0
  161. data/spec/spec_tests/data/transactions/errors.yml +3 -0
  162. data/spec/spec_tests/data/transactions/findOneAndDelete.yml +3 -0
  163. data/spec/spec_tests/data/transactions/findOneAndReplace.yml +3 -0
  164. data/spec/spec_tests/data/transactions/findOneAndUpdate.yml +3 -0
  165. data/spec/spec_tests/data/transactions/insert.yml +3 -0
  166. data/spec/spec_tests/data/transactions/isolation.yml +3 -0
  167. data/spec/spec_tests/data/transactions/mongos-pin-auto.yml +1671 -0
  168. data/spec/spec_tests/data/transactions/mongos-recovery-token.yml +347 -0
  169. data/spec/spec_tests/data/transactions/pin-mongos.yml +557 -0
  170. data/spec/spec_tests/data/transactions/read-concern.yml +3 -0
  171. data/spec/spec_tests/data/transactions/read-pref.yml +3 -0
  172. data/spec/spec_tests/data/transactions/reads.yml +3 -0
  173. data/spec/spec_tests/data/transactions/retryable-abort.yml +5 -2
  174. data/spec/spec_tests/data/transactions/retryable-commit.yml +4 -1
  175. data/spec/spec_tests/data/transactions/retryable-writes.yml +3 -0
  176. data/spec/spec_tests/data/transactions/run-command.yml +3 -0
  177. data/spec/spec_tests/data/transactions/transaction-options.yml +6 -0
  178. data/spec/spec_tests/data/transactions/update.yml +3 -8
  179. data/spec/spec_tests/data/transactions/write-concern.yml +348 -38
  180. data/spec/spec_tests/data/transactions_api/callback-aborts.yml +6 -0
  181. data/spec/spec_tests/data/transactions_api/callback-commits.yml +5 -0
  182. data/spec/spec_tests/data/transactions_api/callback-retry.yml +7 -2
  183. data/spec/spec_tests/data/transactions_api/commit-retry.yml +70 -15
  184. data/spec/spec_tests/data/transactions_api/commit-transienttransactionerror-4.2.yml +3 -0
  185. data/spec/spec_tests/data/transactions_api/commit-transienttransactionerror.yml +3 -0
  186. data/spec/spec_tests/data/transactions_api/commit-writeconcernerror.yml +59 -109
  187. data/spec/spec_tests/data/transactions_api/commit.yml +5 -0
  188. data/spec/spec_tests/data/transactions_api/transaction-options.yml +10 -0
  189. data/spec/spec_tests/retryable_reads_spec.rb +5 -2
  190. data/spec/spec_tests/retryable_writes_spec.rb +5 -2
  191. data/spec/spec_tests/sdam_monitoring_spec.rb +3 -3
  192. data/spec/spec_tests/sdam_spec.rb +2 -2
  193. data/spec/spec_tests/transactions_api_spec.rb +1 -67
  194. data/spec/spec_tests/transactions_spec.rb +2 -66
  195. data/spec/support/authorization.rb +4 -0
  196. data/spec/support/change_streams.rb +30 -10
  197. data/spec/support/change_streams/operation.rb +27 -0
  198. data/spec/support/client_registry.rb +44 -25
  199. data/spec/support/cluster_config.rb +25 -14
  200. data/spec/support/cluster_tools.rb +32 -10
  201. data/spec/support/command_monitoring.rb +1 -1
  202. data/spec/support/common_shortcuts.rb +30 -0
  203. data/spec/support/connection_string.rb +8 -3
  204. data/spec/support/constraints.rb +34 -0
  205. data/spec/support/crud.rb +31 -16
  206. data/spec/support/crud/context.rb +23 -0
  207. data/spec/support/crud/operation.rb +311 -14
  208. data/spec/support/crud/spec.rb +2 -1
  209. data/spec/support/crud/test.rb +24 -27
  210. data/spec/support/crud/test_base.rb +22 -0
  211. data/spec/support/crud/verifier.rb +15 -1
  212. data/spec/support/event_subscriber.rb +12 -0
  213. data/spec/support/sdam_formatter_integration.rb +12 -6
  214. data/spec/support/shared/server_selector.rb +10 -0
  215. data/spec/support/shared/session.rb +13 -12
  216. data/spec/support/spec_config.rb +32 -22
  217. data/spec/support/spec_setup.rb +2 -2
  218. data/spec/support/transactions.rb +87 -0
  219. data/spec/support/transactions/context.rb +33 -0
  220. data/spec/support/transactions/operation.rb +99 -349
  221. data/spec/support/transactions/spec.rb +1 -3
  222. data/spec/support/transactions/test.rb +110 -49
  223. data/spec/support/utils.rb +74 -1
  224. metadata +52 -10
  225. metadata.gz.sig +0 -0
  226. data/spec/support/crud/read.rb +0 -265
  227. data/spec/support/crud/write.rb +0 -284
metadata.gz.sig CHANGED
Binary file
@@ -1,265 +0,0 @@
1
- # Copyright (C) 2014-2019 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 CRUD
17
- module Operation
18
-
19
- # Defines common behavior for running CRUD read operation tests
20
- # on a collection.
21
- #
22
- # @since 2.0.0
23
- class Read
24
-
25
- # Map of method names to test operation argument names.
26
- #
27
- # @since 2.0.0
28
- ARGUMENT_MAP = { :sort => 'sort',
29
- :skip => 'skip',
30
- :batch_size => 'batchSize',
31
- :limit => 'limit',
32
- :collation => 'collation'
33
- }.freeze
34
-
35
- # Map of read preference mode names to their equivalent Ruby-formatted symbols.
36
- #
37
- # @since 2.4.0
38
- READ_PREFERENCE_MAP = { 'primary' => :primary,
39
- 'secondary' => :secondary,
40
- 'primaryPreferred' => :primary_preferred,
41
- 'secondaryPreferred' => :secondary_preferred,
42
- 'nearest' => :nearest
43
- }.freeze
44
-
45
- # Instantiate the operation.
46
- #
47
- # @return [ Hash ] spec The operation spec.
48
- #
49
- # @since 2.0.0
50
- def initialize(spec, outcome_spec = nil)
51
- @spec = spec
52
- @outcome = Outcome.new(outcome_spec || spec)
53
- @name = spec['name']
54
- end
55
-
56
- # The operation name.
57
- #
58
- # @return [ String ] name The operation name.
59
- #
60
- # @since 2.0.0
61
- attr_reader :name
62
-
63
- attr_reader :outcome
64
-
65
- def object
66
- @spec['object'] || 'collection'
67
- end
68
-
69
- # Which collection to verify results from.
70
- # Returns the collection name specified on the operation, or
71
- # the collection name for the entire spec file.
72
- def verify_collection_name
73
- if outcome && outcome.collection_name
74
- outcome.collection_name
75
- else
76
- spec.collection_name.tap do |cn|
77
- if cn.nil?
78
- raise "Collection name cannot be nil"
79
- end
80
- end
81
- end
82
- end
83
-
84
- # Execute the operation.
85
- #
86
- # @example Execute the operation.
87
- # operation.execute
88
- #
89
- # @param [ Collection ] collection The collection to execute the operation on.
90
- #
91
- # @return [ Result, Array<Hash> ] The result of executing the operation.
92
- #
93
- # @since 2.0.0
94
- def execute(target)
95
- op_name = Utils.underscore(name)
96
- if target.is_a?(Mongo::Database)
97
- op_name = "db_#{op_name}"
98
- elsif target.is_a?(Mongo::Client)
99
- op_name= "client_#{op_name}"
100
- end
101
- send(op_name, target)
102
- end
103
-
104
- # Whether the operation is expected to have results.
105
- #
106
- # @example Whether the operation is expected to have results.
107
- # operation.has_results?
108
- #
109
- # @return [ true, false ] If the operation is expected to have results.
110
- #
111
- # @since 2.0.0
112
- def has_results?
113
- !(name == 'aggregate' &&
114
- pipeline.find {|op| op.keys.include?('$out') })
115
- end
116
-
117
- private
118
-
119
- def count(collection)
120
- options = ARGUMENT_MAP.reduce({}) do |opts, (key, value)|
121
- opts.merge!(key => arguments[value]) if arguments[value]
122
- opts
123
- end
124
- collection.count(filter, options)
125
- end
126
-
127
- def count_documents(collection)
128
- options = ARGUMENT_MAP.reduce({}) do |opts, (key, value)|
129
- opts.merge!(key => arguments[value]) if arguments[value]
130
- opts
131
- end
132
- collection.count_documents(filter, options)
133
- end
134
-
135
- def estimated_document_count(collection)
136
- # estimated_document_count defaults options to {}
137
- args = arguments || {}
138
- options = ARGUMENT_MAP.reduce({}) do |opts, (key, value)|
139
- opts.merge!(key => args[value]) if args[value]
140
- opts
141
- end
142
- collection.estimated_document_count(options)
143
- end
144
-
145
- def aggregate(collection)
146
- collection.aggregate(pipeline, options).to_a
147
- end
148
-
149
- def distinct(collection)
150
- collection.distinct(field_name, filter, options)
151
- end
152
-
153
- def find(collection)
154
- opts = modifiers ? options.merge(modifiers: BSON::Document.new(modifiers)) : options
155
- (read_preference ? collection.with(read: read_preference) : collection).find(filter, opts).to_a
156
- end
157
-
158
- def find_one(collection)
159
- find(collection).first
160
- end
161
-
162
- def client_list_databases(client)
163
- client.list_databases
164
- end
165
-
166
- def client_list_database_names(client)
167
- client.list_databases({}, true)
168
- end
169
-
170
- def client_list_database_objects(client)
171
- client.list_mongo_databases
172
- end
173
-
174
- def db_list_collections(database)
175
- database.list_collections
176
- end
177
-
178
- def db_list_collection_names(database)
179
- database.collection_names
180
- end
181
-
182
- def db_list_collection_objects(database)
183
- database.collections
184
- end
185
-
186
- def list_indexes(collection)
187
- collection.indexes.to_a
188
- end
189
-
190
- def watch(collection)
191
- collection.watch
192
- end
193
-
194
- def db_watch(database)
195
- database.watch
196
- end
197
-
198
- def client_watch(client)
199
- client.watch
200
- end
201
-
202
- def download(fs_bucket)
203
- stream = fs_bucket.open_download_stream(BSON::ObjectId.from_string(arguments['id']['$oid']))
204
- stream.read
205
- end
206
-
207
- def download_by_name(fs_bucket)
208
- stream = fs_bucket.open_download_stream_by_name(arguments['filename'])
209
- stream.read
210
- end
211
-
212
- def map_reduce(collection)
213
- view = Mongo::Collection::View.new(collection)
214
- mr = Mongo::Collection::View::MapReduce.new(view, arguments['map']['$code'], arguments['reduce']['$code'])
215
- mr.to_a
216
- end
217
-
218
- def options
219
- ARGUMENT_MAP.reduce({}) do |opts, (key, value)|
220
- value = if arguments[value].is_a?(Hash) && arguments[value]['$numberLong']
221
- arguments[value]['$numberLong'].to_i
222
- else
223
- arguments[value]
224
- end
225
- value ? opts.merge!(key => value) : opts
226
- end
227
- end
228
-
229
- def collation
230
- arguments['collation']
231
- end
232
-
233
- def batch_size
234
- arguments['batchSize']
235
- end
236
-
237
- def filter
238
- arguments['filter']
239
- end
240
-
241
- def pipeline
242
- arguments['pipeline']
243
- end
244
-
245
- def modifiers
246
- arguments['modifiers']
247
- end
248
-
249
- def field_name
250
- arguments['fieldName']
251
- end
252
-
253
- def arguments
254
- @spec['arguments']
255
- end
256
-
257
- def read_preference
258
- if @spec['read_preference'] && @spec['read_preference']['mode']
259
- { mode: READ_PREFERENCE_MAP[@spec['read_preference']['mode']] }
260
- end
261
- end
262
- end
263
- end
264
- end
265
- end
@@ -1,284 +0,0 @@
1
- # Copyright (C) 2014-2019 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 CRUD
17
- module Operation
18
-
19
- # Defines common behavior for running CRUD write operation tests on a
20
- # collection.
21
- #
22
- # @since 2.0.0
23
- class Write
24
-
25
- # Map of CRUD operation names to method names.
26
- #
27
- # @since 2.0.0
28
- OPERATIONS = { 'deleteMany' => :delete_many,
29
- 'deleteOne' => :delete_one,
30
- 'insertMany' => :insert_many,
31
- 'insertOne' => :insert_one,
32
- 'replaceOne' => :replace_one,
33
- 'updateMany' => :update_many,
34
- 'updateOne' => :update_one,
35
- 'findOneAndDelete' => :find_one_and_delete,
36
- 'findOneAndReplace' => :find_one_and_replace,
37
- 'findOneAndUpdate' => :find_one_and_update,
38
- 'bulkWrite' => :bulk_write
39
- }.freeze
40
-
41
- # Map of operation options to method names.
42
- #
43
- # @since 2.0.0
44
- ARGUMENT_MAP = {
45
- :sort => 'sort',
46
- :projection => 'projection',
47
- :return_document => 'returnDocument',
48
- :upsert => 'upsert',
49
- :ordered => 'ordered',
50
- :write_concern => 'writeConcern',
51
- :collation => 'collation',
52
- :array_filters => 'arrayFilters'
53
- }.freeze
54
-
55
- # The operation name.
56
- #
57
- # @return [ String ] name The operation name.
58
- #
59
- # @since 2.0.0
60
- attr_reader :name
61
-
62
- # Instantiate the operation.
63
- #
64
- # @param [ Hash ] spec The operation specification.
65
- # @param [ Hash ] outcome_spec The outcome specification.
66
- # If not provided, outcome is taken out of operation specification.
67
- #
68
- # @since 2.0.0
69
- def initialize(spec, outcome_spec = nil)
70
- @spec = spec
71
- @name = spec['name']
72
- @outcome = Outcome.new(outcome_spec || spec)
73
- end
74
-
75
- attr_reader :outcome
76
-
77
- def object
78
- 'collection'
79
- end
80
-
81
- def verify_collection_name
82
- 'crud_spec_test'
83
- end
84
-
85
- # Whether the operation is expected to have results.
86
- #
87
- # @example Whether the operation is expected to have results.
88
- # operation.has_results?
89
- #
90
- # @return [ true ] If the operation is expected to have results.
91
- #
92
- # @since 2.0.0
93
- def has_results?
94
- true
95
- end
96
-
97
- # Execute the operation.
98
- #
99
- # @example Execute the operation.
100
- # operation.execute
101
- #
102
- # @param [ Collection ] collection The collection to execute
103
- # the operation on.
104
- #
105
- # @return [ Result, Array<Hash> ] The result of executing the operation.
106
- #
107
- # @since 2.0.0
108
- def execute(collection)
109
- send(OPERATIONS[name], collection)
110
- end
111
-
112
- private
113
-
114
- def bulk_write(collection)
115
- result = collection.bulk_write(requests, options)
116
- return_doc = {}
117
- return_doc['deletedCount'] = result.deleted_count if result.deleted_count
118
- return_doc['insertedIds'] = result.inserted_ids if result.inserted_ids
119
- return_doc['upsertedIds'] = result.upserted_ids if result.upserted_ids
120
- return_doc['upsertedId'] = result.upserted_id if upsert
121
- return_doc['upsertedCount'] = result.upserted_count if result.upserted_count
122
- return_doc['insertedCount'] = result.inserted_count if result.inserted_count
123
- return_doc['matchedCount'] = result.matched_count if result.matched_count
124
- return_doc['modifiedCount'] = result.modified_count if result.modified_count
125
- return_doc
126
- end
127
-
128
- def delete_many(collection)
129
- result = collection.delete_many(filter, options)
130
- { 'deletedCount' => result.deleted_count }
131
- end
132
-
133
- def delete_one(collection)
134
- result = collection.delete_one(filter, options)
135
- { 'deletedCount' => result.deleted_count }
136
- end
137
-
138
- def insert_many(collection)
139
- result = collection.insert_many(documents, options)
140
- { 'insertedIds' => result.inserted_ids }
141
- end
142
-
143
- def insert_one(collection)
144
- result = collection.insert_one(document)
145
- { 'insertedId' => result.inserted_id }
146
- end
147
-
148
- def update_return_doc(result)
149
- return_doc = {}
150
- return_doc['upsertedId'] = result.upserted_id if upsert
151
- return_doc['upsertedCount'] = result.upserted_count
152
- return_doc['matchedCount'] = result.matched_count
153
- return_doc['modifiedCount'] = result.modified_count if result.modified_count
154
- return_doc
155
- end
156
-
157
- def replace_one(collection)
158
- result = collection.replace_one(filter, replacement, options)
159
- update_return_doc(result)
160
- end
161
-
162
- def update_many(collection)
163
- result = collection.update_many(filter, update, options)
164
- update_return_doc(result)
165
- end
166
-
167
- def update_one(collection)
168
- result = collection.update_one(filter, update, options)
169
- update_return_doc(result)
170
- end
171
-
172
- def find_one_and_delete(collection)
173
- collection.find_one_and_delete(filter, options)
174
- end
175
-
176
- def find_one_and_replace(collection)
177
- collection.find_one_and_replace(filter, replacement, options)
178
- end
179
-
180
- def find_one_and_update(collection)
181
- collection.find_one_and_update(filter, update, options)
182
- end
183
-
184
- def options
185
- args = (arguments['options'] || {}).reduce({}) do |a, kv|
186
- a[kv.first.to_sym] = kv.last
187
- a
188
- end
189
-
190
- ARGUMENT_MAP.reduce(args) do |opts, (key, value)|
191
- arguments.key?(value) ? opts.merge!(key => send(key)) : opts
192
- end
193
- end
194
-
195
- def collation
196
- arguments['collation']
197
- end
198
-
199
- def replacement
200
- arguments['replacement']
201
- end
202
-
203
- def sort
204
- arguments['sort']
205
- end
206
-
207
- def projection
208
- arguments['projection']
209
- end
210
-
211
- def documents
212
- arguments['documents']
213
- end
214
-
215
- def document
216
- arguments['document']
217
- end
218
-
219
- def write_concern
220
- arguments['writeConcern']
221
- end
222
-
223
- def ordered
224
- arguments['ordered']
225
- end
226
-
227
- def filter
228
- arguments['filter']
229
- end
230
-
231
- def array_filters
232
- arguments['arrayFilters']
233
- end
234
-
235
- def requests
236
- arguments['requests'].map do |request|
237
- case request.keys.first
238
- when 'insertOne' then
239
- { insert_one: request['insertOne']['document'] }
240
- when 'updateOne' then
241
- update = request['updateOne']
242
- { update_one: { filter: update['filter'], update: update['update'] } }
243
- when 'name' then
244
- bulk_request(request)
245
- end
246
- end
247
- end
248
-
249
- def bulk_request(request)
250
- op_name = OPERATIONS[request['name']]
251
- op = { op_name => {} }
252
- op[op_name].merge!(filter: request['arguments']['filter']) if request['arguments']['filter']
253
- op[op_name].merge!(update: request['arguments']['update']) if request['arguments']['update']
254
- op[op_name].merge!(upsert: request['arguments']['upsert']) if request['arguments']['upsert']
255
- op[op_name].merge!(replacement: request['arguments']['replacement']) if request['arguments']['replacement']
256
- op[op_name].merge!(array_filters: request['arguments']['arrayFilters']) if request['arguments']['arrayFilters']
257
- op[op_name] = request['arguments']['document'] if request['arguments']['document']
258
- op
259
- end
260
-
261
- def upsert
262
- arguments['upsert']
263
- end
264
-
265
- def return_document
266
- case arguments['returnDocument']
267
- when 'Before'
268
- :before
269
- when 'After'
270
- :after
271
- end
272
- end
273
-
274
- def update
275
- arguments['update']
276
- end
277
-
278
- def arguments
279
- @spec['arguments']
280
- end
281
- end
282
- end
283
- end
284
- end