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
data/lib/mongo/cluster.rb CHANGED
@@ -25,6 +25,16 @@ module Mongo
25
25
  include Event::Subscriber
26
26
  include Loggable
27
27
 
28
+ # The default number of mongos read retries.
29
+ #
30
+ # @since 2.1.1
31
+ MAX_READ_RETRIES = 1
32
+
33
+ # The default mongos read retry interval, in seconds.
34
+ #
35
+ # @since 2.1.1
36
+ READ_RETRY_INTERVAL = 5
37
+
28
38
  # @return [ Hash ] The options hash.
29
39
  attr_reader :options
30
40
 
@@ -65,7 +75,7 @@ module Mongo
65
75
  address = Address.new(host)
66
76
  if !addresses.include?(address)
67
77
  if addition_allowed?(address)
68
- log_debug([ "Adding #{address.to_s} to the cluster." ])
78
+ log_debug("Adding #{address.to_s} to the cluster.")
69
79
  @update_lock.synchronize { @addresses.push(address) }
70
80
  server = Server.new(address, self, @monitoring, event_listeners, options)
71
81
  @update_lock.synchronize { @servers.push(server) }
@@ -88,7 +98,7 @@ module Mongo
88
98
  # @param [ Hash ] options The options.
89
99
  #
90
100
  # @since 2.0.0
91
- def initialize(seeds, monitoring, options = {})
101
+ def initialize(seeds, monitoring, options = Options::Redacted.new)
92
102
  @addresses = []
93
103
  @servers = []
94
104
  @monitoring = monitoring
@@ -96,12 +106,34 @@ module Mongo
96
106
  @options = options.freeze
97
107
  @topology = Topology.initial(seeds, options)
98
108
  @update_lock = Mutex.new
109
+ @pool_lock = Mutex.new
99
110
 
100
111
  subscribe_to(Event::STANDALONE_DISCOVERED, Event::StandaloneDiscovered.new(self))
101
112
  subscribe_to(Event::DESCRIPTION_CHANGED, Event::DescriptionChanged.new(self))
102
113
  subscribe_to(Event::PRIMARY_ELECTED, Event::PrimaryElected.new(self))
103
114
 
104
115
  seeds.each{ |seed| add(seed) }
116
+ ObjectSpace.define_finalizer(self, self.class.finalize(pools))
117
+ end
118
+
119
+ # Finalize the cluster for garbage collection. Disconnects all the scoped
120
+ # connection pools.
121
+ #
122
+ # @example Finalize the cluster.
123
+ # Cluster.finalize(pools)
124
+ #
125
+ # @param [ Hash<Address, Server::ConnectionPool> ] pools The connection
126
+ # pools.
127
+ #
128
+ # @return [ Proc ] The Finalizer.
129
+ #
130
+ # @since 2.2.0
131
+ def self.finalize(pools)
132
+ proc do
133
+ pools.values.each do |pool|
134
+ pool.disconnect!
135
+ end
136
+ end
105
137
  end
106
138
 
107
139
  # Get the nicer formatted string for use in inspection.
@@ -121,11 +153,13 @@ module Mongo
121
153
  # @example Get the next primary server.
122
154
  # cluster.next_primary
123
155
  #
156
+ # @param [ true, false ] ping Whether to ping the server before selection.
157
+ #
124
158
  # @return [ Mongo::Server ] A primary server.
125
159
  #
126
160
  # @since 2.0.0
127
- def next_primary
128
- ServerSelector.get({ mode: :primary }, options).select_server(self)
161
+ def next_primary(ping = true)
162
+ ServerSelector.get(ServerSelector::PRIMARY.merge(options)).select_server(self, ping)
129
163
  end
130
164
 
131
165
  # Elect a primary server from the description that has just changed to a
@@ -143,6 +177,48 @@ module Mongo
143
177
  @topology = topology.elect_primary(description, servers_list)
144
178
  end
145
179
 
180
+ # Get the maximum number of times the cluster can retry a read operation on
181
+ # a mongos.
182
+ #
183
+ # @example Get the max read retries.
184
+ # cluster.max_read_retries
185
+ #
186
+ # @return [ Integer ] The maximum retries.
187
+ #
188
+ # @since 2.1.1
189
+ def max_read_retries
190
+ options[:max_read_retries] || MAX_READ_RETRIES
191
+ end
192
+
193
+ # Get the scoped connection pool for the server.
194
+ #
195
+ # @example Get the connection pool.
196
+ # cluster.pool(server)
197
+ #
198
+ # @param [ Server ] server The server.
199
+ #
200
+ # @return [ Server::ConnectionPool ] The connection pool.
201
+ #
202
+ # @since 2.2.0
203
+ def pool(server)
204
+ @pool_lock.synchronize do
205
+ pools[server.address] ||= Server::ConnectionPool.get(server)
206
+ end
207
+ end
208
+
209
+ # Get the interval, in seconds, in which a mongos read operation is
210
+ # retried.
211
+ #
212
+ # @example Get the read retry interval.
213
+ # cluster.read_retry_interval
214
+ #
215
+ # @return [ Float ] The interval.
216
+ #
217
+ # @since 2.1.1
218
+ def read_retry_interval
219
+ options[:read_retry_interval] || READ_RETRY_INTERVAL
220
+ end
221
+
146
222
  # Notify the cluster that a standalone server was discovered so that the
147
223
  # topology can be updated accordingly.
148
224
  #
@@ -166,7 +242,7 @@ module Mongo
166
242
  #
167
243
  # @since 2.0.0
168
244
  def remove(host)
169
- log_debug([ "#{host} being removed from the cluster." ])
245
+ log_debug("#{host} being removed from the cluster.")
170
246
  address = Address.new(host)
171
247
  removed_servers = @servers.select { |s| s.address == address }
172
248
  @update_lock.synchronize { @servers = @servers - removed_servers }
@@ -301,6 +377,10 @@ module Mongo
301
377
  !@topology.single? || direct_connection?(address)
302
378
  end
303
379
 
380
+ def pools
381
+ @pools ||= {}
382
+ end
383
+
304
384
  def servers_list
305
385
  @update_lock.synchronize do
306
386
  @servers.reduce([]) do |servers, server|
@@ -25,6 +25,8 @@ module Mongo
25
25
  include Immutable
26
26
  include Iterable
27
27
  include Explainable
28
+ include Loggable
29
+ include Retryable
28
30
 
29
31
  # @return [ View ] view The collection view.
30
32
  attr_reader :view
@@ -37,14 +39,10 @@ module Mongo
37
39
  # Delegate necessary operations to the collection.
38
40
  def_delegators :collection, :database
39
41
 
40
- # Options mapping for an aggregation.
42
+ # The reroute message.
41
43
  #
42
44
  # @since 2.1.0
43
- OPTIONS_MAP = {
44
- :allow_disk_use => :allowDiskUse,
45
- :max_time_ms => :maxTimeMS,
46
- :explain => :explain
47
- }
45
+ REROUTE = 'Rerouting the Aggregation operation to the primary server.'.freeze
48
46
 
49
47
  # Set to true if disk usage is allowed during the aggregation.
50
48
  #
@@ -58,7 +56,7 @@ module Mongo
58
56
  #
59
57
  # @since 2.0.0
60
58
  def allow_disk_use(value = nil)
61
- configure(__method__, value)
59
+ configure(:allow_disk_use, value)
62
60
  end
63
61
 
64
62
  # Initialize the aggregation for the provided collection view, pipeline
@@ -87,61 +85,37 @@ module Mongo
87
85
  #
88
86
  # @since 2.0.0
89
87
  def explain
90
- self.class.new(view, pipeline, options.merge(explain_options)).first
88
+ self.class.new(view, pipeline, options.merge(explain: true)).first
91
89
  end
92
90
 
93
91
  private
94
92
 
95
93
  def aggregate_spec
96
- { :db_name => database.name,
97
- :read => read,
98
- :selector => {
99
- :aggregate => collection.name,
100
- :pipeline => pipeline,
101
- :cursor => cursor,
102
- }.merge!(agg_options)
103
- }
94
+ Builder::Aggregation.new(pipeline, view, options).specification
104
95
  end
105
96
 
106
- def agg_options
107
- @agg_options ||= options.each.reduce({}) do |opts, (key, value)|
108
- OPTIONS_MAP[key] ? opts.merge!(OPTIONS_MAP[key] => value) : opts
109
- end
110
- end
111
-
112
- def cursor
113
- if options[:use_cursor] == true || options[:use_cursor].nil?
114
- batch_size_doc
115
- end
116
- end
117
-
118
- def batch_size_doc
119
- (value = options[:batch_size] || view.batch_size) ?
120
- { :batchSize => value } : {}
97
+ def new(options)
98
+ Aggregation.new(view, pipeline, options)
121
99
  end
122
100
 
123
- def explain_options
124
- { :explain => true }
101
+ def initial_query_op
102
+ Operation::Commands::Aggregate.new(aggregate_spec)
125
103
  end
126
104
 
127
- def new(options)
128
- Aggregation.new(view, pipeline, options)
105
+ def valid_server?(server)
106
+ server.standalone? || server.mongos? || server.primary? || secondary_ok?
129
107
  end
130
108
 
131
- def initial_query_op
132
- Operation::Aggregate.new(aggregate_spec)
109
+ def secondary_ok?
110
+ pipeline.none? { |op| op.key?('$out') || op.key?(:$out) }
133
111
  end
134
112
 
135
113
  def send_initial_query(server)
136
- begin
137
- initial_query_op.execute(server.context)
138
- rescue Mongo::Error::NeedPrimaryServer
139
- log_warn([
140
- 'Rerouting the Aggregation operation to the primary server.'
141
- ])
142
- server = ServerSelector.get(mode: :primary).select_server(cluster)
143
- initial_query_op.execute(server.context)
114
+ unless valid_server?(server)
115
+ log_warn(REROUTE)
116
+ server = cluster.next_primary(false)
144
117
  end
118
+ initial_query_op.execute(server.context)
145
119
  end
146
120
  end
147
121
  end
@@ -0,0 +1,98 @@
1
+ # Copyright (C) 2015 MongoDB, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ module Mongo
16
+ class Collection
17
+ class View
18
+ module Builder
19
+
20
+ # Builds an aggregation command specification from the view and options.
21
+ #
22
+ # @since 2.2.0
23
+ class Aggregation
24
+ extend Forwardable
25
+
26
+ # The mappings from ruby options to the aggregation options.
27
+ #
28
+ # @since 2.2.0
29
+ MAPPINGS = BSON::Document.new(
30
+ :allow_disk_use => 'allowDiskUse',
31
+ :max_time_ms => 'maxTimeMS',
32
+ :explain => 'explain',
33
+ :bypass_document_validation => 'bypassDocumentValidation'
34
+ ).freeze
35
+
36
+ def_delegators :@view, :collection, :database, :read
37
+
38
+ # @return [ Array<Hash> ] pipeline The pipeline.
39
+ attr_reader :pipeline
40
+
41
+ # @return [ Collection::View ] view The collection view.
42
+ attr_reader :view
43
+
44
+ # @return [ Hash ] options The map/reduce specific options.
45
+ attr_reader :options
46
+
47
+ # Initialize the builder.
48
+ #
49
+ # @example Initialize the builder.
50
+ # Aggregation.new(map, reduce, view, options)
51
+ #
52
+ # @param [ Array<Hash> ] pipeline The aggregation pipeline.
53
+ # @param [ Collection::View ] view The collection view.
54
+ # @param [ Hash ] options The map/reduce options.
55
+ #
56
+ # @since 2.2.0
57
+ def initialize(pipeline, view, options)
58
+ @pipeline = pipeline
59
+ @view = view
60
+ @options = options
61
+ end
62
+
63
+ # Get the specification to pass to the aggregation operation.
64
+ #
65
+ # @example Get the specification.
66
+ # builder.specification
67
+ #
68
+ # @return [ Hash ] The specification.
69
+ #
70
+ # @since 2.2.0
71
+ def specification
72
+ { selector: aggregation_command, db_name: database.name, read: read }
73
+ end
74
+
75
+ private
76
+
77
+ def aggregation_command
78
+ command = BSON::Document.new(:aggregate => collection.name, :pipeline => pipeline)
79
+ command[:cursor] = cursor if cursor
80
+ command[:readConcern] = collection.read_concern if collection.read_concern
81
+ command.merge!(Options::Mapper.transform_documents(options, MAPPINGS))
82
+ command
83
+ end
84
+
85
+ def cursor
86
+ if options[:use_cursor] == true || options[:use_cursor].nil?
87
+ batch_size_doc
88
+ end
89
+ end
90
+
91
+ def batch_size_doc
92
+ (value = options[:batch_size] || view.batch_size) ? { :batchSize => value } : {}
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,111 @@
1
+ # Copyright (C) 2015 MongoDB, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ module Mongo
16
+ class Collection
17
+ class View
18
+ module Builder
19
+
20
+ # Builds a find command specification from options.
21
+ #
22
+ # @since 2.2.0
23
+ class FindCommand
24
+ extend Forwardable
25
+
26
+ # The mappings from ruby options to the find command.
27
+ #
28
+ # @since 2.2.0
29
+ MAPPINGS = BSON::Document.new(
30
+ sort: 'sort',
31
+ projection: 'projection',
32
+ hint: 'hint',
33
+ skip: 'skip',
34
+ limit: 'limit',
35
+ batch_size: 'batchSize',
36
+ single_batch: 'singleBatch',
37
+ comment: 'comment',
38
+ max_scan: 'maxScan',
39
+ max_time_ms: 'maxTimeMS',
40
+ max_value: 'max',
41
+ min_value: 'min',
42
+ return_key: 'returnKey',
43
+ show_disk_loc: 'showRecordId',
44
+ snapshot: 'snapshot',
45
+ tailable: 'tailable',
46
+ oplog_replay: 'oplogReplay',
47
+ no_cursor_timeout: 'noCursorTimeout',
48
+ await_data: 'awaitData',
49
+ allow_partial_results: 'allowPartialResults',
50
+ read_concern: 'readConcern'
51
+ ).freeze
52
+
53
+ def_delegators :@view, :collection, :database, :filter, :options, :read
54
+
55
+ # Get the specification for an explain command that wraps the find
56
+ # command.
57
+ #
58
+ # @example Get the explain spec.
59
+ # builder.explain_specification
60
+ #
61
+ # @return [ Hash ] The specification.
62
+ #
63
+ # @since 2.2.0
64
+ def explain_specification
65
+ { selector: { explain: find_command }, db_name: database.name, read: read }
66
+ end
67
+
68
+ # Create the find command builder.
69
+ #
70
+ # @example Create the find command builder.
71
+ # FindCommandBuilder.new(view)
72
+ #
73
+ # @param [ Collection::View ] view The collection view.
74
+ #
75
+ # @since 2.2.2
76
+ def initialize(view)
77
+ @view = view
78
+ end
79
+
80
+ # Get the specification to pass to the find command operation.
81
+ #
82
+ # @example Get the specification.
83
+ # builder.specification
84
+ #
85
+ # @return [ Hash ] The specification.
86
+ #
87
+ # @since 2.2.0
88
+ def specification
89
+ { selector: find_command, db_name: database.name, read: read }
90
+ end
91
+
92
+ private
93
+
94
+ def find_command
95
+ document = BSON::Document.new('find' => collection.name, 'filter' => filter)
96
+ command = Options::Mapper.transform_documents(options, MAPPINGS, document)
97
+ convert_negative_limit(command)
98
+ end
99
+
100
+ def convert_negative_limit(command)
101
+ if command[:limit] && command[:limit] < 0
102
+ command.delete('limit')
103
+ command[:singleBatch] = true
104
+ end
105
+ command
106
+ end
107
+ end
108
+ end
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,62 @@
1
+ # Copyright (C) 2015 MongoDB, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ module Mongo
16
+ class Collection
17
+ class View
18
+ module Builder
19
+
20
+ # Provides behaviour for mapping flags.
21
+ #
22
+ # @since 2.2.0
23
+ module Flags
24
+ extend self
25
+
26
+ # Options to cursor flags mapping.
27
+ #
28
+ # @since 2.2.0
29
+ MAPPINGS = {
30
+ :allow_partial_results => [ :partial ],
31
+ :oplog_replay => [ :oplog_replay ],
32
+ :no_cursor_timeout => [ :no_cursor_timeout ],
33
+ :tailable => [ :tailable_cursor ],
34
+ :tailable_await => [ :await_data, :tailable_cursor],
35
+ :await_data => [ :await_data ],
36
+ :exhaust => [ :exhaust ]
37
+ }.freeze
38
+
39
+ # Maps an array of flags from the provided options.
40
+ #
41
+ # @example Map the flags.
42
+ # Flags.map_flags(options)
43
+ #
44
+ # @param [ Hash, BSON::Document ] options The options.
45
+ #
46
+ # @return [ Array<Symbol> ] The flags.
47
+ #
48
+ # @since 2.2.0
49
+ def map_flags(options)
50
+ MAPPINGS.each.reduce(options[:flags] || []) do |flags, (key, value)|
51
+ cursor_type = options[:cursor_type]
52
+ if options[key] || (cursor_type && cursor_type == key)
53
+ flags.push(*value)
54
+ end
55
+ flags
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,134 @@
1
+ # Copyright (C) 2015 MongoDB, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ module Mongo
16
+ class Collection
17
+ class View
18
+ module Builder
19
+
20
+ # Builds a map/reduce specification from the view and options.
21
+ #
22
+ # @since 2.2.0
23
+ class MapReduce
24
+ extend Forwardable
25
+
26
+ # The mappings from ruby options to the map/reduce options.
27
+ #
28
+ # @since 2.2.0
29
+ MAPPINGS = BSON::Document.new(
30
+ finalize: 'finalize',
31
+ js_mode: 'jsMode',
32
+ out: 'out',
33
+ scope: 'scope',
34
+ verbose: 'verbose',
35
+ bypass_document_validation: 'bypassDocumentValidation'
36
+ ).freeze
37
+
38
+ def_delegators :@view, :collection, :database, :filter, :read
39
+
40
+ # @return [ String ] map The map function.
41
+ attr_reader :map
42
+
43
+ # @return [ String ] reduce The reduce function.
44
+ attr_reader :reduce
45
+
46
+ # @return [ Collection::View ] view The collection view.
47
+ attr_reader :view
48
+
49
+ # @return [ Hash ] options The map/reduce specific options.
50
+ attr_reader :options
51
+
52
+ # Initialize the builder.
53
+ #
54
+ # @example Initialize the builder.
55
+ # MapReduce.new(map, reduce, view, options)
56
+ #
57
+ # @param [ String ] map The map function.
58
+ # @param [ String ] reduce The reduce function.
59
+ # @param [ Collection::View ] view The collection view.
60
+ # @param [ Hash ] options The map/reduce options.
61
+ #
62
+ # @since 2.2.0
63
+ def initialize(map, reduce, view, options)
64
+ @map = map
65
+ @reduce = reduce
66
+ @view = view
67
+ @options = options
68
+ end
69
+
70
+ # Get the specification for issuing a find command on the map/reduce
71
+ # results.
72
+ #
73
+ # @example Get the command specification.
74
+ # builder.command_specification
75
+ #
76
+ # @return [ Hash ] The specification.
77
+ #
78
+ # @since 2.2.0
79
+ def command_specification
80
+ { selector: find_command, db_name: database.name, read: read }
81
+ end
82
+
83
+ # Get the specification for the document query after a map/reduce.
84
+ #
85
+ # @example Get the query specification.
86
+ # builder.query_specification
87
+ #
88
+ # @return [ Hash ] The specification.
89
+ #
90
+ # @since 2.2.0
91
+ def query_specification
92
+ { selector: {}, options: {}, db_name: database.name, coll_name: query_collection }
93
+ end
94
+
95
+ # Get the specification to pass to the map/reduce operation.
96
+ #
97
+ # @example Get the specification.
98
+ # builder.specification
99
+ #
100
+ # @return [ Hash ] The specification.
101
+ #
102
+ # @since 2.2.0
103
+ def specification
104
+ { selector: map_reduce_command, db_name: database.name, read: read }
105
+ end
106
+
107
+ private
108
+
109
+ def find_command
110
+ BSON::Document.new('find' => query_collection, 'filter' => {})
111
+ end
112
+
113
+ def map_reduce_command
114
+ command = BSON::Document.new(
115
+ :mapreduce => collection.name,
116
+ :map => map,
117
+ :reduce => reduce,
118
+ :query => filter,
119
+ :out => { inline: 1 }
120
+ )
121
+ command[:readConcern] = collection.read_concern if collection.read_concern
122
+ command.merge!(Options::Mapper.transform_documents(options, MAPPINGS))
123
+ command.merge!(view.options)
124
+ command
125
+ end
126
+
127
+ def query_collection
128
+ options[:out].respond_to?(:keys) ? options[:out].values.first : options[:out]
129
+ end
130
+ end
131
+ end
132
+ end
133
+ end
134
+ end