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
@@ -53,10 +53,12 @@ module Mongo
53
53
  # Supported flags: +:upsert+, +:multi_update+
54
54
  def initialize(database, collection, selector, update, options = {})
55
55
  @database = database
56
+ @collection = collection
56
57
  @namespace = "#{database}.#{collection}"
57
58
  @selector = selector
58
59
  @update = update
59
60
  @flags = options[:flags] || []
61
+ @upconverter = Upconverter.new(collection, selector, update, flags)
60
62
  end
61
63
 
62
64
  # Return the event payload for monitoring.
@@ -71,13 +73,15 @@ module Mongo
71
73
  {
72
74
  command_name: 'update',
73
75
  database_name: @database,
74
- command: { filter: selector, update: update },
76
+ command: upconverter.command,
75
77
  request_id: request_id
76
78
  }
77
79
  end
78
80
 
79
81
  private
80
82
 
83
+ attr_reader :upconverter
84
+
81
85
  # The operation code required to specify an Update message.
82
86
  # @return [Fixnum] the operation code.
83
87
  def op_code
@@ -105,6 +109,94 @@ module Mongo
105
109
  # @!attribute
106
110
  # @return [Hash] The update for this Delete message.
107
111
  field :update, Document
112
+
113
+ # Converts legacy update messages to the appropriare OP_COMMAND style
114
+ # message.
115
+ #
116
+ # @since 2.1.0
117
+ class Upconverter
118
+
119
+ # The multi constant.
120
+ #
121
+ # @since 2.2.0
122
+ MULTI = 'multi'.freeze
123
+
124
+ # The u constant.
125
+ #
126
+ # @since 2.2.0
127
+ U = 'u'.freeze
128
+
129
+ # The update constant.
130
+ #
131
+ # @since 2.2.0
132
+ UPDATE = 'update'.freeze
133
+
134
+ # The updates constant.
135
+ #
136
+ # @since 2.2.0
137
+ UPDATES = 'updates'.freeze
138
+
139
+ # The upsert constant.
140
+ #
141
+ # @since 2.2.0
142
+ UPSERT = 'upsert'.freeze
143
+
144
+ # @return [ String ] collection The name of the collection.
145
+ attr_reader :collection
146
+
147
+ # @return [ Hash ] filter The filter.
148
+ attr_reader :filter
149
+
150
+ # @return [ Hash ] update The update.
151
+ attr_reader :update
152
+
153
+ # @return [ Array<Symbol> ] flags The flags.
154
+ attr_reader :flags
155
+
156
+ # Instantiate the upconverter.
157
+ #
158
+ # @example Instantiate the upconverter.
159
+ # Upconverter.new(
160
+ # 'users',
161
+ # { name: 'test' },
162
+ # { '$set' => { 'name' => 't' }},
163
+ # []
164
+ # )
165
+ #
166
+ # @param [ String ] collection The name of the collection.
167
+ # @param [ Hash ] filter The filter.
168
+ # @param [ Hash ] update The update.
169
+ # @param [ Array<Symbol> ] flags The flags.
170
+ #
171
+ # @since 2.1.0
172
+ def initialize(collection, filter, update, flags)
173
+ @collection = collection
174
+ @filter = filter
175
+ @update = update
176
+ @flags = flags
177
+ end
178
+
179
+ # Get the upconverted command.
180
+ #
181
+ # @example Get the command.
182
+ # upconverter.command
183
+ #
184
+ # @return [ BSON::Document ] The upconverted command.
185
+ #
186
+ # @since 2.1.0
187
+ def command
188
+ document = BSON::Document.new
189
+ updates = BSON::Document.new
190
+ updates.store(Message::Q, filter)
191
+ updates.store(U, update)
192
+ updates.store(MULTI, flags.include?(:multi_update))
193
+ updates.store(UPSERT, flags.include?(:upsert))
194
+ document.store(UPDATE, collection)
195
+ document.store(Message::ORDERED, true)
196
+ document.store(UPDATES, [ updates ])
197
+ document
198
+ end
199
+ end
108
200
  end
109
201
  end
110
202
  end
@@ -0,0 +1,101 @@
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
+
17
+ # Defines basic behaviour around retrying operations.
18
+ #
19
+ # @since 2.1.0
20
+ module Retryable
21
+
22
+ # The not master error message.
23
+ #
24
+ # @since 2.1.0
25
+ NOT_MASTER = 'not master'.freeze
26
+
27
+ # Execute a read operation with a retry.
28
+ #
29
+ # @api private
30
+ #
31
+ # @example Execute the read.
32
+ # read_with_retry do
33
+ # ...
34
+ # end
35
+ #
36
+ # @note This only retries read operations on socket errors.
37
+ #
38
+ # @param [ Integer ] attempt The retry attempt count - for internal use.
39
+ # @param [ Proc ] block The block to execute.
40
+ #
41
+ # @return [ Result ] The result of the operation.
42
+ #
43
+ # @since 2.1.0
44
+ def read_with_retry(attempt = 0, &block)
45
+ begin
46
+ block.call
47
+ rescue Error::SocketError, Error::SocketTimeoutError
48
+ retry_operation(&block)
49
+ rescue Error::OperationFailure => e
50
+ if cluster.sharded? && e.retryable?
51
+ if attempt < cluster.max_read_retries
52
+ # We don't scan the cluster in this case as Mongos always returns
53
+ # ready after a ping no matter what the state behind it is.
54
+ sleep(cluster.read_retry_interval)
55
+ read_with_retry(attempt + 1, &block)
56
+ else
57
+ raise e
58
+ end
59
+ else
60
+ raise e
61
+ end
62
+ end
63
+ end
64
+
65
+ # Execute a write operation with a retry.
66
+ #
67
+ # @api private
68
+ #
69
+ # @example Execute the write.
70
+ # write_with_retry do
71
+ # ...
72
+ # end
73
+ #
74
+ # @note This only retries operations on not master failures, since it is
75
+ # the only case we can be sure a partial write did not already occur.
76
+ #
77
+ # @param [ Proc ] block The block to execute.
78
+ #
79
+ # @return [ Result ] The result of the operation.
80
+ #
81
+ # @since 2.1.0
82
+ def write_with_retry(&block)
83
+ begin
84
+ block.call
85
+ rescue Error::OperationFailure => e
86
+ if e.message.include?(NOT_MASTER)
87
+ retry_operation(&block)
88
+ else
89
+ raise e
90
+ end
91
+ end
92
+ end
93
+
94
+ private
95
+
96
+ def retry_operation(&block)
97
+ cluster.scan!
98
+ block.call
99
+ end
100
+ end
101
+ end
@@ -20,7 +20,12 @@ module Mongo
20
20
  # @since 2.0.0
21
21
  module Connectable
22
22
 
23
- # The default time in seconds to timeout a connection attempt.
23
+ # The ssl option prefix.
24
+ #
25
+ # @since 2.1.0
26
+ SSL = 'ssl'.freeze
27
+
28
+ # The default time in seconds to timeout an operation executed on a socket.
24
29
  #
25
30
  # @since 2.0.0
26
31
  TIMEOUT = 5.freeze
@@ -34,6 +39,19 @@ module Mongo
34
39
  # @return [ Integer ] pid The process id when the connection was created.
35
40
  attr_reader :pid
36
41
 
42
+ # Determine if the server is connectable. This will check not only if the
43
+ # connection exists, but if messages can send to it successfully.
44
+ #
45
+ # @example Is the server connectable?
46
+ # connection.connectable?
47
+ #
48
+ # @return [ true, false ] If the connection is connectable.
49
+ #
50
+ # @since 2.1.0
51
+ def connectable?
52
+ begin; ping; rescue; false; end
53
+ end
54
+
37
55
  # Determine if the connection is currently connected.
38
56
  #
39
57
  # @example Is the connection connected?
@@ -41,17 +59,17 @@ module Mongo
41
59
  #
42
60
  # @return [ true, false ] If connected.
43
61
  #
44
- # @since 2.0.0
62
+ # @deprecated Use #connectable? instead
45
63
  def connected?
46
64
  !!@socket && @socket.alive?
47
65
  end
48
66
 
49
- # Get the connection timeout.
67
+ # Get the timeout to execute an operation on a socket.
50
68
  #
51
- # @example Get the connection timeout.
69
+ # @example Get the timeout to execute an operation on a socket.
52
70
  # connection.timeout
53
71
  #
54
- # @return [ Float ] The connection timeout in seconds.
72
+ # @return [ Float ] The operation timeout in seconds.
55
73
  #
56
74
  # @since 2.0.0
57
75
  def timeout
@@ -68,10 +86,10 @@ module Mongo
68
86
 
69
87
  def ensure_connected
70
88
  ensure_same_process!
71
- connect! if socket.nil? || !socket.alive?
89
+ connect!
72
90
  begin
73
91
  yield socket
74
- rescue Error::SocketError, Error::SocketTimeoutError => e
92
+ rescue Exception => e
75
93
  disconnect!
76
94
  raise e
77
95
  end
@@ -85,7 +103,9 @@ module Mongo
85
103
  end
86
104
 
87
105
  def read
88
- ensure_connected{ |socket| Protocol::Reply.deserialize(socket) }
106
+ ensure_connected do |socket|
107
+ Protocol::Reply.deserialize(socket)
108
+ end
89
109
  end
90
110
  end
91
111
  end
@@ -23,6 +23,21 @@ module Mongo
23
23
  include Monitoring::Publishable
24
24
  extend Forwardable
25
25
 
26
+ # The ping command.
27
+ #
28
+ # @since 2.1.0
29
+ PING = { :ping => 1 }.freeze
30
+
31
+ # Ping message.
32
+ #
33
+ # @since 2.1.0
34
+ PING_MESSAGE = Protocol::Query.new(Database::ADMIN, Database::COMMAND, PING, :limit => -1)
35
+
36
+ # The ping message as raw bytes.
37
+ #
38
+ # @since 2.1.0
39
+ PING_BYTES = PING_MESSAGE.serialize.to_s.freeze
40
+
26
41
  # @return [ Mongo::Auth::CR, Mongo::Auth::X509, Mongo::Auth:LDAP, Mongo::Auth::SCRAM ]
27
42
  # authenticator The authentication strategy.
28
43
  attr_reader :authenticator
@@ -60,7 +75,7 @@ module Mongo
60
75
  def connect!
61
76
  unless socket
62
77
  @socket = address.socket(timeout, ssl_options)
63
- @socket.connect!
78
+ socket.connect!
64
79
  if authenticator
65
80
  authenticator.login(self)
66
81
  @authenticated = true
@@ -105,9 +120,12 @@ module Mongo
105
120
  #
106
121
  # @since 2.0.0
107
122
  def dispatch(messages, operation_id = nil)
108
- publish_command(messages, operation_id || Monitoring.next_operation_id) do |msgs|
109
- write(msgs)
110
- msgs.last.replyable? ? read : nil
123
+ if monitoring.subscribers?(Monitoring::COMMAND)
124
+ publish_command(messages, operation_id || Monitoring.next_operation_id) do |msgs|
125
+ deliver(msgs)
126
+ end
127
+ else
128
+ deliver(messages)
111
129
  end
112
130
  end
113
131
 
@@ -130,33 +148,57 @@ module Mongo
130
148
  @monitoring = server.monitoring
131
149
  @options = options.freeze
132
150
  @server = server
133
- @ssl_options = options.reject { |k, v| !k.to_s.start_with?('ssl') }
151
+ @ssl_options = options.reject { |k, v| !k.to_s.start_with?(SSL) }
134
152
  @socket = nil
135
153
  @pid = Process.pid
136
154
  setup_authentication!
137
155
  end
138
156
 
157
+ # Ping the connection to see if the server is responding to commands.
158
+ # This is non-blocking on the server side.
159
+ #
160
+ # @example Ping the connection.
161
+ # connection.ping
162
+ #
163
+ # @note This uses a pre-serialized ping message for optimization.
164
+ #
165
+ # @return [ true, false ] If the server is accepting connections.
166
+ #
167
+ # @since 2.1.0
168
+ def ping
169
+ ensure_connected do |socket|
170
+ socket.write(PING_BYTES)
171
+ reply = Protocol::Reply.deserialize(socket)
172
+ reply.documents[0][Operation::Result::OK] == 1
173
+ end
174
+ end
175
+
139
176
  private
140
177
 
178
+ def deliver(messages)
179
+ write(messages)
180
+ messages.last.replyable? ? read : nil
181
+ end
182
+
141
183
  def setup_authentication!
142
184
  if options[:user]
143
185
  default_mechanism = @server.features.scram_sha_1_enabled? ? :scram : :mongodb_cr
144
- user = Auth::User.new({ :auth_mech => default_mechanism }.merge(options))
186
+ user = Auth::User.new(Options::Redacted.new(:auth_mech => default_mechanism).merge(options))
145
187
  @authenticator = Auth.get(user)
146
188
  end
147
189
  end
148
190
 
149
- def write(messages, buffer = '')
191
+ def write(messages, buffer = BSON::ByteBuffer.new)
150
192
  start_size = 0
151
193
  messages.each do |message|
152
194
  message.serialize(buffer, max_bson_object_size)
153
195
  if max_message_size &&
154
- (buffer.size - start_size) > max_message_size
196
+ (buffer.length - start_size) > max_message_size
155
197
  raise Error::MaxMessageSize.new(max_message_size)
156
- start_size = buffer.size
198
+ start_size = buffer.length
157
199
  end
158
200
  end
159
- ensure_connected{ |socket| socket.write(buffer) }
201
+ ensure_connected{ |socket| socket.write(buffer.to_s) }
160
202
  end
161
203
  end
162
204
  end
@@ -63,6 +63,21 @@ module Mongo
63
63
  end
64
64
  end
65
65
 
66
+ # Disconnect all connections in the queue.
67
+ #
68
+ # @example Disconnect all connections.
69
+ # queue.disconnect!
70
+ #
71
+ # @return [ true ] Always true.
72
+ #
73
+ # @since 2.1.0
74
+ def disconnect!
75
+ mutex.synchronize do
76
+ queue.each{ |connection| connection.disconnect! }
77
+ true
78
+ end
79
+ end
80
+
66
81
  # Enqueue a connection in the queue.
67
82
  #
68
83
  # @example Enqueue a connection.
@@ -23,9 +23,6 @@ module Mongo
23
23
  class ConnectionPool
24
24
  include Loggable
25
25
 
26
- # Used for synchronization of pools access.
27
- MUTEX = Mutex.new
28
-
29
26
  # @return [ Hash ] options The pool options.
30
27
  attr_reader :options
31
28
 
@@ -54,6 +51,18 @@ module Mongo
54
51
  queue.dequeue
55
52
  end
56
53
 
54
+ # Disconnect the connection pool.
55
+ #
56
+ # @example Disconnect the connection pool.
57
+ # pool.disconnect!
58
+ #
59
+ # @return [ true ] true.
60
+ #
61
+ # @since 2.1.0
62
+ def disconnect!
63
+ queue.disconnect!
64
+ end
65
+
57
66
  # Create the new connection pool.
58
67
  #
59
68
  # @example Create the new connection pool.
@@ -119,22 +128,10 @@ module Mongo
119
128
  #
120
129
  # @since 2.0.0
121
130
  def get(server)
122
- MUTEX.synchronize do
123
- pools[server.address] ||= create_pool(server)
124
- end
125
- end
126
-
127
- private
128
-
129
- def create_pool(server)
130
131
  ConnectionPool.new(server.options) do
131
132
  Connection.new(server, server.options)
132
133
  end
133
134
  end
134
-
135
- def pools
136
- @pools ||= {}
137
- end
138
135
  end
139
136
  end
140
137
  end
@@ -25,16 +25,18 @@ module Mongo
25
25
  #
26
26
  # @since 2.0.0
27
27
  MAPPINGS = {
28
+ :find_command => 4,
28
29
  :list_collections => 3,
29
30
  :list_indexes => 3,
30
31
  :scram_sha_1 => 3,
31
- :write_command => 2
32
+ :write_command => 2,
33
+ :users_info => 2
32
34
  }.freeze
33
35
 
34
36
  # The wire protocol versions that this version of the driver supports.
35
37
  #
36
38
  # @since 2.0.0
37
- DRIVER_WIRE_VERSIONS = (0..3).freeze
39
+ DRIVER_WIRE_VERSIONS = (0..4).freeze
38
40
 
39
41
  # Create the methods for each mapping to tell if they are supported.
40
42
  #
@@ -84,6 +84,11 @@ module Mongo
84
84
  # @since 2.0.0
85
85
  MAX_WRITE_BATCH_SIZE = 'maxWriteBatchSize'.freeze
86
86
 
87
+ # Constant for reading the me field.
88
+ #
89
+ # @since 2.1.0
90
+ ME = 'me'.freeze
91
+
87
92
  # Default max write batch size.
88
93
  #
89
94
  # @since 2.0.0
@@ -137,7 +142,7 @@ module Mongo
137
142
  # Fields to exclude when comparing two descriptions.
138
143
  #
139
144
  # @since 2.0.6
140
- EXCLUDE_FOR_COMPARISON = [ LOCAL_TIME, ELECTION_ID ]
145
+ EXCLUDE_FOR_COMPARISON = [ LOCAL_TIME, ELECTION_ID ].freeze
141
146
 
142
147
  # @return [ Address ] address The server's address.
143
148
  attr_reader :address
@@ -302,6 +307,18 @@ module Mongo
302
307
  config[MIN_WIRE_VERSION] || LEGACY_WIRE_VERSION
303
308
  end
304
309
 
310
+ # Get the me field value.
311
+ #
312
+ # @example Get the me field value.
313
+ # description.me
314
+ #
315
+ # @return [ String ] The me field.
316
+ #
317
+ # @since 2.1.0
318
+ def me
319
+ config[ME]
320
+ end
321
+
305
322
  # Get the tags configured for the server.
306
323
  #
307
324
  # @example Get the tags.
@@ -347,7 +364,8 @@ module Mongo
347
364
  #
348
365
  # @since 2.0.0
349
366
  def other?
350
- !primary? && !secondary? && !passive? && !arbiter?
367
+ (!primary? && !secondary? && !passive? && !arbiter?) ||
368
+ (hidden? && !replica_set_name.nil?)
351
369
  end
352
370
 
353
371
  # Will return true if the server is passive.
@@ -511,6 +529,18 @@ module Mongo
511
529
  !(standalone? || mongos?)
512
530
  end
513
531
 
532
+ # Check if there is a mismatch between the address host and the me field.
533
+ #
534
+ # @example Check if there is a mismatch.
535
+ # description.me_mismatch?
536
+ #
537
+ # @return [ true, false ] If there is a mismatch between the me field and the address host.
538
+ #
539
+ # @since 2.0.6
540
+ def me_mismatch?
541
+ !!(address.to_s != me if me)
542
+ end
543
+
514
544
  # Check equality of two descriptions.
515
545
  #
516
546
  # @example Check description equality.
@@ -524,11 +554,17 @@ module Mongo
524
554
  def ==(other)
525
555
  return false if self.class != other.class
526
556
  return true if config == other.config
557
+ compare_config(other)
558
+ end
559
+ alias_method :eql?, :==
560
+
561
+ private
562
+
563
+ def compare_config(other)
527
564
  !config.keys.empty? && config.keys.all? do |k|
528
565
  config[k] == other.config[k] || EXCLUDE_FOR_COMPARISON.include?(k)
529
566
  end
530
567
  end
531
- alias_method :eql?, :==
532
568
  end
533
569
  end
534
570
  end
@@ -22,6 +22,53 @@ module Mongo
22
22
  class Connection
23
23
  include Connectable
24
24
 
25
+ # The command used for determining server status.
26
+ #
27
+ # @since 2.2.0
28
+ ISMASTER = { :ismaster => 1 }.freeze
29
+
30
+ # The constant for the ismaster command.
31
+ #
32
+ # @since 2.2.0
33
+ ISMASTER_MESSAGE = Protocol::Query.new(Database::ADMIN, Database::COMMAND, ISMASTER, :limit => -1)
34
+
35
+ # The raw bytes for the ismaster message.
36
+ #
37
+ # @since 2.2.0
38
+ ISMASTER_BYTES = ISMASTER_MESSAGE.serialize.to_s.freeze
39
+
40
+ # The default time in seconds to timeout a connection attempt.
41
+ #
42
+ # @since 2.1.2
43
+ CONNECT_TIMEOUT = 10.freeze
44
+
45
+ # Send the preserialized ismaster call.
46
+ #
47
+ # @example Send a preserialized ismaster message.
48
+ # connection.ismaster
49
+ #
50
+ # @return [ BSON::Document ] The ismaster result.
51
+ #
52
+ # @since 2.2.0
53
+ def ismaster
54
+ ensure_connected do |socket|
55
+ socket.write(ISMASTER_BYTES)
56
+ Protocol::Reply.deserialize(socket).documents[0]
57
+ end
58
+ end
59
+
60
+ # Get the connection timeout.
61
+ #
62
+ # @example Get the connection timeout.
63
+ # connection.timeout
64
+ #
65
+ # @return [ Float ] The connection timeout in seconds.
66
+ #
67
+ # @since 2.0.0
68
+ def timeout
69
+ @timeout ||= options[:connect_timeout] || CONNECT_TIMEOUT
70
+ end
71
+
25
72
  # Tell the underlying socket to establish a connection to the host.
26
73
  #
27
74
  # @example Connect to the host.
@@ -36,7 +83,7 @@ module Mongo
36
83
  def connect!
37
84
  unless socket
38
85
  @socket = address.socket(timeout, ssl_options)
39
- @socket.connect!
86
+ socket.connect!
40
87
  end
41
88
  true
42
89
  end
@@ -60,25 +107,6 @@ module Mongo
60
107
  true
61
108
  end
62
109
 
63
- # Dispatch the provided messages to the connection. If the last message
64
- # requires a response a reply will be returned.
65
- #
66
- # @example Dispatch the messages.
67
- # connection.dispatch([ insert, command ])
68
- #
69
- # @note This method is named dispatch since 'send' is a core Ruby method on
70
- # all objects.
71
- #
72
- # @param [ Array<Message> ] messages The messages to dispatch.
73
- #
74
- # @return [ Protocol::Reply ] The reply if needed.
75
- #
76
- # @since 2.0.0
77
- def dispatch(messages)
78
- write(messages)
79
- messages.last.replyable? ? read : nil
80
- end
81
-
82
110
  # Initialize a new socket connection from the client to the server.
83
111
  #
84
112
  # @api private
@@ -96,17 +124,10 @@ module Mongo
96
124
  def initialize(address, options = {})
97
125
  @address = address
98
126
  @options = options.freeze
99
- @ssl_options = options.reject { |k, v| !k.to_s.start_with?('ssl') }
127
+ @ssl_options = options.reject { |k, v| !k.to_s.start_with?(SSL) }
100
128
  @socket = nil
101
129
  @pid = Process.pid
102
130
  end
103
-
104
- private
105
-
106
- def write(messages, buffer = '')
107
- messages.each{ |message| message.serialize(buffer) }
108
- ensure_connected{ |socket| socket.write(buffer) }
109
- end
110
131
  end
111
132
  end
112
133
  end