mongo 2.1.0.beta → 2.2.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 (342) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/README.md +10 -3
  4. data/Rakefile +1 -7
  5. data/lib/mongo/address/ipv4.rb +6 -1
  6. data/lib/mongo/address/unix.rb +2 -2
  7. data/lib/mongo/address.rb +32 -10
  8. data/lib/mongo/auth/cr/conversation.rb +1 -1
  9. data/lib/mongo/auth/ldap/conversation.rb +7 -3
  10. data/lib/mongo/auth/scram/conversation.rb +9 -3
  11. data/lib/mongo/auth/user/view.rb +23 -2
  12. data/lib/mongo/auth/x509/conversation.rb +1 -1
  13. data/lib/mongo/bulk_write/combineable.rb +51 -0
  14. data/lib/mongo/bulk_write/ordered_combiner.rb +55 -0
  15. data/lib/mongo/bulk_write/result.rb +61 -8
  16. data/lib/mongo/bulk_write/result_combiner.rb +117 -0
  17. data/lib/mongo/bulk_write/transformable.rb +132 -0
  18. data/lib/mongo/bulk_write/unordered_combiner.rb +52 -0
  19. data/lib/mongo/bulk_write/validatable.rb +62 -0
  20. data/lib/mongo/bulk_write.rb +164 -23
  21. data/lib/mongo/client.rb +75 -18
  22. data/lib/mongo/cluster/topology/replica_set.rb +8 -6
  23. data/lib/mongo/cluster/topology/unknown.rb +5 -2
  24. data/lib/mongo/cluster.rb +85 -5
  25. data/lib/mongo/collection/view/aggregation.rb +19 -45
  26. data/lib/mongo/collection/view/builder/aggregation.rb +98 -0
  27. data/lib/mongo/collection/view/builder/find_command.rb +111 -0
  28. data/lib/mongo/collection/view/builder/flags.rb +62 -0
  29. data/lib/mongo/collection/view/builder/map_reduce.rb +134 -0
  30. data/lib/mongo/collection/view/builder/modifiers.rb +80 -0
  31. data/lib/mongo/collection/view/builder/op_query.rb +83 -0
  32. data/lib/mongo/collection/view/builder.rb +20 -0
  33. data/lib/mongo/collection/view/explainable.rb +15 -0
  34. data/lib/mongo/collection/view/immutable.rb +4 -11
  35. data/lib/mongo/collection/view/iterable.rb +40 -5
  36. data/lib/mongo/collection/view/map_reduce.rb +67 -37
  37. data/lib/mongo/collection/view/readable.rb +114 -100
  38. data/lib/mongo/collection/view/writable.rb +46 -22
  39. data/lib/mongo/collection/view.rb +25 -22
  40. data/lib/mongo/collection.rb +130 -12
  41. data/lib/mongo/cursor/builder/get_more_command.rb +71 -0
  42. data/lib/mongo/cursor/builder/kill_cursors_command.rb +62 -0
  43. data/lib/mongo/cursor/builder/op_get_more.rb +61 -0
  44. data/lib/mongo/cursor/builder/op_kill_cursors.rb +56 -0
  45. data/lib/mongo/cursor/builder.rb +18 -0
  46. data/lib/mongo/cursor.rb +76 -21
  47. data/lib/mongo/database/view.rb +11 -6
  48. data/lib/mongo/database.rb +16 -6
  49. data/lib/mongo/dbref.rb +9 -9
  50. data/lib/mongo/{bulk_write/unordered_bulk_write.rb → error/closed_stream.rb} +12 -21
  51. data/lib/mongo/{bulk_write/ordered_bulk_write.rb → error/extra_file_chunk.rb} +13 -27
  52. data/lib/mongo/error/file_not_found.rb +37 -0
  53. data/lib/mongo/error/invalid_file.rb +2 -2
  54. data/lib/mongo/error/invalid_file_revision.rb +37 -0
  55. data/lib/mongo/error/invalid_uri.rb +5 -4
  56. data/lib/mongo/error/invalid_write_concern.rb +35 -0
  57. data/lib/mongo/error/missing_file_chunk.rb +38 -0
  58. data/lib/mongo/error/operation_failure.rb +33 -2
  59. data/lib/mongo/error/unchangeable_collection_option.rb +38 -0
  60. data/lib/mongo/error/unexpected_chunk_length.rb +39 -0
  61. data/lib/mongo/error.rb +8 -0
  62. data/lib/mongo/grid/file/chunk.rb +9 -9
  63. data/lib/mongo/grid/file/{metadata.rb → info.rb} +41 -39
  64. data/lib/mongo/grid/file.rb +12 -9
  65. data/lib/mongo/grid/fs_bucket.rb +448 -0
  66. data/lib/mongo/grid/stream/read.rb +208 -0
  67. data/lib/mongo/grid/stream/write.rb +187 -0
  68. data/lib/mongo/grid/stream.rb +64 -0
  69. data/lib/mongo/grid.rb +2 -1
  70. data/lib/mongo/index/view.rb +7 -4
  71. data/lib/mongo/index.rb +5 -0
  72. data/lib/mongo/loggable.rb +34 -57
  73. data/lib/mongo/logger.rb +16 -78
  74. data/lib/mongo/monitoring/command_log_subscriber.rb +38 -14
  75. data/lib/mongo/monitoring/event/command_started.rb +2 -1
  76. data/lib/mongo/monitoring/event/command_succeeded.rb +24 -2
  77. data/lib/mongo/monitoring/event/secure.rb +58 -0
  78. data/lib/mongo/monitoring/event.rb +1 -0
  79. data/lib/mongo/monitoring/publishable.rb +22 -12
  80. data/lib/mongo/monitoring.rb +1 -5
  81. data/lib/mongo/operation/commands/aggregate/result.rb +89 -0
  82. data/lib/mongo/operation/commands/aggregate.rb +64 -0
  83. data/lib/mongo/operation/commands/collections_info/result.rb +41 -0
  84. data/lib/mongo/operation/{read → commands}/collections_info.rb +5 -3
  85. data/lib/mongo/operation/commands/command.rb +47 -0
  86. data/lib/mongo/operation/commands/find/result.rb +62 -0
  87. data/lib/mongo/operation/commands/find.rb +27 -0
  88. data/lib/mongo/operation/commands/get_more/result.rb +62 -0
  89. data/lib/mongo/operation/commands/get_more.rb +27 -0
  90. data/lib/mongo/operation/{read → commands}/indexes.rb +9 -6
  91. data/lib/mongo/operation/{list_collections → commands/list_collections}/result.rb +1 -21
  92. data/lib/mongo/operation/{read → commands}/list_collections.rb +4 -32
  93. data/lib/mongo/operation/{list_indexes → commands/list_indexes}/result.rb +1 -21
  94. data/lib/mongo/operation/{read → commands}/list_indexes.rb +3 -33
  95. data/lib/mongo/operation/commands/map_reduce/result.rb +119 -0
  96. data/lib/mongo/operation/commands/map_reduce.rb +49 -0
  97. data/lib/mongo/operation/commands/parallel_scan/result.rb +64 -0
  98. data/lib/mongo/operation/commands/parallel_scan.rb +52 -0
  99. data/lib/mongo/operation/commands/user_query.rb +71 -0
  100. data/lib/mongo/operation/commands/users_info/result.rb +38 -0
  101. data/lib/mongo/operation/commands/users_info.rb +48 -0
  102. data/lib/mongo/operation/commands.rb +26 -0
  103. data/lib/mongo/operation/executable.rb +4 -68
  104. data/lib/mongo/operation/kill_cursors.rb +3 -3
  105. data/lib/mongo/operation/object_id_generator.rb +36 -0
  106. data/lib/mongo/operation/read/get_more.rb +2 -22
  107. data/lib/mongo/operation/read/query/result.rb +40 -0
  108. data/lib/mongo/operation/read/query.rb +4 -21
  109. data/lib/mongo/operation/read.rb +0 -4
  110. data/lib/mongo/operation/{read_preferrable.rb → read_preference.rb} +3 -2
  111. data/lib/mongo/operation/result.rb +43 -1
  112. data/lib/mongo/operation/specifiable.rb +59 -1
  113. data/lib/mongo/operation/write/bulk/bulkable.rb +83 -0
  114. data/lib/mongo/operation/write/bulk/delete/result.rb +67 -0
  115. data/lib/mongo/operation/write/bulk/delete.rb +71 -0
  116. data/lib/mongo/operation/write/bulk/insert/result.rb +129 -0
  117. data/lib/mongo/operation/write/bulk/insert.rb +96 -0
  118. data/lib/mongo/operation/write/bulk/legacy_mergable.rb +87 -0
  119. data/lib/mongo/operation/write/bulk/mergable.rb +71 -0
  120. data/lib/mongo/operation/write/bulk/update/result.rb +174 -0
  121. data/lib/mongo/operation/write/bulk/update.rb +81 -0
  122. data/lib/mongo/operation/write/bulk.rb +6 -3
  123. data/lib/mongo/operation/write/command/create_index.rb +0 -1
  124. data/lib/mongo/operation/write/command/create_user.rb +0 -1
  125. data/lib/mongo/operation/write/command/delete.rb +3 -3
  126. data/lib/mongo/operation/write/command/drop_index.rb +0 -1
  127. data/lib/mongo/operation/write/command/insert.rb +4 -3
  128. data/lib/mongo/operation/write/command/remove_user.rb +0 -1
  129. data/lib/mongo/operation/write/command/update.rb +6 -4
  130. data/lib/mongo/operation/write/command/update_user.rb +0 -1
  131. data/lib/mongo/operation/write/command/writable.rb +13 -18
  132. data/lib/mongo/operation/write/create_index.rb +4 -27
  133. data/lib/mongo/operation/write/create_user.rb +4 -30
  134. data/lib/mongo/operation/write/delete.rb +6 -29
  135. data/lib/mongo/operation/write/drop_index.rb +3 -3
  136. data/lib/mongo/operation/write/gle.rb +49 -0
  137. data/lib/mongo/operation/write/idable.rb +24 -2
  138. data/lib/mongo/operation/write/insert.rb +2 -24
  139. data/lib/mongo/operation/write/remove_user.rb +4 -27
  140. data/lib/mongo/operation/write/update.rb +13 -36
  141. data/lib/mongo/operation/write/update_user.rb +4 -30
  142. data/lib/mongo/operation/write/write_command_enabled.rb +53 -0
  143. data/lib/mongo/operation/write.rb +2 -0
  144. data/lib/mongo/operation.rb +33 -5
  145. data/lib/mongo/options/mapper.rb +26 -2
  146. data/lib/mongo/options/redacted.rb +156 -0
  147. data/lib/mongo/options.rb +1 -0
  148. data/lib/mongo/protocol/bit_vector.rb +11 -9
  149. data/lib/mongo/protocol/delete.rb +78 -3
  150. data/lib/mongo/protocol/get_more.rb +59 -2
  151. data/lib/mongo/protocol/insert.rb +73 -1
  152. data/lib/mongo/protocol/kill_cursors.rb +66 -4
  153. data/lib/mongo/protocol/message.rb +44 -20
  154. data/lib/mongo/protocol/query.rb +153 -65
  155. data/lib/mongo/protocol/reply.rb +92 -1
  156. data/lib/mongo/protocol/serializers.rb +49 -40
  157. data/lib/mongo/protocol/update.rb +93 -1
  158. data/lib/mongo/retryable.rb +101 -0
  159. data/lib/mongo/server/connectable.rb +28 -8
  160. data/lib/mongo/server/connection.rb +52 -10
  161. data/lib/mongo/server/connection_pool/queue.rb +15 -0
  162. data/lib/mongo/server/connection_pool.rb +12 -15
  163. data/lib/mongo/server/description/features.rb +4 -2
  164. data/lib/mongo/server/description.rb +39 -3
  165. data/lib/mongo/server/monitor/connection.rb +49 -28
  166. data/lib/mongo/server/monitor.rb +3 -14
  167. data/lib/mongo/server.rb +31 -4
  168. data/lib/mongo/server_selector/selectable.rb +58 -32
  169. data/lib/mongo/server_selector.rb +19 -10
  170. data/lib/mongo/socket/ssl.rb +4 -1
  171. data/lib/mongo/socket/tcp.rb +2 -2
  172. data/lib/mongo/socket/unix.rb +5 -8
  173. data/lib/mongo/socket.rb +11 -4
  174. data/lib/mongo/uri.rb +245 -139
  175. data/lib/mongo/version.rb +1 -1
  176. data/lib/mongo/write_concern.rb +21 -6
  177. data/lib/mongo.rb +4 -4
  178. data/mongo.gemspec +1 -2
  179. data/spec/mongo/address/unix_spec.rb +1 -1
  180. data/spec/mongo/address_spec.rb +25 -0
  181. data/spec/mongo/auth/ldap/conversation_spec.rb +43 -0
  182. data/spec/mongo/auth/user/view_spec.rb +26 -1
  183. data/spec/mongo/bulk_write/ordered_combiner_spec.rb +284 -0
  184. data/spec/mongo/bulk_write/unordered_combiner_spec.rb +239 -0
  185. data/spec/mongo/bulk_write_spec.rb +385 -161
  186. data/spec/mongo/client_spec.rb +193 -23
  187. data/spec/mongo/cluster/topology/replica_set_spec.rb +2 -0
  188. data/spec/mongo/collection/view/aggregation_spec.rb +65 -0
  189. data/spec/mongo/collection/view/builder/find_command_spec.rb +167 -0
  190. data/spec/mongo/collection/view/builder/flags_spec.rb +106 -0
  191. data/spec/mongo/collection/view/builder/modifiers_spec.rb +210 -0
  192. data/spec/mongo/collection/view/builder/op_query_spec.rb +154 -0
  193. data/spec/mongo/collection/view/explainable_spec.rb +1 -2
  194. data/spec/mongo/collection/view/immutable_spec.rb +54 -0
  195. data/spec/mongo/collection/view/map_reduce_spec.rb +104 -9
  196. data/spec/mongo/collection/view/readable_spec.rb +109 -112
  197. data/spec/mongo/collection/view_spec.rb +119 -487
  198. data/spec/mongo/collection_spec.rb +1002 -33
  199. data/spec/mongo/command_monitoring_spec.rb +64 -0
  200. data/spec/mongo/connection_string_spec.rb +115 -0
  201. data/spec/mongo/cursor/builder/get_more_command_spec.rb +160 -0
  202. data/spec/mongo/cursor/builder/op_get_more_spec.rb +52 -0
  203. data/spec/mongo/cursor_spec.rb +10 -60
  204. data/spec/mongo/database_spec.rb +81 -12
  205. data/spec/mongo/dbref_spec.rb +4 -4
  206. data/spec/mongo/grid/file/chunk_spec.rb +6 -6
  207. data/spec/mongo/grid/file/{metadata_spec.rb → info_spec.rb} +29 -17
  208. data/spec/mongo/grid/file_spec.rb +8 -8
  209. data/spec/mongo/grid/fs_bucket_spec.rb +1020 -0
  210. data/spec/mongo/grid/stream/read_spec.rb +275 -0
  211. data/spec/mongo/grid/stream/write_spec.rb +440 -0
  212. data/spec/mongo/grid/stream_spec.rb +48 -0
  213. data/spec/mongo/gridfs_spec.rb +50 -0
  214. data/spec/mongo/index/view_spec.rb +41 -0
  215. data/spec/mongo/logger_spec.rb +0 -40
  216. data/spec/mongo/monitoring/command_log_subscriber_spec.rb +76 -0
  217. data/spec/mongo/monitoring/event/command_started_spec.rb +26 -0
  218. data/spec/mongo/monitoring/event/command_succeeded_spec.rb +26 -0
  219. data/spec/mongo/monitoring/event/secure_spec.rb +57 -0
  220. data/spec/mongo/operation/{aggregate → commands/aggregate}/result_spec.rb +1 -1
  221. data/spec/mongo/operation/commands/aggregate_spec.rb +69 -0
  222. data/spec/mongo/operation/{read → commands}/collections_info_spec.rb +1 -1
  223. data/spec/mongo/operation/{command_spec.rb → commands/command_spec.rb} +1 -19
  224. data/spec/mongo/operation/{read → commands}/indexes_spec.rb +1 -1
  225. data/spec/mongo/operation/{map_reduce_spec.rb → commands/map_reduce_spec.rb} +1 -19
  226. data/spec/mongo/operation/kill_cursors_spec.rb +1 -17
  227. data/spec/mongo/operation/read/get_more_spec.rb +0 -16
  228. data/spec/mongo/operation/read/query_spec.rb +19 -16
  229. data/spec/mongo/operation/{read_preferrable_spec.rb → read_preference_spec.rb} +11 -11
  230. data/spec/mongo/operation/result_spec.rb +19 -0
  231. data/spec/mongo/operation/write/bulk/{bulk_delete_spec.rb → delete_spec.rb} +17 -28
  232. data/spec/mongo/operation/write/bulk/{bulk_insert_spec.rb → insert_spec.rb} +1 -12
  233. data/spec/mongo/operation/write/bulk/{bulk_update_spec.rb → update_spec.rb} +7 -18
  234. data/spec/mongo/operation/write/command/delete_spec.rb +18 -9
  235. data/spec/mongo/operation/write/command/insert_spec.rb +18 -9
  236. data/spec/mongo/operation/write/command/update_spec.rb +18 -9
  237. data/spec/mongo/operation/write/delete_spec.rb +3 -3
  238. data/spec/mongo/operation/write/insert_spec.rb +0 -11
  239. data/spec/mongo/operation/write/update_spec.rb +6 -6
  240. data/spec/mongo/options/redacted_spec.rb +350 -0
  241. data/spec/mongo/protocol/delete_spec.rb +4 -4
  242. data/spec/mongo/protocol/get_more_spec.rb +4 -4
  243. data/spec/mongo/protocol/insert_spec.rb +3 -3
  244. data/spec/mongo/protocol/kill_cursors_spec.rb +8 -6
  245. data/spec/mongo/protocol/query_spec.rb +21 -7
  246. data/spec/mongo/protocol/update_spec.rb +5 -5
  247. data/spec/mongo/retryable_spec.rb +221 -0
  248. data/spec/mongo/server/connection_pool/queue_spec.rb +16 -0
  249. data/spec/mongo/server/connection_pool_spec.rb +42 -6
  250. data/spec/mongo/server/connection_spec.rb +86 -1
  251. data/spec/mongo/server/description/features_spec.rb +25 -0
  252. data/spec/mongo/server/description_spec.rb +42 -0
  253. data/spec/mongo/server/monitor_spec.rb +44 -0
  254. data/spec/mongo/server_discovery_and_monitoring_spec.rb +25 -59
  255. data/spec/mongo/server_selection_rtt_spec.rb +37 -57
  256. data/spec/mongo/server_selection_spec.rb +5 -3
  257. data/spec/mongo/server_selector/nearest_spec.rb +35 -27
  258. data/spec/mongo/server_selector/primary_preferred_spec.rb +32 -30
  259. data/spec/mongo/server_selector/primary_spec.rb +21 -14
  260. data/spec/mongo/server_selector/secondary_preferred_spec.rb +28 -26
  261. data/spec/mongo/server_selector/secondary_spec.rb +24 -22
  262. data/spec/mongo/server_selector_spec.rb +87 -24
  263. data/spec/mongo/server_spec.rb +78 -15
  264. data/spec/mongo/socket/ssl_spec.rb +101 -57
  265. data/spec/mongo/socket/unix_spec.rb +52 -0
  266. data/spec/mongo/uri_spec.rb +271 -59
  267. data/spec/mongo/write_concern_spec.rb +126 -0
  268. data/spec/spec_helper.rb +29 -23
  269. data/spec/support/authorization.rb +4 -5
  270. data/spec/support/command_monitoring/bulkWrite.yml +73 -0
  271. data/spec/support/command_monitoring/command.yml +42 -0
  272. data/spec/support/command_monitoring/deleteMany.yml +55 -0
  273. data/spec/support/command_monitoring/deleteOne.yml +55 -0
  274. data/spec/support/command_monitoring/find.yml +268 -0
  275. data/spec/support/command_monitoring/insertMany.yml +81 -0
  276. data/spec/support/command_monitoring/insertOne.yml +51 -0
  277. data/spec/support/command_monitoring/updateMany.yml +67 -0
  278. data/spec/support/command_monitoring/updateOne.yml +95 -0
  279. data/spec/support/command_monitoring.rb +373 -0
  280. data/spec/support/connection_string.rb +228 -0
  281. data/spec/support/connection_string_tests/invalid-uris.yml +193 -0
  282. data/spec/support/connection_string_tests/valid-auth.yml +256 -0
  283. data/spec/support/connection_string_tests/valid-host_identifiers.yml +121 -0
  284. data/spec/support/connection_string_tests/valid-options.yml +30 -0
  285. data/spec/support/connection_string_tests/valid-unix_socket-absolute.yml +197 -0
  286. data/spec/support/connection_string_tests/valid-unix_socket-relative.yml +213 -0
  287. data/spec/support/connection_string_tests/valid-warnings.yml +55 -0
  288. data/spec/support/crud/read.rb +14 -10
  289. data/spec/support/crud/write.rb +36 -9
  290. data/spec/support/crud.rb +10 -2
  291. data/spec/support/gridfs.rb +637 -0
  292. data/spec/support/gridfs_tests/delete.yml +157 -0
  293. data/spec/support/gridfs_tests/download.yml +210 -0
  294. data/spec/support/gridfs_tests/download_by_name.yml +113 -0
  295. data/spec/support/gridfs_tests/upload.yml +158 -0
  296. data/spec/support/matchers.rb +2 -2
  297. data/spec/support/sdam/rs/equal_electionids.yml +1 -2
  298. data/spec/support/sdam/rs/new_primary_new_electionid.yml +0 -3
  299. data/spec/support/sdam/rs/primary_mismatched_me.yml +37 -0
  300. data/spec/support/sdam/rs/primary_to_no_primary_mismatched_me.yml +75 -0
  301. data/spec/support/sdam/rs/rsother_discovered.yml +24 -3
  302. data/spec/support/sdam/rs/secondary_mismatched_me.yml +37 -0
  303. data/spec/support/sdam/rs/stepdown_change_set_name.yml +59 -0
  304. data/spec/support/sdam/single/direct_connection_rsarbiter.yml +1 -1
  305. data/spec/support/sdam/single/direct_connection_rsprimary.yml +1 -1
  306. data/spec/support/sdam/single/direct_connection_rssecondary.yml +1 -1
  307. data/spec/support/sdam/single/direct_connection_slave.yml +1 -1
  308. data/spec/support/sdam/single/direct_connection_standalone.yml +1 -1
  309. data/spec/support/sdam/single/not_ok_response.yml +0 -1
  310. data/spec/support/server_discovery_and_monitoring.rb +3 -1
  311. data/spec/support/server_selection.rb +3 -1
  312. data/spec/support/shared/bulk_write.rb +192 -0
  313. data/spec/support/shared/protocol.rb +5 -5
  314. data/spec/support/shared/server_selector.rb +78 -13
  315. data/spec/support/travis.rb +1 -1
  316. data.tar.gz.sig +0 -0
  317. metadata +211 -72
  318. metadata.gz.sig +0 -0
  319. data/lib/mongo/bulk_write/bulk_writable.rb +0 -252
  320. data/lib/mongo/bulk_write/deletable.rb +0 -57
  321. data/lib/mongo/bulk_write/insertable.rb +0 -49
  322. data/lib/mongo/bulk_write/replacable.rb +0 -58
  323. data/lib/mongo/bulk_write/updatable.rb +0 -69
  324. data/lib/mongo/grid/fs.rb +0 -146
  325. data/lib/mongo/operation/aggregate/result.rb +0 -103
  326. data/lib/mongo/operation/aggregate.rb +0 -108
  327. data/lib/mongo/operation/command.rb +0 -61
  328. data/lib/mongo/operation/map_reduce/result.rb +0 -122
  329. data/lib/mongo/operation/map_reduce.rb +0 -95
  330. data/lib/mongo/operation/parallel_scan/result.rb +0 -72
  331. data/lib/mongo/operation/parallel_scan.rb +0 -76
  332. data/lib/mongo/operation/write/bulk/bulk_delete/result.rb +0 -75
  333. data/lib/mongo/operation/write/bulk/bulk_delete.rb +0 -145
  334. data/lib/mongo/operation/write/bulk/bulk_insert/result.rb +0 -130
  335. data/lib/mongo/operation/write/bulk/bulk_insert.rb +0 -132
  336. data/lib/mongo/operation/write/bulk/bulk_mergable.rb +0 -67
  337. data/lib/mongo/operation/write/bulk/bulk_update/result.rb +0 -174
  338. data/lib/mongo/operation/write/bulk/bulk_update.rb +0 -154
  339. data/lib/mongo/operation/write/bulk/legacy_bulk_mergable.rb +0 -83
  340. data/spec/mongo/grid/fs_spec.rb +0 -160
  341. data/spec/mongo/loggable_spec.rb +0 -63
  342. data/spec/mongo/operation/aggregate_spec.rb +0 -127
@@ -8,253 +8,477 @@ describe Mongo::BulkWrite do
8
8
 
9
9
  after do
10
10
  authorized_collection.delete_many
11
+ collection_with_validator.drop()
11
12
  end
12
13
 
13
- let(:bulk) do
14
- described_class.get(authorized_collection, operations, options)
14
+ let(:collection_with_validator) do
15
+ authorized_client[:validating,
16
+ :validator => { :a => { '$exists' => true } }].tap do |c|
17
+ c.create
18
+ end
15
19
  end
16
20
 
17
- describe '#get' do
21
+ describe '#execute' do
18
22
 
19
- let(:operations) do
20
- [{ insert_one: { _id: 0 } }]
21
- end
23
+ shared_examples_for 'an executable bulk write' do
22
24
 
23
- context 'When an ordered bulk write object is created' do
25
+ context 'when providing a bad operation' do
24
26
 
25
- let(:options) do
26
- { ordered: true }
27
- end
27
+ let(:requests) do
28
+ [{ not_an_operation: { _id: 0 }}]
29
+ end
28
30
 
29
- it 'returns an OrderedBulkWrite object' do
30
- expect(bulk).to be_a(Mongo::BulkWrite::OrderedBulkWrite)
31
+ it 'raises an exception' do
32
+ expect {
33
+ bulk_write.execute
34
+ }.to raise_error(Mongo::Error::InvalidBulkOperationType)
35
+ end
31
36
  end
32
- end
33
37
 
34
- context 'When an unordered bulk write object is created' do
38
+ context 'when the operations do not need to be split' do
35
39
 
36
- let(:options) do
37
- { ordered: false }
38
- end
40
+ context 'when a write error occurs' do
39
41
 
40
- it 'returns an UnorderedBulkWrite object' do
41
- expect(bulk).to be_a(Mongo::BulkWrite::UnorderedBulkWrite)
42
- end
43
- end
42
+ let(:requests) do
43
+ [
44
+ { insert_one: { _id: 0 }},
45
+ { insert_one: { _id: 1 }},
46
+ { insert_one: { _id: 0 }},
47
+ { insert_one: { _id: 1 }}
48
+ ]
49
+ end
44
50
 
45
- context 'When ordered is not specified in options' do
51
+ let(:error) do
52
+ begin
53
+ bulk_write.execute
54
+ rescue => e
55
+ e
56
+ end
57
+ end
46
58
 
47
- let(:options) do
48
- { }
49
- end
59
+ it 'raises an exception' do
60
+ expect {
61
+ bulk_write.execute
62
+ }.to raise_error(Mongo::Error::BulkWriteError)
63
+ end
50
64
 
51
- it 'returns an OrderedBulkWrite object' do
52
- expect(bulk).to be_a(Mongo::BulkWrite::OrderedBulkWrite)
53
- end
54
- end
55
- end
65
+ it 'sets the document index on the error' do
66
+ expect(error.result[Mongo::Error::WRITE_ERRORS].first['index']).to eq(2)
67
+ end
68
+ end
56
69
 
57
- describe 'Ordered bulk write' do
70
+ context 'when provided a single insert one' do
58
71
 
59
- let(:options) do
60
- { ordered: true }
61
- end
72
+ let(:requests) do
73
+ [{ insert_one: { _id: 0 }}]
74
+ end
62
75
 
63
- it_behaves_like 'a bulk write object'
76
+ let(:result) do
77
+ bulk_write.execute
78
+ end
79
+
80
+ it 'inserts the document' do
81
+ expect(result.inserted_count).to eq(1)
82
+ expect(authorized_collection.find(_id: 0).count).to eq(1)
83
+ end
84
+ end
64
85
 
65
- context 'when the batch requires splitting' do
86
+ context 'when provided multiple insert ones' do
66
87
 
67
- context 'when the operations are the same type' do
88
+ let(:requests) do
89
+ [
90
+ { insert_one: { _id: 0 }},
91
+ { insert_one: { _id: 1 }},
92
+ { insert_one: { _id: 2 }}
93
+ ]
94
+ end
68
95
 
69
- let(:error) do
70
- begin
71
- bulk.execute
72
- rescue => ex
73
- ex
96
+ let(:result) do
97
+ bulk_write.execute
98
+ end
99
+
100
+ it 'inserts the documents' do
101
+ expect(result.inserted_count).to eq(3)
102
+ expect(authorized_collection.find(_id: { '$in'=> [ 0, 1, 2 ]}).count).to eq(3)
74
103
  end
75
104
  end
76
105
 
77
- let(:operations) do
78
- [].tap do |ops|
79
- 3000.times do |i|
80
- ops << { insert_one: { _id: i } }
81
- end
82
- ops << { insert_one: { _id: 0 } }
83
- ops << { insert_one: { _id: 3001 } }
106
+ context 'when provided a single delete one' do
107
+
108
+ let(:requests) do
109
+ [{ delete_one: { filter: { _id: 0 }}}]
110
+ end
111
+
112
+ let(:result) do
113
+ bulk_write.execute
114
+ end
115
+
116
+ before do
117
+ authorized_collection.insert_one({ _id: 0 })
118
+ end
119
+
120
+ it 'deletes the document' do
121
+ expect(result.deleted_count).to eq(1)
122
+ expect(authorized_collection.find(_id: 0).count).to eq(0)
84
123
  end
85
124
  end
86
125
 
87
- it 'raises a BulkWriteError' do
88
- expect(error).to be_a(Mongo::Error::BulkWriteError)
126
+ context 'when provided multiple delete ones' do
127
+
128
+ let(:requests) do
129
+ [
130
+ { delete_one: { filter: { _id: 0 }}},
131
+ { delete_one: { filter: { _id: 1 }}},
132
+ { delete_one: { filter: { _id: 2 }}}
133
+ ]
134
+ end
135
+
136
+ let(:result) do
137
+ bulk_write.execute
138
+ end
139
+
140
+ before do
141
+ authorized_collection.insert_many([
142
+ { _id: 0 }, { _id: 1 }, { _id: 2 }
143
+ ])
144
+ end
145
+
146
+ it 'deletes the documents' do
147
+ expect(result.deleted_count).to eq(3)
148
+ expect(authorized_collection.find(_id: { '$in'=> [ 0, 1, 2 ]}).count).to eq(0)
149
+ end
89
150
  end
90
151
 
91
- it 'halts execution after first error and reports correct index' do
92
- expect(error.result[Mongo::Error::WRITE_ERRORS].first['index']).to eq(3000)
93
- expect(authorized_collection.find.count).to eq(3000)
152
+ context 'when provided a single delete many' do
153
+
154
+ let(:requests) do
155
+ [{ delete_many: { filter: { _id: 0 }}}]
156
+ end
157
+
158
+ let(:result) do
159
+ bulk_write.execute
160
+ end
161
+
162
+ before do
163
+ authorized_collection.insert_one({ _id: 0 })
164
+ end
165
+
166
+ it 'deletes the documents' do
167
+ expect(result.deleted_count).to eq(1)
168
+ expect(authorized_collection.find(_id: 0).count).to eq(0)
169
+ end
94
170
  end
95
- end
96
171
 
97
- context 'when operations are mixed types' do
172
+ context 'when provided multiple delete many ops' do
98
173
 
99
- let(:error) do
100
- begin
101
- bulk.execute
102
- rescue => ex
103
- ex
174
+ let(:requests) do
175
+ [
176
+ { delete_many: { filter: { _id: 0 }}},
177
+ { delete_many: { filter: { _id: 1 }}},
178
+ { delete_many: { filter: { _id: 2 }}}
179
+ ]
180
+ end
181
+
182
+ let(:result) do
183
+ bulk_write.execute
184
+ end
185
+
186
+ before do
187
+ authorized_collection.insert_many([
188
+ { _id: 0 }, { _id: 1 }, { _id: 2 }
189
+ ])
190
+ end
191
+
192
+ it 'deletes the documents' do
193
+ expect(result.deleted_count).to eq(3)
194
+ expect(authorized_collection.find(_id: { '$in'=> [ 0, 1, 2 ]}).count).to eq(0)
104
195
  end
105
196
  end
106
197
 
107
- let(:operations) do
108
- [].tap do |ops|
109
- 2000.times do |i|
110
- ops << { insert_one: { _id: i } }
111
- end
112
- ops << { delete_one: { _id: 0 } }
113
- ops << { insert_one: { _id: 1 } }
114
- ops << { insert_one: { _id: 2000 } }
198
+ context 'when providing a single replace one' do
199
+
200
+ let(:requests) do
201
+ [{ replace_one: { filter: { _id: 0 }, replacement: { name: 'test' }}}]
202
+ end
203
+
204
+ let(:result) do
205
+ bulk_write.execute
206
+ end
207
+
208
+ before do
209
+ authorized_collection.insert_one({ _id: 0 })
210
+ end
211
+
212
+ it 'replaces the document' do
213
+ expect(result.modified_count).to eq(1)
214
+ expect(authorized_collection.find(_id: 0).first[:name]).to eq('test')
115
215
  end
116
216
  end
117
217
 
118
- it 'raises a BulkWriteError error' do
119
- expect(error).to be_a(Mongo::Error::BulkWriteError)
218
+ context 'when providing a single update one' do
219
+
220
+ let(:requests) do
221
+ [{ update_one: { filter: { _id: 0 }, update: { "$set" => { name: 'test' }}}}]
222
+ end
223
+
224
+ let(:result) do
225
+ bulk_write.execute
226
+ end
227
+
228
+ before do
229
+ authorized_collection.insert_one({ _id: 0 })
230
+ end
231
+
232
+ it 'updates the document' do
233
+ expect(result.modified_count).to eq(1)
234
+ expect(authorized_collection.find(_id: 0).first[:name]).to eq('test')
235
+ end
120
236
  end
121
237
 
122
- it 'halts execution after first error and reports correct index' do
123
- expect(error.result[Mongo::Error::WRITE_ERRORS].first['index']).to eq(2001)
124
- expect(authorized_collection.find.count).to eq(1999)
238
+ context 'when providing a single update many' do
239
+
240
+ let(:requests) do
241
+ [{ update_many: { filter: { _id: 0 }, update: { "$set" => { name: 'test' }}}}]
242
+ end
243
+
244
+ let(:result) do
245
+ bulk_write.execute
246
+ end
247
+
248
+ before do
249
+ authorized_collection.insert_one({ _id: 0 })
250
+ end
251
+
252
+ it 'updates the documents' do
253
+ expect(result.modified_count).to eq(1)
254
+ expect(authorized_collection.find(_id: 0).first[:name]).to eq('test')
255
+ end
125
256
  end
126
257
  end
127
258
 
128
- context 'when the operations exceed the max bson size' do
259
+ context 'when the operations need to be split' do
129
260
 
130
- let(:error) do
131
- begin
132
- bulk.execute
133
- rescue => ex
134
- ex
261
+ context 'when a write error occurs' do
262
+
263
+ let(:requests) do
264
+ 1001.times.map do |i|
265
+ { insert_one: { _id: i }}
266
+ end
267
+ end
268
+
269
+ let(:error) do
270
+ begin
271
+ bulk_write.execute
272
+ rescue => e
273
+ e
274
+ end
275
+ end
276
+
277
+ it 'raises an exception' do
278
+ expect {
279
+ requests.push({ insert_one: { _id: 5 }})
280
+ bulk_write.execute
281
+ }.to raise_error(Mongo::Error::BulkWriteError)
282
+ end
283
+
284
+ it 'sets the document index on the error' do
285
+ requests.push({ insert_one: { _id: 5 }})
286
+ expect(error.result[Mongo::Error::WRITE_ERRORS].first['index']).to eq(1001)
135
287
  end
136
288
  end
137
289
 
138
- let(:operations) do
139
- [].tap do |ops|
140
- 6.times do |i|
141
- ops << { insert_one: { _id: i, x: 'y'*4000000 } }
290
+ context 'when no write errors occur' do
291
+
292
+ let(:requests) do
293
+ 1001.times.map do |i|
294
+ { insert_one: { _id: i }}
142
295
  end
143
- ops << { insert_one: { _id: 0 } }
144
- ops << { insert_one: { _id: 100 } }
296
+ end
297
+
298
+ let(:result) do
299
+ bulk_write.execute
300
+ end
301
+
302
+ it 'inserts the documents' do
303
+ expect(result.inserted_count).to eq(1001)
304
+ end
305
+ end
306
+ end
307
+
308
+ context 'when an operation exceeds the max bson size' do
309
+
310
+ let(:requests) do
311
+ 5.times.map do |i|
312
+ { insert_one: { _id: i, x: 'y' * 4000000 }}
145
313
  end
146
314
  end
147
315
 
148
- it 'raises a BulkWriteError error' do
149
- expect(error).to be_a(Mongo::Error::BulkWriteError)
316
+ let(:result) do
317
+ bulk_write.execute
150
318
  end
151
319
 
152
- it 'splits messages into multiple messages' do
153
- error
154
- expect(authorized_collection.find.count).to eq(6)
320
+ it 'inserts the documents' do
321
+ expect(result.inserted_count).to eq(5)
155
322
  end
156
323
  end
157
324
  end
325
+
326
+ context 'when the bulk write is unordered' do
327
+
328
+ let(:bulk_write) do
329
+ described_class.new(authorized_collection, requests, ordered: false)
330
+ end
331
+
332
+ it_behaves_like 'an executable bulk write'
333
+ end
334
+
335
+ context 'when the bulk write is ordered' do
336
+
337
+ let(:bulk_write) do
338
+ described_class.new(authorized_collection, requests, ordered: true)
339
+ end
340
+
341
+ it_behaves_like 'an executable bulk write'
342
+ end
158
343
  end
159
344
 
160
- describe 'Unordered bulk write' do
345
+ describe '#initialize' do
161
346
 
162
- let(:options) do
163
- { ordered: false }
347
+ let(:requests) do
348
+ [{ insert_one: { _id: 0 }}]
164
349
  end
165
350
 
166
- it_behaves_like 'a bulk write object'
351
+ shared_examples_for 'a bulk write initializer' do
167
352
 
168
- context 'when the operations exceed the max batch size' do
353
+ it 'sets the collection' do
354
+ expect(bulk_write.collection).to eq(authorized_collection)
355
+ end
169
356
 
170
- context 'when operations are all the same type' do
357
+ it 'sets the requests' do
358
+ expect(bulk_write.requests).to eq(requests)
359
+ end
360
+ end
171
361
 
172
- let(:error) do
173
- begin
174
- bulk.execute
175
- rescue => ex
176
- ex
177
- end
178
- end
362
+ context 'when no options are provided' do
179
363
 
180
- let(:operations) do
181
- [].tap do |ops|
182
- 3000.times do |i|
183
- ops << { insert_one: { _id: i } }
184
- end
185
- ops << { insert_one: { _id: 0 } }
186
- ops << { insert_one: { _id: 3001 } }
187
- end
188
- end
364
+ let(:bulk_write) do
365
+ described_class.new(authorized_collection, requests)
366
+ end
189
367
 
190
- it 'raises a BulkWriteError error' do
191
- expect(error).to be_a(Mongo::Error::BulkWriteError)
192
- end
368
+ it 'sets empty options' do
369
+ expect(bulk_write.options).to be_empty
370
+ end
193
371
 
194
- it 'does not halt execution after first error' do
195
- expect(error.result[Mongo::Error::WRITE_ERRORS].first['index']).to eq(3000)
196
- expect(authorized_collection.find.count).to eq(3001)
197
- end
372
+ it_behaves_like 'a bulk write initializer'
373
+ end
374
+
375
+ context 'when options are provided' do
376
+
377
+ let(:bulk_write) do
378
+ described_class.new(authorized_collection, requests, ordered: true)
198
379
  end
199
380
 
200
- context 'when operations are mixed types' do
381
+ it 'sets the options' do
382
+ expect(bulk_write.options).to eq(ordered: true)
383
+ end
384
+ end
201
385
 
202
- let(:error) do
203
- begin
204
- bulk.execute
205
- rescue => ex
206
- ex
207
- end
386
+ context 'when nil options are provided' do
387
+
388
+ let(:bulk_write) do
389
+ described_class.new(authorized_collection, requests, nil)
390
+ end
391
+
392
+ it 'sets empty options' do
393
+ expect(bulk_write.options).to be_empty
394
+ end
395
+ end
396
+ end
397
+
398
+ describe '#ordered?' do
399
+
400
+ context 'when no option provided' do
401
+
402
+ let(:bulk_write) do
403
+ described_class.new(authorized_collection, [])
404
+ end
405
+
406
+ it 'returns true' do
407
+ expect(bulk_write).to be_ordered
408
+ end
409
+ end
410
+
411
+ context 'when the option is provided' do
412
+
413
+ context 'when the option is true' do
414
+
415
+ let(:bulk_write) do
416
+ described_class.new(authorized_collection, [], ordered: true)
208
417
  end
209
418
 
210
- let(:operations) do
211
- [].tap do |ops|
212
- 2000.times do |i|
213
- ops << { insert_one: { _id: i } }
214
- end
215
- ops << { delete_one: { _id: 0 } }
216
- ops << { insert_one: { _id: 1 } }
217
- ops << { insert_one: { _id: 2000 } }
218
- end
419
+ it 'returns true' do
420
+ expect(bulk_write).to be_ordered
219
421
  end
422
+ end
423
+
424
+ context 'when the option is false' do
220
425
 
221
- it 'raises a BulkWriteError error' do
222
- expect(error).to be_a(Mongo::Error::BulkWriteError)
426
+ let(:bulk_write) do
427
+ described_class.new(authorized_collection, [], ordered: false)
223
428
  end
224
429
 
225
- it 'does not halt execution after first error' do
226
- expect(error.result[Mongo::Error::WRITE_ERRORS].first['index']).to eq(2001)
227
- expect(authorized_collection.find.count).to eq(2000)
430
+ it 'returns false' do
431
+ expect(bulk_write).to_not be_ordered
228
432
  end
229
433
  end
434
+ end
435
+ end
230
436
 
231
- context 'when the operations exceed the max bson size' do
437
+ describe 'when the collection has a validator', if: find_command_enabled? do
232
438
 
233
- let(:error) do
234
- begin
235
- bulk.execute
236
- rescue => ex
237
- ex
238
- end
439
+ before do
440
+ collection_with_validator.insert_many([{ :a => 1 }, { :a => 2 }])
441
+ end
442
+
443
+ after do
444
+ collection_with_validator.delete_many
445
+ end
446
+
447
+ context 'when the documents are invalid' do
448
+
449
+ let(:ops) do
450
+ [
451
+ { insert_one: { :x => 1 } },
452
+ { update_one: { filter: { :a => 1 },
453
+ update: { '$unset' => { :a => '' } } } },
454
+ { replace_one: { filter: { :a => 2 },
455
+ replacement: { :x => 2 } } }
456
+ ]
457
+ end
458
+
459
+ context 'when bypass_document_validation is not set' do
460
+
461
+ let(:result) do
462
+ collection_with_validator.bulk_write(ops)
239
463
  end
240
464
 
241
- let(:operations) do
242
- [].tap do |ops|
243
- 15.times do |i|
244
- ops << { insert_one: { _id: i, x: 'y'*4000000 } }
245
- end
246
- ops << { insert_one: { _id: 0 } }
247
- ops << { insert_one: { _id: 100 } }
248
- end
465
+ it 'raises BulkWriteError' do
466
+ expect {
467
+ result
468
+ }.to raise_exception(Mongo::Error::BulkWriteError)
249
469
  end
470
+ end
471
+
472
+ context 'when bypass_document_validation is true' do
250
473
 
251
- it 'raises a BulkWriteError error' do
252
- expect(error).to be_a(Mongo::Error::BulkWriteError)
474
+ let(:result2) do
475
+ collection_with_validator.bulk_write(
476
+ ops, :bypass_document_validation => true)
253
477
  end
254
478
 
255
- it 'splits messages into multiple messages' do
256
- error
257
- expect(authorized_collection.find.count).to eq(16)
479
+ it 'executes successfully' do
480
+ expect(result2.modified_count).to eq(2)
481
+ expect(result2.inserted_count).to eq(1)
258
482
  end
259
483
  end
260
484
  end