mongo 2.1.0.beta → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -4,6 +4,17 @@ describe Mongo::Collection do
4
4
 
5
5
  after do
6
6
  authorized_collection.delete_many
7
+ collection_with_validator.drop()
8
+ end
9
+
10
+ let(:collection_invalid_write_concern) do
11
+ authorized_collection.client.with(write: { w: (WRITE_CONCERN[:w] + 1) })[authorized_collection.name]
12
+ end
13
+ let(:collection_with_validator) do
14
+ authorized_client[:validating,
15
+ :validator => { :a => { '$exists' => true } }].tap do |c|
16
+ c.create
17
+ end
7
18
  end
8
19
 
9
20
  describe '#==' do
@@ -86,6 +97,172 @@ describe Mongo::Collection do
86
97
  end
87
98
  end
88
99
 
100
+ describe '#with' do
101
+
102
+ let(:client) do
103
+ Mongo::Client.new(ADDRESSES)
104
+ end
105
+
106
+ let(:database) do
107
+ Mongo::Database.new(client, :test)
108
+ end
109
+
110
+ let(:collection) do
111
+ database.collection(:users)
112
+ end
113
+
114
+ let(:new_collection) do
115
+ collection.with(new_options)
116
+ end
117
+
118
+ context 'when new read options are provided' do
119
+
120
+ let(:new_options) do
121
+ { read: { mode: :secondary } }
122
+ end
123
+
124
+ it 'returns a new collection' do
125
+ expect(new_collection).not_to be(collection)
126
+ end
127
+
128
+ it 'sets the new read options on the new collection' do
129
+ expect(new_collection.read_preference).to eq(Mongo::ServerSelector.get(new_options[:read]))
130
+ end
131
+
132
+ context 'when the client has a server selection timeout setting' do
133
+
134
+ let(:client) do
135
+ Mongo::Client.new(ADDRESSES, server_selection_timeout: 2)
136
+ end
137
+
138
+ let(:server_selection_timeout) do
139
+ new_collection.read_preference.server_selection_timeout
140
+ end
141
+
142
+ it 'keeps the server_selection_timeout setting from client' do
143
+ expect(server_selection_timeout).to eq(client.options[:server_selection_timeout])
144
+ end
145
+ end
146
+
147
+ context 'when the client has a read preference set' do
148
+
149
+ let(:client) do
150
+ Mongo::Client.new(ADDRESSES, read: { mode: :primary_preferred })
151
+ end
152
+
153
+ it 'sets the new read options on the new collection' do
154
+ expect(new_collection.read_preference).to eq(Mongo::ServerSelector.get(new_options[:read]))
155
+ end
156
+ end
157
+
158
+ context 'when the client has a read preference and server selection timeout set' do
159
+
160
+ let(:client) do
161
+ Mongo::Client.new(ADDRESSES, read: { mode: :primary_preferred }, server_selection_timeout: 2)
162
+ end
163
+
164
+ let(:server_selection_timeout) do
165
+ new_collection.read_preference.server_selection_timeout
166
+ end
167
+
168
+ it 'sets the new read options on the new collection' do
169
+ expect(new_collection.read_preference).to eq(Mongo::ServerSelector.get(new_options[:read]))
170
+ end
171
+
172
+ it 'keeps the server_selection_timeout setting from client' do
173
+ expect(server_selection_timeout).to eq(client.options[:server_selection_timeout])
174
+ end
175
+ end
176
+ end
177
+
178
+ context 'when new write options are provided' do
179
+
180
+ let(:new_options) do
181
+ { write: { w: 5 } }
182
+ end
183
+
184
+ it 'returns a new collection' do
185
+ expect(new_collection).not_to be(collection)
186
+ end
187
+
188
+ it 'sets the new write options on the new collection' do
189
+ expect(new_collection.write_concern.options).to eq(Mongo::WriteConcern.get(new_options[:write]).options)
190
+ end
191
+
192
+ context 'when the client has a write concern set' do
193
+
194
+ let(:client) do
195
+ Mongo::Client.new(ADDRESSES, write: { w: 10 })
196
+ end
197
+
198
+ it 'sets the new write options on the new collection' do
199
+ expect(new_collection.write_concern.options).to eq(Mongo::WriteConcern.get(new_options[:write]).options)
200
+ end
201
+ end
202
+ end
203
+
204
+ context 'when new read and write options are provided' do
205
+
206
+ let(:new_options) do
207
+ {
208
+ read: { mode: :secondary },
209
+ write: { w: 4}
210
+ }
211
+ end
212
+
213
+ it 'returns a new collection' do
214
+ expect(new_collection).not_to be(collection)
215
+ end
216
+
217
+ it 'sets the new read options on the new collection' do
218
+ expect(new_collection.read_preference).to eq(Mongo::ServerSelector.get(new_options[:read]))
219
+ end
220
+
221
+ it 'sets the new write options on the new collection' do
222
+ expect(new_collection.write_concern.options).to eq(Mongo::WriteConcern.get(new_options[:write]).options)
223
+ end
224
+
225
+ context 'when the client has a server selection timeout setting' do
226
+
227
+ let(:client) do
228
+ Mongo::Client.new(ADDRESSES, server_selection_timeout: 2)
229
+ end
230
+
231
+ let(:server_selection_timeout) do
232
+ new_collection.read_preference.server_selection_timeout
233
+ end
234
+
235
+ it 'keeps the server_selection_timeout setting from client' do
236
+ expect(server_selection_timeout).to eq(client.options[:server_selection_timeout])
237
+ end
238
+ end
239
+
240
+ context 'when the client has a read preference set' do
241
+
242
+ let(:client) do
243
+ Mongo::Client.new(ADDRESSES, read: { mode: :primary_preferred })
244
+ end
245
+
246
+ it 'sets the new read options on the new collection' do
247
+ expect(new_collection.read_preference).to eq(Mongo::ServerSelector.get(new_options[:read]))
248
+ end
249
+ end
250
+ end
251
+
252
+ context 'when neither read nor write options are provided' do
253
+
254
+ let(:new_options) do
255
+ { some_option: 'invalid' }
256
+ end
257
+
258
+ it 'raises an error' do
259
+ expect {
260
+ new_collection
261
+ }.to raise_exception(Mongo::Error::UnchangeableCollectionOption)
262
+ end
263
+ end
264
+ end
265
+
89
266
  describe '#capped?' do
90
267
 
91
268
  let(:database) do
@@ -170,6 +347,10 @@ describe Mongo::Collection do
170
347
  collection.create
171
348
  end
172
349
 
350
+ let(:options) do
351
+ { :capped => true, :size => 1024 }
352
+ end
353
+
173
354
  after do
174
355
  collection.drop
175
356
  end
@@ -187,22 +368,62 @@ describe Mongo::Collection do
187
368
  end
188
369
  end
189
370
 
371
+ shared_examples 'a validated collection command' do
372
+
373
+ let!(:response) do
374
+ collection.create
375
+ end
376
+
377
+ let(:options) do
378
+ { :validator => { fieldName: { '$gte' => 1024 } },
379
+ :validationLevel => 'strict' }
380
+ end
381
+
382
+ let(:collection_info) do
383
+ database.list_collections.find { |i| i['name'] == 'specs' }
384
+ end
385
+
386
+ after do
387
+ collection.drop
388
+ end
389
+
390
+ it 'executes the command' do
391
+ expect(response).to be_successful
392
+ end
393
+
394
+ it 'sets the collection with validators' do
395
+ expect(collection_info['options']['validator']).to eq({ 'fieldName' => { '$gte' => 1024 } })
396
+ end
397
+
398
+ it 'creates the collection in the database' do
399
+ expect(database.collection_names).to include('specs')
400
+ end
401
+ end
402
+
190
403
  context 'when instantiating a collection directly' do
191
404
 
192
405
  let(:collection) do
193
- described_class.new(database, :specs, :capped => true, :size => 1024)
406
+ described_class.new(database, :specs, options)
194
407
  end
195
408
 
196
409
  it_behaves_like 'a capped collection command'
410
+
411
+ context 'when validators can be set', if: find_command_enabled? do
412
+ it_behaves_like 'a validated collection command'
413
+ end
197
414
  end
198
415
 
199
416
  context 'when instantiating a collection through the database' do
200
417
 
201
418
  let(:collection) do
202
- authorized_client[:specs, :capped => true, :size => 1024]
419
+ authorized_client[:specs, options]
203
420
  end
204
421
 
205
422
  it_behaves_like 'a capped collection command'
423
+
424
+ context 'when validators can be set', if: find_command_enabled? do
425
+ it_behaves_like 'a validated collection command'
426
+ end
206
427
  end
207
428
  end
208
429
  end
@@ -244,29 +465,29 @@ describe Mongo::Collection do
244
465
 
245
466
  describe '#find' do
246
467
 
247
- context 'when provided a selector' do
468
+ context 'when provided a filter' do
248
469
 
249
470
  let(:view) do
250
471
  authorized_collection.find(name: 1)
251
472
  end
252
473
 
253
- it 'returns a authorized_collection view for the selector' do
254
- expect(view.selector).to eq(name: 1)
474
+ it 'returns a authorized_collection view for the filter' do
475
+ expect(view.filter).to eq('name' => 1)
255
476
  end
256
477
  end
257
478
 
258
- context 'when provided no selector' do
479
+ context 'when provided no filter' do
259
480
 
260
481
  let(:view) do
261
482
  authorized_collection.find
262
483
  end
263
484
 
264
- it 'returns a authorized_collection view with an empty selector' do
265
- expect(view.selector).to be_empty
485
+ it 'returns a authorized_collection view with an empty filter' do
486
+ expect(view.filter).to be_empty
266
487
  end
267
488
  end
268
489
 
269
- context 'when providing a bad selector' do
490
+ context 'when providing a bad filter' do
270
491
 
271
492
  let(:view) do
272
493
  authorized_collection.find('$or' => [])
@@ -300,6 +521,50 @@ describe Mongo::Collection do
300
521
  end
301
522
  end
302
523
 
524
+ context 'when the user is not authorized', if: auth_enabled? do
525
+
526
+ let(:view) do
527
+ unauthorized_collection.find
528
+ end
529
+
530
+ it 'iterates over the documents' do
531
+ expect {
532
+ view.each{ |document| document }
533
+ }.to raise_error(Mongo::Error::OperationFailure)
534
+ end
535
+ end
536
+
537
+ context 'when documents contain potential error message fields' do
538
+
539
+ [ Mongo::Error::ERRMSG, Mongo::Error::ERROR, Mongo::Operation::Result::OK ].each do |field|
540
+
541
+ context "when the document contains a '#{field}' field" do
542
+
543
+ let(:value) do
544
+ 'testing'
545
+ end
546
+
547
+ let(:view) do
548
+ authorized_collection.find
549
+ end
550
+
551
+ before do
552
+ authorized_collection.insert_one({ field => value })
553
+ end
554
+
555
+ after do
556
+ authorized_collection.delete_many
557
+ end
558
+
559
+ it 'iterates over the documents' do
560
+ view.each do |document|
561
+ expect(document[field]).to eq(value)
562
+ end
563
+ end
564
+ end
565
+ end
566
+ end
567
+
303
568
  context 'when provided options' do
304
569
 
305
570
  let(:view) do
@@ -324,7 +589,7 @@ describe Mongo::Collection do
324
589
  end
325
590
 
326
591
  it 'returns a view with :batch_size set' do
327
- expect(view.options[:batch_size]).to be(options[:batch_size])
592
+ expect(view.options[:batch_size]).to eq(options[:batch_size])
328
593
  end
329
594
  end
330
595
 
@@ -335,7 +600,7 @@ describe Mongo::Collection do
335
600
  end
336
601
 
337
602
  it 'returns a view with :comment set' do
338
- expect(view.options[:comment]).to be(options[:comment])
603
+ expect(view.modifiers[:$comment]).to eq(options[:comment])
339
604
  end
340
605
  end
341
606
 
@@ -346,10 +611,12 @@ describe Mongo::Collection do
346
611
  end
347
612
 
348
613
  it 'returns a view with :cursor_type set' do
349
- expect(view.options[:cursor_type]).to be(options[:cursor_type])
614
+ expect(view.options[:cursor_type]).to eq(options[:cursor_type])
350
615
  end
351
616
  end
352
617
 
618
+ #limit
619
+
353
620
  context 'when provided :max_time_ms' do
354
621
 
355
622
  let(:options) do
@@ -357,18 +624,22 @@ describe Mongo::Collection do
357
624
  end
358
625
 
359
626
  it 'returns a view with :max_time_ms set' do
360
- expect(view.options[:max_time_ms]).to be(options[:max_time_ms])
627
+ expect(view.modifiers[:$maxTimeMS]).to eq(options[:max_time_ms])
361
628
  end
362
629
  end
363
630
 
364
631
  context 'when provided :modifiers' do
365
632
 
366
633
  let(:options) do
367
- { modifiers: { :$orderby => Mongo::Index::ASCENDING } }
634
+ { modifiers: { '$orderby' => Mongo::Index::ASCENDING } }
368
635
  end
369
636
 
370
637
  it 'returns a view with modifiers set' do
371
- expect(view.options[:modifiers]).to be(options[:modifiers])
638
+ expect(view.modifiers).to eq(options[:modifiers])
639
+ end
640
+
641
+ it 'dups the modifiers hash' do
642
+ expect(view.modifiers).not_to be(options[:modifiers])
372
643
  end
373
644
  end
374
645
 
@@ -379,7 +650,7 @@ describe Mongo::Collection do
379
650
  end
380
651
 
381
652
  it 'returns a view with :no_cursor_timeout set' do
382
- expect(view.options[:no_cursor_timeout]).to be(options[:no_cursor_timeout])
653
+ expect(view.options[:no_cursor_timeout]).to eq(options[:no_cursor_timeout])
383
654
  end
384
655
  end
385
656
 
@@ -390,7 +661,7 @@ describe Mongo::Collection do
390
661
  end
391
662
 
392
663
  it 'returns a view with :oplog_replay set' do
393
- expect(view.options[:oplog_replay]).to be(options[:oplog_replay])
664
+ expect(view.options[:oplog_replay]).to eq(options[:oplog_replay])
394
665
  end
395
666
  end
396
667
 
@@ -401,7 +672,7 @@ describe Mongo::Collection do
401
672
  end
402
673
 
403
674
  it 'returns a view with :projection set' do
404
- expect(view.options[:projection]).to be(options[:projection])
675
+ expect(view.options[:projection]).to eq(options[:projection])
405
676
  end
406
677
  end
407
678
 
@@ -412,7 +683,7 @@ describe Mongo::Collection do
412
683
  end
413
684
 
414
685
  it 'returns a view with :skip set' do
415
- expect(view.options[:skip]).to be(options[:skip])
686
+ expect(view.options[:skip]).to eq(options[:skip])
416
687
  end
417
688
  end
418
689
 
@@ -423,7 +694,7 @@ describe Mongo::Collection do
423
694
  end
424
695
 
425
696
  it 'returns a view with :sort set' do
426
- expect(view.options[:sort]).to be(options[:sort])
697
+ expect(view.modifiers[:$orderby]).to eq(options[:sort])
427
698
  end
428
699
  end
429
700
  end
@@ -433,6 +704,7 @@ describe Mongo::Collection do
433
704
 
434
705
  after do
435
706
  authorized_collection.delete_many
707
+ collection_with_validator.delete_many
436
708
  end
437
709
 
438
710
  let(:result) do
@@ -446,12 +718,112 @@ describe Mongo::Collection do
446
718
  it 'contains the ids in the result' do
447
719
  expect(result.inserted_ids.size).to eq(2)
448
720
  end
721
+
722
+ context 'when the client has a custom id generator' do
723
+
724
+ let(:generator) do
725
+ Class.new do
726
+ def generate
727
+ 1
728
+ end
729
+ end.new
730
+ end
731
+
732
+ let(:custom_client) do
733
+ authorized_client.with(id_generator: generator)
734
+ end
735
+
736
+ let(:custom_collection) do
737
+ custom_client[TEST_COLL]
738
+ end
739
+
740
+ before do
741
+ custom_collection.insert_many([{ name: 'testing' }])
742
+ end
743
+
744
+ after do
745
+ custom_client.close
746
+ end
747
+
748
+ it 'inserts with the custom id' do
749
+ expect(custom_collection.find.first[:_id]).to eq(1)
750
+ end
751
+ end
752
+
753
+ context 'when the inserts fail' do
754
+
755
+ let(:result) do
756
+ authorized_collection.insert_many([{ _id: 1 }, { _id: 1 }])
757
+ end
758
+
759
+ it 'raises an BulkWriteError' do
760
+ expect {
761
+ result
762
+ }.to raise_exception(Mongo::Error::BulkWriteError)
763
+ end
764
+ end
765
+
766
+ context "when the documents exceed the max bson size" do
767
+
768
+ let(:documents) do
769
+ [{ '_id' => 1, 'name' => '1'*17000000 }]
770
+ end
771
+
772
+ it 'raises a MaxBSONSize error' do
773
+ expect {
774
+ authorized_collection.insert_many(documents)
775
+ }.to raise_error(Mongo::Error::MaxBSONSize)
776
+ end
777
+ end
778
+
779
+ context 'when collection has a validator', if: find_command_enabled? do
780
+
781
+ context 'when the document is valid' do
782
+
783
+ let(:result) do
784
+ collection_with_validator.insert_many([{ a: 1 }, { a: 2 }])
785
+ end
786
+
787
+ it 'inserts successfully' do
788
+ expect(result.inserted_count).to eq(2)
789
+ end
790
+ end
791
+
792
+ context 'when the document is invalid' do
793
+
794
+ context 'when bypass_document_validation is not set' do
795
+
796
+ let(:result2) do
797
+ collection_with_validator.insert_many([{ x: 1 }, { x: 2 }])
798
+ end
799
+
800
+ it 'raises a BulkWriteError' do
801
+ expect {
802
+ result2
803
+ }.to raise_exception(Mongo::Error::BulkWriteError)
804
+ end
805
+ end
806
+
807
+ context 'when bypass_document_validation is true' do
808
+
809
+ let(:result3) do
810
+ collection_with_validator.insert_many(
811
+ [{ x: 1 }, { x: 2 }], :bypass_document_validation => true)
812
+ end
813
+
814
+ it 'inserts successfully' do
815
+ expect(result3.inserted_count).to eq(2)
816
+ end
817
+ end
818
+ end
819
+ end
449
820
  end
450
821
 
451
822
  describe '#insert_one' do
452
823
 
453
824
  after do
454
825
  authorized_collection.delete_many
826
+ collection_with_validator.delete_many
455
827
  end
456
828
 
457
829
  let(:result) do
@@ -469,6 +841,93 @@ describe Mongo::Collection do
469
841
  it 'contains the id in the result' do
470
842
  expect(result.inserted_id).to_not be_nil
471
843
  end
844
+
845
+ context 'when the insert fails' do
846
+
847
+ let(:result) do
848
+ authorized_collection.insert_one(_id: 1)
849
+ authorized_collection.insert_one(_id: 1)
850
+ end
851
+
852
+ it 'raises an OperationFailure' do
853
+ expect {
854
+ result
855
+ }.to raise_exception(Mongo::Error::OperationFailure)
856
+ end
857
+ end
858
+
859
+ context 'when the client has a custom id generator' do
860
+
861
+ let(:generator) do
862
+ Class.new do
863
+ def generate
864
+ 1
865
+ end
866
+ end.new
867
+ end
868
+
869
+ let(:custom_client) do
870
+ authorized_client.with(id_generator: generator)
871
+ end
872
+
873
+ let(:custom_collection) do
874
+ custom_client[TEST_COLL]
875
+ end
876
+
877
+ before do
878
+ custom_collection.insert_one({ name: 'testing' })
879
+ end
880
+
881
+ after do
882
+ custom_client.close
883
+ end
884
+
885
+ it 'inserts with the custom id' do
886
+ expect(custom_collection.find.first[:_id]).to eq(1)
887
+ end
888
+ end
889
+
890
+ context 'when collection has a validator', if: find_command_enabled? do
891
+
892
+ context 'when the document is valid' do
893
+
894
+ let(:result) do
895
+ collection_with_validator.insert_one({ a: 1 })
896
+ end
897
+
898
+ it 'inserts successfully' do
899
+ expect(result.written_count).to eq(1)
900
+ end
901
+ end
902
+
903
+ context 'when the document is invalid' do
904
+
905
+ context 'when bypass_document_validation is not set' do
906
+
907
+ let(:result2) do
908
+ collection_with_validator.insert_one({ x: 1 })
909
+ end
910
+
911
+ it 'raises a OperationFailure' do
912
+ expect {
913
+ result2
914
+ }.to raise_exception(Mongo::Error::OperationFailure)
915
+ end
916
+ end
917
+
918
+ context 'when bypass_document_validation is true' do
919
+
920
+ let(:result3) do
921
+ collection_with_validator.insert_one(
922
+ { x: 1 }, :bypass_document_validation => true)
923
+ end
924
+
925
+ it 'inserts successfully' do
926
+ expect(result3.written_count).to eq(1)
927
+ end
928
+ end
929
+ end
930
+ end
472
931
  end
473
932
 
474
933
  describe '#inspect' do
@@ -525,7 +984,7 @@ describe Mongo::Collection do
525
984
  context 'when options are provided' do
526
985
 
527
986
  let(:options) do
528
- { :allow_disk_use => true }
987
+ { :allow_disk_use => true, :bypass_document_validation => true }
529
988
  end
530
989
 
531
990
  it 'sets the options on the Aggregation object' do
@@ -575,7 +1034,7 @@ describe Mongo::Collection do
575
1034
  end
576
1035
 
577
1036
  it 'returns the distinct values' do
578
- expect(authorized_collection.distinct(:field)).to eq([ 'test1', 'test2', 'test3' ])
1037
+ expect(authorized_collection.distinct(:field).sort).to eq([ 'test1', 'test2', 'test3' ])
579
1038
  end
580
1039
 
581
1040
  context 'when a selector is provided' do
@@ -588,7 +1047,7 @@ describe Mongo::Collection do
588
1047
  context 'when options are provided' do
589
1048
 
590
1049
  it 'passes the options to the distinct command' do
591
- expect(authorized_collection.distinct(:field, {}, max_time_ms: 100)).to eq([ 'test1', 'test2', 'test3' ])
1050
+ expect(authorized_collection.distinct(:field, {}, max_time_ms: 100).sort).to eq([ 'test1', 'test2', 'test3' ])
592
1051
  end
593
1052
  end
594
1053
  end
@@ -636,6 +1095,19 @@ describe Mongo::Collection do
636
1095
  expect(response.deleted_count).to eq(1)
637
1096
  end
638
1097
  end
1098
+
1099
+ context 'when the delete fails', if: standalone? do
1100
+
1101
+ let(:result) do
1102
+ collection_invalid_write_concern.delete_one
1103
+ end
1104
+
1105
+ it 'raises an OperationFailure' do
1106
+ expect {
1107
+ result
1108
+ }.to raise_exception(Mongo::Error::OperationFailure)
1109
+ end
1110
+ end
639
1111
  end
640
1112
 
641
1113
  describe '#delete_many' do
@@ -661,8 +1133,87 @@ describe Mongo::Collection do
661
1133
 
662
1134
  context 'when no selector was provided' do
663
1135
 
664
- it 'deletes all the documents in the collection' do
665
- expect(authorized_collection.delete_many.deleted_count).to eq(2)
1136
+ it 'deletes all the documents in the collection' do
1137
+ expect(authorized_collection.delete_many.deleted_count).to eq(2)
1138
+ end
1139
+ end
1140
+
1141
+ context 'when the deletes fail', if: standalone? do
1142
+
1143
+ let(:result) do
1144
+ collection_invalid_write_concern.delete_many
1145
+ end
1146
+
1147
+ it 'raises an OperationFailure' do
1148
+ expect {
1149
+ result
1150
+ }.to raise_exception(Mongo::Error::OperationFailure)
1151
+ end
1152
+ end
1153
+ end
1154
+
1155
+ describe '#parallel_scan', unless: sharded? do
1156
+
1157
+ let(:documents) do
1158
+ (1..200).map do |i|
1159
+ { name: "testing-scan-#{i}" }
1160
+ end
1161
+ end
1162
+
1163
+ before do
1164
+ authorized_collection.insert_many(documents)
1165
+ end
1166
+
1167
+ let(:cursors) do
1168
+ authorized_collection.parallel_scan(2)
1169
+ end
1170
+
1171
+ it 'returns an array of cursors', if: write_command_enabled? do
1172
+ cursors.each do |cursor|
1173
+ expect(cursor.class).to be(Mongo::Cursor)
1174
+ end
1175
+ end
1176
+
1177
+ it 'returns the correct number of documents', if: write_command_enabled? do
1178
+ expect(
1179
+ cursors.reduce(0) { |total, cursor| total + cursor.to_a.size }
1180
+ ).to eq(200)
1181
+ end
1182
+
1183
+ it 'raises an error', unless: write_command_enabled? do
1184
+ expect {
1185
+ cursors
1186
+ }.to raise_error(Mongo::Error::OperationFailure)
1187
+ end
1188
+
1189
+ context 'when a read concern is provided', if: find_command_enabled? do
1190
+
1191
+ let(:result) do
1192
+ authorized_collection.with(options).parallel_scan(2)
1193
+ end
1194
+
1195
+ context 'when the read concern is valid' do
1196
+
1197
+ let(:options) do
1198
+ { read_concern: { level: 'local' }}
1199
+ end
1200
+
1201
+ it 'sends the read concern' do
1202
+ expect { result }.to_not raise_error
1203
+ end
1204
+ end
1205
+
1206
+ context 'when the read concern is not valid' do
1207
+
1208
+ let(:options) do
1209
+ { read_concern: { level: 'idontknow' }}
1210
+ end
1211
+
1212
+ it 'raises an exception' do
1213
+ expect {
1214
+ result
1215
+ }.to raise_error(Mongo::Error::OperationFailure)
1216
+ end
666
1217
  end
667
1218
  end
668
1219
  end
@@ -760,6 +1311,69 @@ describe Mongo::Collection do
760
1311
  expect(updated).to be_empty
761
1312
  end
762
1313
  end
1314
+
1315
+ context 'when the replace fails' do
1316
+
1317
+ let(:result) do
1318
+ authorized_collection.replace_one(selector, { '$s' => 'test1' })
1319
+ end
1320
+
1321
+ it 'raises an OperationFailure' do
1322
+ expect {
1323
+ result
1324
+ }.to raise_exception(Mongo::Error::OperationFailure)
1325
+ end
1326
+ end
1327
+
1328
+ context 'when collection has a validator', if: find_command_enabled? do
1329
+
1330
+ before do
1331
+ collection_with_validator.insert_one({ a: 1 })
1332
+ end
1333
+
1334
+ after do
1335
+ collection_with_validator.delete_many
1336
+ end
1337
+
1338
+ context 'when the document is valid' do
1339
+
1340
+ let(:result) do
1341
+ collection_with_validator.replace_one({ a: 1 }, { a: 5 })
1342
+ end
1343
+
1344
+ it 'replaces successfully' do
1345
+ expect(result.modified_count).to eq(1)
1346
+ end
1347
+ end
1348
+
1349
+ context 'when the document is invalid' do
1350
+
1351
+ context 'when bypass_document_validation is not set' do
1352
+
1353
+ let(:result2) do
1354
+ collection_with_validator.replace_one({ a: 1 }, { x: 5 })
1355
+ end
1356
+
1357
+ it 'raises OperationFailure' do
1358
+ expect {
1359
+ result2
1360
+ }.to raise_exception(Mongo::Error::OperationFailure)
1361
+ end
1362
+ end
1363
+
1364
+ context 'when bypass_document_validation is true' do
1365
+
1366
+ let(:result3) do
1367
+ collection_with_validator.replace_one(
1368
+ { a: 1 }, { x: 1 }, :bypass_document_validation => true)
1369
+ end
1370
+
1371
+ it 'replaces successfully' do
1372
+ expect(result3.written_count).to eq(1)
1373
+ end
1374
+ end
1375
+ end
1376
+ end
763
1377
  end
764
1378
 
765
1379
  describe '#update_many' do
@@ -853,6 +1467,72 @@ describe Mongo::Collection do
853
1467
  expect(updated).to be_empty
854
1468
  end
855
1469
  end
1470
+
1471
+ context 'when the updates fail' do
1472
+
1473
+ let(:result) do
1474
+ authorized_collection.update_many(selector, { '$s'=> { field: 'testing' } })
1475
+ end
1476
+
1477
+ it 'raises an OperationFailure' do
1478
+ expect {
1479
+ result
1480
+ }.to raise_exception(Mongo::Error::OperationFailure)
1481
+ end
1482
+ end
1483
+
1484
+ context 'when collection has a validator', if: find_command_enabled? do
1485
+
1486
+ before do
1487
+ collection_with_validator.insert_many([{ a: 1 }, { a: 2 }])
1488
+ end
1489
+
1490
+ after do
1491
+ collection_with_validator.delete_many
1492
+ end
1493
+
1494
+ context 'when the document is valid' do
1495
+
1496
+ let(:result) do
1497
+ collection_with_validator.update_many(
1498
+ { :a => { '$gt' => 0 } }, '$inc' => { :a => 1 } )
1499
+ end
1500
+
1501
+ it 'updates successfully' do
1502
+ expect(result.modified_count).to eq(2)
1503
+ end
1504
+ end
1505
+
1506
+ context 'when the document is invalid' do
1507
+
1508
+ context 'when bypass_document_validation is not set' do
1509
+
1510
+ let(:result2) do
1511
+ collection_with_validator.update_many(
1512
+ { :a => { '$gt' => 0 } }, '$unset' => { :a => '' })
1513
+ end
1514
+
1515
+ it 'raises OperationFailure' do
1516
+ expect {
1517
+ result2
1518
+ }.to raise_exception(Mongo::Error::OperationFailure)
1519
+ end
1520
+ end
1521
+
1522
+ context 'when bypass_document_validation is true' do
1523
+
1524
+ let(:result3) do
1525
+ collection_with_validator.update_many(
1526
+ { :a => { '$gt' => 0 } }, { '$unset' => { :a => '' } },
1527
+ :bypass_document_validation => true)
1528
+ end
1529
+
1530
+ it 'updates successfully' do
1531
+ expect(result3.written_count).to eq(2)
1532
+ end
1533
+ end
1534
+ end
1535
+ end
856
1536
  end
857
1537
 
858
1538
  describe '#update_one' do
@@ -942,6 +1622,72 @@ describe Mongo::Collection do
942
1622
  expect(updated).to be_empty
943
1623
  end
944
1624
  end
1625
+
1626
+ context 'when the update fails' do
1627
+
1628
+ let(:result) do
1629
+ authorized_collection.update_one(selector, { '$s'=> { field: 'testing' } })
1630
+ end
1631
+
1632
+ it 'raises an OperationFailure' do
1633
+ expect {
1634
+ result
1635
+ }.to raise_exception(Mongo::Error::OperationFailure)
1636
+ end
1637
+ end
1638
+
1639
+ context 'when collection has a validator', if: find_command_enabled? do
1640
+
1641
+ before do
1642
+ collection_with_validator.insert_one({ a: 1 })
1643
+ end
1644
+
1645
+ after do
1646
+ collection_with_validator.delete_many
1647
+ end
1648
+
1649
+ context 'when the document is valid' do
1650
+
1651
+ let(:result) do
1652
+ collection_with_validator.update_one(
1653
+ { :a => { '$gt' => 0 } }, '$inc' => { :a => 1 } )
1654
+ end
1655
+
1656
+ it 'updates successfully' do
1657
+ expect(result.modified_count).to eq(1)
1658
+ end
1659
+ end
1660
+
1661
+ context 'when the document is invalid' do
1662
+
1663
+ context 'when bypass_document_validation is not set' do
1664
+
1665
+ let(:result2) do
1666
+ collection_with_validator.update_one(
1667
+ { :a => { '$gt' => 0 } }, '$unset' => { :a => '' })
1668
+ end
1669
+
1670
+ it 'raises OperationFailure' do
1671
+ expect {
1672
+ result2
1673
+ }.to raise_exception(Mongo::Error::OperationFailure)
1674
+ end
1675
+ end
1676
+
1677
+ context 'when bypass_document_validation is true' do
1678
+
1679
+ let(:result3) do
1680
+ collection_with_validator.update_one(
1681
+ { :a => { '$gt' => 0 } }, { '$unset' => { :a => '' } },
1682
+ :bypass_document_validation => true)
1683
+ end
1684
+
1685
+ it 'updates successfully' do
1686
+ expect(result3.written_count).to eq(1)
1687
+ end
1688
+ end
1689
+ end
1690
+ end
945
1691
  end
946
1692
 
947
1693
  describe '#find_one_and_delete' do
@@ -950,11 +1696,11 @@ describe Mongo::Collection do
950
1696
  authorized_collection.insert_many([{ field: 'test1' }])
951
1697
  end
952
1698
 
953
- context 'when a matching document is found' do
1699
+ let(:selector) do
1700
+ { field: 'test1' }
1701
+ end
954
1702
 
955
- let(:selector) do
956
- { field: 'test1' }
957
- end
1703
+ context 'when a matching document is found' do
958
1704
 
959
1705
  context 'when no options are provided' do
960
1706
 
@@ -1026,18 +1772,55 @@ describe Mongo::Collection do
1026
1772
  expect(document).to be_nil
1027
1773
  end
1028
1774
  end
1029
- end
1030
1775
 
1031
- describe '#find_one_and_update' do
1776
+ context 'when the operation fails', if: write_command_enabled? do
1032
1777
 
1033
- before do
1034
- authorized_collection.insert_many([{ field: 'test1' }])
1778
+ let(:result) do
1779
+ authorized_collection.find_one_and_delete(selector, max_time_ms: 0.1)
1780
+ end
1781
+
1782
+ it 'raises an OperationFailure' do
1783
+ expect {
1784
+ result
1785
+ }.to raise_exception(Mongo::Error::OperationFailure)
1786
+ end
1787
+ end
1788
+
1789
+ context 'when write_concern is provided', if: find_command_enabled? && standalone? do
1790
+
1791
+ it 'uses the write concern' do
1792
+ expect {
1793
+ authorized_collection.find_one_and_delete(selector,
1794
+ write_concern: { w: 2 })
1795
+ }.to raise_error(Mongo::Error::OperationFailure)
1796
+ end
1797
+ end
1798
+
1799
+ context 'when the collection has a write concern', if: find_command_enabled? && standalone? do
1800
+
1801
+ let(:collection) do
1802
+ authorized_collection.with(write: { w: 2 })
1803
+ end
1804
+
1805
+ it 'uses the write concern' do
1806
+ expect {
1807
+ collection.find_one_and_delete(selector,
1808
+ write_concern: { w: 2 })
1809
+ }.to raise_error(Mongo::Error::OperationFailure)
1810
+ end
1035
1811
  end
1812
+ end
1813
+
1814
+ describe '#find_one_and_update' do
1036
1815
 
1037
1816
  let(:selector) do
1038
1817
  { field: 'test1' }
1039
1818
  end
1040
1819
 
1820
+ before do
1821
+ authorized_collection.insert_many([{ field: 'test1' }])
1822
+ end
1823
+
1041
1824
  context 'when a matching document is found' do
1042
1825
 
1043
1826
  context 'when no options are provided' do
@@ -1167,6 +1950,99 @@ describe Mongo::Collection do
1167
1950
  end
1168
1951
  end
1169
1952
  end
1953
+
1954
+ context 'when the operation fails', if: write_command_enabled? do
1955
+
1956
+ let(:result) do
1957
+ authorized_collection.find_one_and_update(selector, { '$set' => { field: 'testing' }}, max_time_ms: 0.1)
1958
+ end
1959
+
1960
+ it 'raises an OperationFailure' do
1961
+ expect {
1962
+ result
1963
+ }.to raise_exception(Mongo::Error::OperationFailure)
1964
+ end
1965
+ end
1966
+
1967
+ context 'when collection has a validator', if: find_command_enabled? do
1968
+
1969
+ before do
1970
+ collection_with_validator.insert_one({ a: 1 })
1971
+ end
1972
+
1973
+ after do
1974
+ collection_with_validator.delete_many
1975
+ end
1976
+
1977
+ context 'when the document is valid' do
1978
+
1979
+ let(:result) do
1980
+ collection_with_validator.find_one_and_update(
1981
+ { a: 1 }, { '$inc' => { :a => 1 } }, :return_document => :after)
1982
+ end
1983
+
1984
+ it 'updates successfully' do
1985
+ expect(result['a']).to eq(2)
1986
+ end
1987
+ end
1988
+
1989
+ context 'when the document is invalid' do
1990
+
1991
+ context 'when bypass_document_validation is not set' do
1992
+
1993
+ let(:result2) do
1994
+ collection_with_validator.find_one_and_update(
1995
+ { a: 1 }, { '$unset' => { :a => '' } }, :return_document => :after)
1996
+ end
1997
+
1998
+ it 'raises OperationFailure' do
1999
+ expect {
2000
+ result2
2001
+ }.to raise_exception(Mongo::Error::OperationFailure)
2002
+ end
2003
+ end
2004
+
2005
+ context 'when bypass_document_validation is true' do
2006
+
2007
+ let(:result3) do
2008
+ collection_with_validator.find_one_and_update(
2009
+ { a: 1 }, { '$unset' => { :a => '' } },
2010
+ :bypass_document_validation => true,
2011
+ :return_document => :after)
2012
+ end
2013
+
2014
+ it 'updates successfully' do
2015
+ expect(result3['a']).to be_nil
2016
+ end
2017
+ end
2018
+ end
2019
+ end
2020
+
2021
+ context 'when write_concern is provided', if: find_command_enabled? && standalone? do
2022
+
2023
+ it 'uses the write concern' do
2024
+ expect {
2025
+ authorized_collection.find_one_and_update(selector,
2026
+ { '$set' => { field: 'testing' }},
2027
+ write_concern: { w: 2 })
2028
+ }.to raise_error(Mongo::Error::OperationFailure)
2029
+ end
2030
+ end
2031
+
2032
+ context 'when the collection has a write concern', if: find_command_enabled? && standalone? do
2033
+
2034
+ let(:collection) do
2035
+ authorized_collection.with(write: { w: 2 })
2036
+ end
2037
+
2038
+ it 'uses the write concern' do
2039
+ expect {
2040
+ collection.find_one_and_update(selector,
2041
+ { '$set' => { field: 'testing' }},
2042
+ write_concern: { w: 2 })
2043
+ }.to raise_error(Mongo::Error::OperationFailure)
2044
+ end
2045
+ end
1170
2046
  end
1171
2047
 
1172
2048
  describe '#find_one_and_replace' do
@@ -1282,5 +2158,98 @@ describe Mongo::Collection do
1282
2158
  }.to raise_error(Mongo::Error::OperationFailure)
1283
2159
  end
1284
2160
  end
2161
+
2162
+ context 'when the operation fails', if: write_command_enabled? do
2163
+
2164
+ let(:result) do
2165
+ authorized_collection.find_one_and_replace(selector, { field: 'testing' }, max_time_ms: 0.1)
2166
+ end
2167
+
2168
+ it 'raises an OperationFailure' do
2169
+ expect {
2170
+ result
2171
+ }.to raise_exception(Mongo::Error::OperationFailure)
2172
+ end
2173
+ end
2174
+
2175
+ context 'when collection has a validator', if: find_command_enabled? do
2176
+
2177
+ before do
2178
+ collection_with_validator.insert_one({ a: 1 })
2179
+ end
2180
+
2181
+ after do
2182
+ collection_with_validator.delete_many
2183
+ end
2184
+
2185
+ context 'when the document is valid' do
2186
+
2187
+ let(:result) do
2188
+ collection_with_validator.find_one_and_replace(
2189
+ { a: 1 }, { a: 5 }, :return_document => :after)
2190
+ end
2191
+
2192
+ it 'replaces successfully when document is valid' do
2193
+ expect(result[:a]).to eq(5)
2194
+ end
2195
+ end
2196
+
2197
+ context 'when the document is invalid' do
2198
+
2199
+ context 'when bypass_document_validation is not set' do
2200
+
2201
+ let(:result2) do
2202
+ collection_with_validator.find_one_and_replace(
2203
+ { a: 1 }, { x: 5 }, :return_document => :after)
2204
+ end
2205
+
2206
+ it 'raises OperationFailure' do
2207
+ expect {
2208
+ result2
2209
+ }.to raise_exception(Mongo::Error::OperationFailure)
2210
+ end
2211
+ end
2212
+
2213
+ context 'when bypass_document_validation is true' do
2214
+
2215
+ let(:result3) do
2216
+ collection_with_validator.find_one_and_replace(
2217
+ { a: 1 }, { x: 1 }, :bypass_document_validation => true,
2218
+ :return_document => :after)
2219
+ end
2220
+
2221
+ it 'replaces successfully' do
2222
+ expect(result3[:x]).to eq(1)
2223
+ expect(result3[:a]).to be_nil
2224
+ end
2225
+ end
2226
+ end
2227
+ end
2228
+
2229
+ context 'when write_concern is provided', if: find_command_enabled? && standalone? do
2230
+
2231
+ it 'uses the write concern' do
2232
+ expect {
2233
+ authorized_collection.find_one_and_replace(selector,
2234
+ { field: 'testing' },
2235
+ write_concern: { w: 2 })
2236
+ }.to raise_error(Mongo::Error::OperationFailure)
2237
+ end
2238
+ end
2239
+
2240
+ context 'when the collection has a write concern', if: find_command_enabled? && standalone? do
2241
+
2242
+ let(:collection) do
2243
+ authorized_collection.with(write: { w: 2 })
2244
+ end
2245
+
2246
+ it 'uses the write concern' do
2247
+ expect {
2248
+ collection.find_one_and_replace(selector,
2249
+ { field: 'testing' },
2250
+ write_concern: { w: 2 })
2251
+ }.to raise_error(Mongo::Error::OperationFailure)
2252
+ end
2253
+ end
1285
2254
  end
1286
2255
  end