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
@@ -21,32 +21,15 @@ module Mongo
21
21
  # @since 2.0.0
22
22
  module Readable
23
23
 
24
- # Special fields and their getters for the query selector.
24
+ # The query modifier constant.
25
25
  #
26
- # @since 2.0.0
27
- SPECIAL_FIELDS = {
28
- :$query => :selector,
29
- :$readPreference => :read_pref_formatted,
30
- :$orderby => :sort,
31
- :$hint => :hint,
32
- :$comment => :comment,
33
- :$snapshot => :snapshot,
34
- :$maxScan => :max_scan,
35
- :$maxTimeMS => :max_time_ms,
36
- :$showDiskLoc => :show_disk_loc,
37
- :$explain => :explained?
38
- }.freeze
39
-
40
- # Options to cursor flags mapping.
26
+ # @since 2.2.0
27
+ QUERY = '$query'.freeze
28
+
29
+ # The modifiers option constant.
41
30
  #
42
- # @since 2.1.0
43
- CURSOR_FLAGS_MAP = {
44
- :allow_partial_results => [ :partial ],
45
- :oplog_replay => [ :oplog_replay ],
46
- :no_cursor_timeout => [ :no_cursor_timeout ],
47
- :tailable => [ :tailable_cursor ],
48
- :tailable_await => [ :await_data, :tailable_cursor]
49
- }.freeze
31
+ # @since 2.2.0
32
+ MODIFIERS = 'modifiers'.freeze
50
33
 
51
34
  # Execute an aggregation on the collection view.
52
35
  #
@@ -65,45 +48,28 @@ module Mongo
65
48
  Aggregation.new(self, pipeline, options)
66
49
  end
67
50
 
68
- # Execute a parallel scan on the collection view.
69
- # Returns a list of up to cursor_count cursors that can be iterated concurrently.
70
- # As long as the collection is not modified during scanning, each document appears once
71
- # in one of the cursors' result sets.
72
- #
73
- # @example Execute a parallel collection scan.
74
- # view.parallel_scan(2)
51
+ # Allows the query to get partial results if some shards are down.
75
52
  #
76
- # @param [ Integer ] cursor_count The max number of cursors to return.
53
+ # @example Allow partial results.
54
+ # view.allow_partial_results
77
55
  #
78
- # @return [ Array<Cursor> ] An array of cursors.
56
+ # @return [ View ] The new view.
79
57
  #
80
- # @since 2.1
81
- def parallel_scan(cursor_count)
82
- server = read.select_server(cluster)
83
- Operation::ParallelScan.new(
84
- :coll_name => collection.name,
85
- :db_name => database.name,
86
- :cursor_count => cursor_count
87
- ).execute(server.context).cursor_ids.map do |cursor_id|
88
- result = Operation::Read::GetMore.new({ :to_return => 0,
89
- :cursor_id => cursor_id,
90
- :db_name => database.name,
91
- :coll_name => collection.name
92
- }).execute(server.context)
93
- Cursor.new(self, result, server)
94
- end
58
+ # @since 2.0.0
59
+ def allow_partial_results
60
+ configure(:allow_partial_results, true)
95
61
  end
96
62
 
97
- # Allows the query to get partial results if some shards are down.
63
+ # Tell the query's cursor to stay open and wait for data.
98
64
  #
99
- # @example Allow partial results.
100
- # view.allow_partial_results
65
+ # @example Await data on the cursor.
66
+ # view.await_data
101
67
  #
102
68
  # @return [ View ] The new view.
103
69
  #
104
70
  # @since 2.0.0
105
- def allow_partial_results
106
- configure_flag(:partial)
71
+ def await_data
72
+ configure(:await_data, true)
107
73
  end
108
74
 
109
75
  # The number of documents returned in each batch of results from MongoDB.
@@ -160,12 +126,15 @@ module Mongo
160
126
  #
161
127
  # @since 2.0.0
162
128
  def count(options = {})
163
- cmd = { :count => collection.name, :query => selector }
129
+ cmd = { :count => collection.name, :query => filter }
164
130
  cmd[:skip] = options[:skip] if options[:skip]
165
131
  cmd[:hint] = options[:hint] if options[:hint]
166
132
  cmd[:limit] = options[:limit] if options[:limit]
167
133
  cmd[:maxTimeMS] = options[:max_time_ms] if options[:max_time_ms]
168
- database.command(cmd, options).n
134
+ cmd[:readConcern] = collection.read_concern if collection.read_concern
135
+ read_with_retry do
136
+ database.command(cmd, options).n.to_i
137
+ end
169
138
  end
170
139
 
171
140
  # Get a list of distinct values for a specific field.
@@ -186,9 +155,12 @@ module Mongo
186
155
  def distinct(field_name, options={})
187
156
  cmd = { :distinct => collection.name,
188
157
  :key => field_name.to_s,
189
- :query => selector }
158
+ :query => filter }
190
159
  cmd[:maxTimeMS] = options[:max_time_ms] if options[:max_time_ms]
191
- database.command(cmd, options).first['values']
160
+ cmd[:readConcern] = collection.read_concern if collection.read_concern
161
+ read_with_retry do
162
+ database.command(cmd, options).first['values']
163
+ end
192
164
  end
193
165
 
194
166
  # The index that MongoDB will be forced to use for the query.
@@ -249,6 +221,34 @@ module Mongo
249
221
  configure(:max_scan, value)
250
222
  end
251
223
 
224
+ # Set the maximum value to search.
225
+ #
226
+ # @example Set the max value.
227
+ # view.max_value(_id: 1)
228
+ #
229
+ # @param [ Hash ] value The max field and value.
230
+ #
231
+ # @return [ Hash, View ] The value or a new +View+.
232
+ #
233
+ # @since 2.1.0
234
+ def max_value(value = nil)
235
+ configure(:max_value, value)
236
+ end
237
+
238
+ # Set the minimum value to search.
239
+ #
240
+ # @example Set the min value.
241
+ # view.min_value(_id: 1)
242
+ #
243
+ # @param [ Hash ] value The min field and value.
244
+ #
245
+ # @return [ Hash, View ] The value or a new +View+.
246
+ #
247
+ # @since 2.1.0
248
+ def min_value(value = nil)
249
+ configure(:min_value, value)
250
+ end
251
+
252
252
  # The server normally times out idle cursors after an inactivity period
253
253
  # (10 minutes) to prevent excess memory use. Set this option to prevent that.
254
254
  #
@@ -259,7 +259,7 @@ module Mongo
259
259
  #
260
260
  # @since 2.0.0
261
261
  def no_cursor_timeout
262
- configure_flag(:no_cursor_timeout)
262
+ configure(:no_cursor_timeout, true)
263
263
  end
264
264
 
265
265
  # The fields to include or exclude from each doc in the result set.
@@ -294,7 +294,22 @@ module Mongo
294
294
  # @since 2.0.0
295
295
  def read(value = nil)
296
296
  return default_read if value.nil?
297
- configure(:read, value.is_a?(Hash) ? ServerSelector.get(value) : value)
297
+ selector = value.is_a?(Hash) ? ServerSelector.get(client.options.merge(value)) : value
298
+ configure(:read, selector)
299
+ end
300
+
301
+ # Set whether to return only the indexed field or fields.
302
+ #
303
+ # @example Set the return key value.
304
+ # view.return_key(true)
305
+ #
306
+ # @param [ true, false ] value The return key value.
307
+ #
308
+ # @return [ true, false, View ] The value or a new +View+.
309
+ #
310
+ # @since 2.1.0
311
+ def return_key(value = nil)
312
+ configure(:return_key, value)
298
313
  end
299
314
 
300
315
  # Set whether the disk location should be shown for each document.
@@ -311,6 +326,7 @@ module Mongo
311
326
  def show_disk_loc(value = nil)
312
327
  configure(:show_disk_loc, value)
313
328
  end
329
+ alias :show_record_id :show_disk_loc
314
330
 
315
331
  # The number of docs to skip before returning results.
316
332
  #
@@ -368,7 +384,23 @@ module Mongo
368
384
  #
369
385
  # @since 2.1.0
370
386
  def modifiers(doc = nil)
371
- configure(:modifiers, doc)
387
+ return Builder::Modifiers.map_server_modifiers(options) if doc.nil?
388
+ new(options.merge(Builder::Modifiers.map_driver_options(doc)))
389
+ end
390
+
391
+ # A cumulative time limit in milliseconds for processing get more operations
392
+ # on a cursor.
393
+ #
394
+ # @example Set the max await time ms value.
395
+ # view.max_await_time_ms(500)
396
+ #
397
+ # @param [ Integer ] max The max time in milliseconds.
398
+ #
399
+ # @return [ Integer, View ] Either the max await time ms value or a new +View+.
400
+ #
401
+ # @since 2.1.0
402
+ def max_await_time_ms(max = nil)
403
+ configure(:max_await_time_ms, max)
372
404
  end
373
405
 
374
406
  # A cumulative time limit in milliseconds for processing operations on a cursor.
@@ -387,53 +419,35 @@ module Mongo
387
419
 
388
420
  private
389
421
 
390
- def default_read(read = nil)
422
+ def default_read
391
423
  options[:read] || read_preference
392
424
  end
393
425
 
394
- def flags
395
- @flags ||= CURSOR_FLAGS_MAP.each.reduce([]) do |flags, (key, value)|
396
- if options[key] || (options[:cursor_type] && options[:cursor_type] == key)
397
- flags.push(*value)
426
+ def parallel_scan(cursor_count)
427
+ server = read.select_server(cluster, false)
428
+ Operation::Commands::ParallelScan.new(
429
+ :coll_name => collection.name,
430
+ :db_name => database.name,
431
+ :cursor_count => cursor_count,
432
+ :read_concern => collection.read_concern
433
+ ).execute(server.context).cursor_ids.map do |cursor_id|
434
+ result = if server.features.find_command_enabled?
435
+ Operation::Commands::GetMore.new({
436
+ :selector => { :getMore => cursor_id, :collection => collection.name },
437
+ :db_name => database.name
438
+ }).execute(server.context)
439
+ else
440
+ Operation::Read::GetMore.new({
441
+ :to_return => 0,
442
+ :cursor_id => cursor_id,
443
+ :db_name => database.name,
444
+ :coll_name => collection.name
445
+ }).execute(server.context)
398
446
  end
399
- flags
400
- end
401
- end
402
-
403
- def has_special_fields?
404
- modifiers || sort || hint || comment || max_time_ms || max_scan ||
405
- show_disk_loc || snapshot || explained? || cluster.sharded?
406
- end
407
-
408
- def query_options
409
- { :project => projection, :skip => skip, :limit => to_return, :flags => flags }
410
- end
411
-
412
- def query_spec
413
- sel = has_special_fields? ? special_selector : selector
414
- { :selector => sel,
415
- :read => read,
416
- :options => query_options,
417
- :db_name => database.name,
418
- :coll_name => collection.name }
419
- end
420
-
421
- def read_pref_formatted
422
- read.to_mongos
423
- end
424
-
425
- def special_selector
426
- SPECIAL_FIELDS.reduce({}) do |hash, (key, method)|
427
- value = send(method) || (options[:modifiers] && options[:modifiers][key])
428
- hash[key] = value if value
429
- hash
447
+ Cursor.new(self, result, server)
430
448
  end
431
449
  end
432
450
 
433
- def to_return
434
- [ limit || batch_size, batch_size || limit ].min
435
- end
436
-
437
451
  def validate_doc!(doc)
438
452
  raise Error::InvalidDocument.new unless doc.respond_to?(:keys)
439
453
  end
@@ -31,11 +31,16 @@ module Mongo
31
31
  #
32
32
  # @since 2.0.0
33
33
  def find_one_and_delete
34
- cmd = { :findandmodify => collection.name, :query => selector, :remove => true }
34
+ cmd = { :findandmodify => collection.name, :query => filter, :remove => true }
35
35
  cmd[:fields] = projection if projection
36
36
  cmd[:sort] = sort if sort
37
37
  cmd[:maxTimeMS] = max_time_ms if max_time_ms
38
- database.command(cmd).first['value']
38
+ wc = options[:write_concern] || (collection.write_concern &&
39
+ collection.write_concern.options)
40
+ cmd[:writeConcern] = wc if wc
41
+ write_with_retry do
42
+ database.command(cmd).first['value']
43
+ end
39
44
  end
40
45
 
41
46
  # Finds a single document and replaces it.
@@ -50,8 +55,11 @@ module Mongo
50
55
  # @param [ Hash ] opts The options.
51
56
  #
52
57
  # @option opts [ Symbol ] :return_document Either :before or :after.
53
- # @option opts [ true, false ] :upsert Whether to upsert if the
54
- # document doesn't exist.
58
+ # @option opts [ true, false ] :upsert Whether to upsert if the document doesn't exist.
59
+ # @option opts [ true, false ] :bypass_document_validation Whether or
60
+ # not to skip document level validation.
61
+ # @option options [ Hash ] :write_concern The write concern options.
62
+ # Defaults to the collection's write concern.
55
63
  #
56
64
  # @return [ BSON::Document ] The document.
57
65
  #
@@ -69,20 +77,31 @@ module Mongo
69
77
  # @param [ Hash ] opts The options.
70
78
  #
71
79
  # @option opts [ Symbol ] :return_document Either :before or :after.
80
+ # @option opts [ true, false ] :upsert Whether to upsert if the document doesn't exist.
81
+ # @option opts [ true, false ] :bypass_document_validation Whether or
82
+ # not to skip document level validation.
83
+ # @option options [ Hash ] :write_concern The write concern options.
84
+ # Defaults to the collection's write concern.
72
85
  #
73
86
  # @return [ BSON::Document ] The document.
74
87
  #
75
88
  # @since 2.0.0
76
89
  def find_one_and_update(document, opts = {})
77
- cmd = { :findandmodify => collection.name, :query => selector }
90
+ cmd = { :findandmodify => collection.name, :query => filter }
78
91
  cmd[:update] = document
79
92
  cmd[:fields] = projection if projection
80
93
  cmd[:sort] = sort if sort
81
94
  cmd[:new] = !!(opts[:return_document] && opts[:return_document] == :after)
82
95
  cmd[:upsert] = opts[:upsert] if opts[:upsert]
83
96
  cmd[:maxTimeMS] = max_time_ms if max_time_ms
84
- value = database.command(cmd).first['value']
85
- value unless value.nil? || value.empty?
97
+ cmd[:bypassDocumentValidation] = !!opts[:bypass_document_validation]
98
+ wc = options[:write_concern] || (collection.write_concern &&
99
+ collection.write_concern.options)
100
+ cmd[:writeConcern] = wc if wc
101
+ write_with_retry do
102
+ value = database.command(cmd).first['value']
103
+ value unless value.nil? || value.empty?
104
+ end
86
105
  end
87
106
 
88
107
  # Remove documents from the collection.
@@ -166,24 +185,29 @@ module Mongo
166
185
  private
167
186
 
168
187
  def remove(value)
169
- Operation::Write::Delete.new(
170
- :delete => { q: selector, limit: value },
171
- :db_name => collection.database.name,
172
- :coll_name => collection.name,
173
- :write_concern => collection.write_concern
174
- ).execute(next_primary.context)
188
+ write_with_retry do
189
+ Operation::Write::Delete.new(
190
+ :delete => { Operation::Q => filter, Operation::LIMIT => value },
191
+ :db_name => collection.database.name,
192
+ :coll_name => collection.name,
193
+ :write_concern => collection.write_concern
194
+ ).execute(next_primary.context)
195
+ end
175
196
  end
176
197
 
177
198
  def update(spec, multi, opts)
178
- Operation::Write::Update.new(
179
- :update => { q: selector,
180
- u: spec,
181
- multi: multi,
182
- upsert: !!opts[:upsert] },
183
- :db_name => collection.database.name,
184
- :coll_name => collection.name,
185
- :write_concern => collection.write_concern
186
- ).execute(next_primary.context)
199
+ write_with_retry do
200
+ Operation::Write::Update.new(
201
+ :update => { Operation::Q => filter,
202
+ Operation::U => spec,
203
+ Operation::MULTI => multi,
204
+ Operation::UPSERT => !!opts[:upsert] },
205
+ :db_name => collection.database.name,
206
+ :coll_name => collection.name,
207
+ :write_concern => collection.write_concern,
208
+ :bypass_document_validation => !!opts[:bypass_document_validation]
209
+ ).execute(next_primary.context)
210
+ end
187
211
  end
188
212
  end
189
213
  end
@@ -12,6 +12,7 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ require 'mongo/collection/view/builder'
15
16
  require 'mongo/collection/view/immutable'
16
17
  require 'mongo/collection/view/iterable'
17
18
  require 'mongo/collection/view/explainable'
@@ -44,13 +45,15 @@ module Mongo
44
45
  include Immutable
45
46
  include Iterable
46
47
  include Readable
48
+ include Retryable
47
49
  include Explainable
48
50
  include Writable
49
51
 
50
- # @return [ View ] The +View+ to query.
52
+ # @return [ Collection ] The +Collection+ to query.
51
53
  attr_reader :collection
52
- # @return [ Hash ] The query selector.
53
- attr_reader :selector
54
+
55
+ # @return [ Hash ] The query filter.
56
+ attr_reader :filter
54
57
 
55
58
  # Delegate necessary operations to the collection.
56
59
  def_delegators :collection, :client, :cluster, :database, :read_preference, :write_concern
@@ -58,25 +61,27 @@ module Mongo
58
61
  # Delegate to the cluster for the next primary.
59
62
  def_delegators :cluster, :next_primary
60
63
 
64
+ alias :selector :filter
65
+
61
66
  # Compare two +View+ objects.
62
67
  #
63
68
  # @example Compare the view with another object.
64
69
  # view == other
65
70
  #
66
- # @return [ true, false ] Equal if collection, selector, and options of two
71
+ # @return [ true, false ] Equal if collection, filter, and options of two
67
72
  # +View+ match.
68
73
  #
69
74
  # @since 2.0.0
70
75
  def ==(other)
71
76
  return false unless other.is_a?(View)
72
77
  collection == other.collection &&
73
- selector == other.selector &&
78
+ filter == other.filter &&
74
79
  options == other.options
75
80
  end
76
81
  alias_method :eql?, :==
77
82
 
78
83
  # A hash value for the +View+ composed of the collection namespace,
79
- # hash of the options and hash of the selector.
84
+ # hash of the options and hash of the filter.
80
85
  #
81
86
  # @example Get the hash value.
82
87
  # view.hash
@@ -85,7 +90,7 @@ module Mongo
85
90
  #
86
91
  # @since 2.0.0
87
92
  def hash
88
- [ collection.namespace, options.hash, selector.hash ].hash
93
+ [ collection.namespace, options.hash, filter.hash ].hash
89
94
  end
90
95
 
91
96
  # Creates a new +View+.
@@ -100,7 +105,7 @@ module Mongo
100
105
  # View.new(collection, {:name => 'Emily'}, :read => :secondary_preferred)
101
106
  #
102
107
  # @param [ Collection ] collection The +Collection+ to query.
103
- # @param [ Hash ] selector The query selector.
108
+ # @param [ Hash ] filter The query filter.
104
109
  # @param [ Hash ] options The additional query options.
105
110
  #
106
111
  # @option options :comment [ String ] Associate a comment with the query.
@@ -124,11 +129,10 @@ module Mongo
124
129
  # results.
125
130
  #
126
131
  # @since 2.0.0
127
- def initialize(collection, selector = {}, options = {})
128
- validate_doc!(selector)
132
+ def initialize(collection, filter = {}, options = {})
133
+ validate_doc!(filter)
129
134
  @collection = collection
130
- @selector = selector.dup
131
- @options = options.dup
135
+ parse_parameters!(BSON::Document.new(filter.freeze), BSON::Document.new(options.freeze))
132
136
  end
133
137
 
134
138
  # Get a human-readable string representation of +View+.
@@ -140,8 +144,8 @@ module Mongo
140
144
  #
141
145
  # @since 2.0.0
142
146
  def inspect
143
- "#<Mongo::Collection::View:0x#{object_id} namespace='#{collection.namespace}" +
144
- " @selector=#{selector.inspect} @options=#{options.inspect}>"
147
+ "#<Mongo::Collection::View:0x#{object_id} namespace='#{collection.namespace}'" +
148
+ " @filter=#{filter.to_s} @options=#{options.to_s}>"
145
149
  end
146
150
 
147
151
  private
@@ -149,19 +153,18 @@ module Mongo
149
153
  def initialize_copy(other)
150
154
  @collection = other.collection
151
155
  @options = other.options.dup
152
- @selector = other.selector.dup
156
+ @filter = other.filter.dup
153
157
  end
154
158
 
155
- def initial_query_op
156
- Operation::Read::Query.new(query_spec)
159
+ def parse_parameters!(filter, options)
160
+ query = filter.delete(QUERY)
161
+ modifiers = (filter || {}).merge(options.delete(MODIFIERS) || {})
162
+ @filter = query || filter
163
+ @options = Builder::Modifiers.map_driver_options(modifiers).merge!(options)
157
164
  end
158
165
 
159
166
  def new(options)
160
- View.new(collection, selector, options)
161
- end
162
-
163
- def send_initial_query(server)
164
- initial_query_op.execute(server.context)
167
+ View.new(collection, filter, options)
165
168
  end
166
169
 
167
170
  def view; self; end