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
@@ -42,6 +42,31 @@ module Mongo
42
42
  class Message
43
43
  include Serializers
44
44
 
45
+ # The batch size constant.
46
+ #
47
+ # @since 2.2.0
48
+ BATCH_SIZE = 'batchSize'.freeze
49
+
50
+ # The collection constant.
51
+ #
52
+ # @since 2.2.0
53
+ COLLECTION = 'collection'.freeze
54
+
55
+ # The limit constant.
56
+ #
57
+ # @since 2.2.0
58
+ LIMIT = 'limit'.freeze
59
+
60
+ # The ordered constant.
61
+ #
62
+ # @since 2.2.0
63
+ ORDERED = 'ordered'.freeze
64
+
65
+ # The q constant.
66
+ #
67
+ # @since 2.2.0
68
+ Q = 'q'.freeze
69
+
45
70
  # Returns the request id for the message
46
71
  #
47
72
  # @return [Fixnum] The request id for this message
@@ -64,13 +89,11 @@ module Mongo
64
89
  #
65
90
  # @param buffer [String] buffer where the message should be inserted
66
91
  # @return [String] buffer containing the serialized message
67
- def serialize(buffer = ''.force_encoding('BINARY'), max_bson_size = nil)
68
- start = buffer.bytesize
92
+ def serialize(buffer = BSON::ByteBuffer.new, max_bson_size = nil)
93
+ start = buffer.length
69
94
  serialize_header(buffer)
70
95
  serialize_fields(buffer, max_bson_size)
71
- length = buffer.bytesize - start
72
- buffer[start, 4] = Int32.serialize('', length)
73
- buffer
96
+ buffer.replace_int32(start, buffer.length - start)
74
97
  end
75
98
 
76
99
  alias_method :to_s, :serialize
@@ -80,13 +103,14 @@ module Mongo
80
103
  # @param io [IO] Stream containing a message
81
104
  # @return [Message] Instance of a Message class
82
105
  def self.deserialize(io)
83
- deserialize_header(io)
106
+ length = deserialize_header(BSON::ByteBuffer.new(io.read(16))).first
107
+ buffer = BSON::ByteBuffer.new(io.read(length - 16))
84
108
  message = allocate
85
109
  fields.each do |field|
86
110
  if field[:multi]
87
- deserialize_array(message, io, field)
111
+ deserialize_array(message, buffer, field)
88
112
  else
89
- deserialize_field(message, io, field)
113
+ deserialize_field(message, buffer, field)
90
114
  end
91
115
  end
92
116
  message
@@ -114,6 +138,17 @@ module Mongo
114
138
  fields.map { |field| instance_variable_get(field[:name]) }.hash
115
139
  end
116
140
 
141
+ # Generates a request id for a message
142
+ #
143
+ # @return [Fixnum] a request id used for sending a message to the
144
+ # server. The server will put this id in the response_to field of
145
+ # a reply.
146
+ def set_request_id
147
+ @@id_lock.synchronize do
148
+ @request_id = @@request_id += 1
149
+ end
150
+ end
151
+
117
152
  private
118
153
 
119
154
  @@request_id = 0
@@ -158,17 +193,6 @@ module Mongo
158
193
  end
159
194
  end
160
195
 
161
- # Generates a request id for a message
162
- #
163
- # @return [Fixnum] a request id used for sending a message to the
164
- # server. The server will put this id in the response_to field of
165
- # a reply.
166
- def set_request_id
167
- @@id_lock.synchronize do
168
- @request_id = @@request_id += 1
169
- end
170
- end
171
-
172
196
  # Serializes the header of the message consisting of 4 32bit integers
173
197
  #
174
198
  # The integers represent a message length placeholder (calculation of
@@ -181,7 +205,7 @@ module Mongo
181
205
  # @param buffer [String] Buffer to receive the header
182
206
  # @return [String] Serialized header
183
207
  def serialize_header(buffer)
184
- set_request_id
208
+ set_request_id unless @request_id
185
209
  Header.serialize(buffer, [0, request_id, 0, op_code])
186
210
  end
187
211
 
@@ -30,12 +30,6 @@ module Mongo
30
30
  # @api semipublic
31
31
  class Query < Message
32
32
 
33
- # Constant for the max number of characters to print when inspecting
34
- # a query field.
35
- #
36
- # @since 2.0.3
37
- LOG_STRING_LIMIT = 250
38
-
39
33
  # Creates a new Query message
40
34
  #
41
35
  # @example Find all users named Tyler.
@@ -64,14 +58,15 @@ module Mongo
64
58
  # Supported flags: +:tailable_cursor+, +:slave_ok+, +:oplog_replay+,
65
59
  # +:no_cursor_timeout+, +:await_data+, +:exhaust+, +:partial+
66
60
  def initialize(database, collection, selector, options = {})
67
- @database = database
68
- @namespace = "#{database}.#{collection}"
69
- @selector = selector
70
- @options = options
71
- @project = options[:project]
72
- @skip = options[:skip] || 0
73
- @limit = options[:limit] || 0
74
- @flags = options[:flags] || []
61
+ @database = database
62
+ @namespace = "#{database}.#{collection}"
63
+ @selector = selector
64
+ @options = options
65
+ @project = options[:project]
66
+ @limit = determine_limit
67
+ @skip = options[:skip] || 0
68
+ @flags = options[:flags] || []
69
+ @upconverter = Upconverter.new(collection, selector, options, flags)
75
70
  end
76
71
 
77
72
  # Return the event payload for monitoring.
@@ -84,57 +79,13 @@ module Mongo
84
79
  # @since 2.1.0
85
80
  def payload
86
81
  {
87
- command_name: command_name,
82
+ command_name: upconverter.command_name,
88
83
  database_name: @database,
89
- command: arguments,
84
+ command: upconverter.command,
90
85
  request_id: request_id
91
86
  }
92
87
  end
93
88
 
94
- # If the message a command?
95
- #
96
- # @example Is the message a command?
97
- # message.command?
98
- #
99
- # @return [ true, false ] If the message is a command.
100
- #
101
- # @since 2.1.0
102
- def command?
103
- namespace.include?(Database::COMMAND)
104
- end
105
-
106
- # Returns the name of the command.
107
- #
108
- # @example Get the command name.
109
- # message.command_name
110
- #
111
- # @return [ String ] The name of the command, or 'find' if a query.
112
- #
113
- # @since 2.1.0
114
- def command_name
115
- if command?
116
- selector.keys.first
117
- else
118
- 'find'
119
- end
120
- end
121
-
122
- # Get the command arguments.
123
- #
124
- # @example Get the command arguments.
125
- # message.arguments
126
- #
127
- # @return [ Hash ] The command arguments.
128
- #
129
- # @since 2.1.0
130
- def arguments
131
- if command?
132
- selector
133
- else
134
- { filter: selector }.merge(@options)
135
- end
136
- end
137
-
138
89
  # Query messages require replies from the database.
139
90
  #
140
91
  # @example Does the message require a reply?
@@ -149,17 +100,16 @@ module Mongo
149
100
 
150
101
  private
151
102
 
103
+ attr_reader :upconverter
104
+
152
105
  # The operation code required to specify a Query message.
153
106
  # @return [Fixnum] the operation code.
154
107
  def op_code
155
108
  2004
156
109
  end
157
110
 
158
- def formatted_selector
159
- ( (str = selector.inspect).length > LOG_STRING_LIMIT ) ?
160
- "#{str[0..LOG_STRING_LIMIT]}..." : str
161
- rescue ArgumentError
162
- '<Unable to inspect selector>'
111
+ def determine_limit
112
+ [ @options[:limit] || @options[:batch_size], @options[:batch_size] || @options[:limit] ].min || 0
163
113
  end
164
114
 
165
115
  # Available flags for a Query message.
@@ -197,6 +147,144 @@ module Mongo
197
147
  # @!attribute
198
148
  # @return [Hash] The projection.
199
149
  field :project, Document
150
+
151
+ # Converts legacy query messages to the appropriare OP_COMMAND style
152
+ # message.
153
+ #
154
+ # @since 2.1.0
155
+ class Upconverter
156
+
157
+ # Mappings of the options to the find command options.
158
+ #
159
+ # @since 2.1.0
160
+ OPTION_MAPPINGS = {
161
+ :project => 'projection',
162
+ :skip => 'skip',
163
+ :limit => 'limit',
164
+ :batch_size => 'batchSize'
165
+ }.freeze
166
+
167
+ SPECIAL_FIELD_MAPPINGS = {
168
+ :$readPreference => 'readPreference',
169
+ :$orderby => 'sort',
170
+ :$hint => 'hint',
171
+ :$comment => 'comment',
172
+ :$returnKey => 'returnKey',
173
+ :$snapshot => 'snapshot',
174
+ :$maxScan => 'maxScan',
175
+ :$max => 'max',
176
+ :$min => 'min',
177
+ :$maxTimeMS => 'maxTimeMS',
178
+ :$showDiskLoc => 'showRecordId',
179
+ :$explain => 'explain'
180
+ }.freeze
181
+
182
+ # Mapping of flags to find command options.
183
+ #
184
+ # @since 2.1.0
185
+ FLAG_MAPPINGS = {
186
+ :tailable_cursor => 'tailable',
187
+ :oplog_replay => 'oplogReplay',
188
+ :no_cursor_timeout => 'noCursorTimeout',
189
+ :await_data => 'awaitData',
190
+ :partial => 'allowPartialResults'
191
+ }.freeze
192
+
193
+ # Find command constant.
194
+ #
195
+ # @since 2.1.0
196
+ FIND = 'find'.freeze
197
+
198
+ # Filter attribute constant.
199
+ #
200
+ # @since 2.1.0
201
+ FILTER = 'filter'.freeze
202
+
203
+ # @return [ String ] collection The name of the collection.
204
+ attr_reader :collection
205
+
206
+ # @return [ BSON::Document, Hash ] filter The query filter or command.
207
+ attr_reader :filter
208
+
209
+ # @return [ BSON::Document, Hash ] options The options.
210
+ attr_reader :options
211
+
212
+ # @return [ Array<Symbol> ] flags The flags.
213
+ attr_reader :flags
214
+
215
+ # Instantiate the upconverter.
216
+ #
217
+ # @example Instantiate the upconverter.
218
+ # Upconverter.new('users', { name: 'test' }, { skip: 10 })
219
+ #
220
+ # @param [ String ] collection The name of the collection.
221
+ # @param [ BSON::Document, Hash ] filter The filter or command.
222
+ # @param [ BSON::Document, Hash ] options The options.
223
+ # @param [ Array<Symbol> ] flags The flags.
224
+ #
225
+ # @since 2.1.0
226
+ def initialize(collection, filter, options, flags)
227
+ @collection = collection
228
+ @filter = filter
229
+ @options = options
230
+ @flags = flags
231
+ end
232
+
233
+ # Get the upconverted command.
234
+ #
235
+ # @example Get the command.
236
+ # upconverter.command
237
+ #
238
+ # @return [ BSON::Document ] The upconverted command.
239
+ #
240
+ # @since 2.1.0
241
+ def command
242
+ command? ? op_command : find_command
243
+ end
244
+
245
+ # Get the name of the command. If the collection is $cmd then it's the
246
+ # first key in the filter, otherwise it's a find.
247
+ #
248
+ # @example Get the command name.
249
+ # upconverter.command_name
250
+ #
251
+ # @return [ String, Symbol ] The command name.
252
+ #
253
+ # @since 2.1.0
254
+ def command_name
255
+ command? ? filter.keys.first : FIND
256
+ end
257
+
258
+ private
259
+
260
+ def command?
261
+ collection == Database::COMMAND
262
+ end
263
+
264
+ def op_command
265
+ document = BSON::Document.new
266
+ filter.each do |field, value|
267
+ document.store(field.to_s, value)
268
+ end
269
+ document
270
+ end
271
+
272
+ def find_command
273
+ document = BSON::Document.new
274
+ document.store(FIND, collection)
275
+ document.store(FILTER, filter[:$query] ? filter[:$query] : filter)
276
+ OPTION_MAPPINGS.each do |legacy, option|
277
+ document.store(option, options[legacy]) unless options[legacy].nil?
278
+ end
279
+ SPECIAL_FIELD_MAPPINGS.each do |special, normal|
280
+ document.store(normal, filter[special]) unless filter[special].nil?
281
+ end
282
+ FLAG_MAPPINGS.each do |legacy, flag|
283
+ document.store(flag, true) if flags.include?(legacy)
284
+ end
285
+ document
286
+ end
287
+ end
200
288
  end
201
289
  end
202
290
  end
@@ -47,11 +47,15 @@ module Mongo
47
47
  #
48
48
  # @since 2.1.0
49
49
  def payload
50
- { reply: documents, request_id: request_id }
50
+ { reply: upconverter.command, request_id: request_id }
51
51
  end
52
52
 
53
53
  private
54
54
 
55
+ def upconverter
56
+ @upconverter ||= Upconverter.new(documents, cursor_id, starting_from)
57
+ end
58
+
55
59
  # The operation code required to specify a Reply message.
56
60
  # @return [Fixnum] the operation code.
57
61
  def op_code
@@ -91,6 +95,93 @@ module Mongo
91
95
  # @!attribute
92
96
  # @return [Array<Hash>] The documents in this Reply.
93
97
  field :documents, Document, :@number_returned
98
+
99
+ # Upconverts legacy replies to new op command replies.
100
+ #
101
+ # @since 2.1.0
102
+ class Upconverter
103
+
104
+ # Next batch constant.
105
+ #
106
+ # @since 2.1.0
107
+ NEXT_BATCH = 'nextBatch'.freeze
108
+
109
+ # First batch constant.
110
+ #
111
+ # @since 2.1.0
112
+ FIRST_BATCH = 'firstBatch'.freeze
113
+
114
+ # Cursor field constant.
115
+ #
116
+ # @since 2.1.0
117
+ CURSOR = 'cursor'.freeze
118
+
119
+ # Id field constant.
120
+ #
121
+ # @since 2.1.0
122
+ ID = 'id'.freeze
123
+
124
+ # @return [ Array<BSON::Document> ] documents The documents.
125
+ attr_reader :documents
126
+
127
+ # @return [ Integer ] cursor_id The cursor id.
128
+ attr_reader :cursor_id
129
+
130
+ # @return [ Integer ] starting_from The starting point in the cursor.
131
+ attr_reader :starting_from
132
+
133
+ # Initialize the new upconverter.
134
+ #
135
+ # @example Create the upconverter.
136
+ # Upconverter.new(docs, 1, 3)
137
+ #
138
+ # @param [ Array<BSON::Document> ] documents The documents.
139
+ # @param [ Integer ] cursor_id The cursor id.
140
+ # @param [ Integer ] starting_from The starting position.
141
+ #
142
+ # @since 2.1.0
143
+ def initialize(documents, cursor_id, starting_from)
144
+ @documents = documents
145
+ @cursor_id = cursor_id
146
+ @starting_from = starting_from
147
+ end
148
+
149
+ # Get the upconverted command.
150
+ #
151
+ # @example Get the command.
152
+ # upconverter.command
153
+ #
154
+ # @return [ BSON::Document ] The command.
155
+ #
156
+ # @since 2.1.0
157
+ def command
158
+ command? ? op_command : find_command
159
+ end
160
+
161
+ private
162
+
163
+ def batch_field
164
+ starting_from > 0 ? NEXT_BATCH : FIRST_BATCH
165
+ end
166
+
167
+ def command?
168
+ !documents.empty? && documents.first.key?(Operation::Result::OK)
169
+ end
170
+
171
+ def find_command
172
+ document = BSON::Document.new
173
+ cursor_document = BSON::Document.new
174
+ cursor_document.store(ID, cursor_id)
175
+ cursor_document.store(batch_field, documents)
176
+ document.store(Operation::Result::OK, 1)
177
+ document.store(CURSOR, cursor_document)
178
+ document
179
+ end
180
+
181
+ def op_command
182
+ documents.first
183
+ end
184
+ end
94
185
  end
95
186
  end
96
187
  end
@@ -46,20 +46,22 @@ module Mongo
46
46
 
47
47
  # Serializes the header value into the buffer
48
48
  #
49
- # @param buffer [String] Buffer to receive the serialized value.
50
- # @param value [String] Header value to be serialized.
51
- # @return [String] Buffer with serialized value.
49
+ # @param buffer [ String ] Buffer to receive the serialized value.
50
+ # @param value [ String ] Header value to be serialized.
51
+ #
52
+ # @return [ String ] Buffer with serialized value.
52
53
  def self.serialize(buffer, value)
53
- buffer << value.pack(HEADER_PACK)
54
+ buffer.put_bytes(value.pack(HEADER_PACK))
54
55
  end
55
56
 
56
57
  # Deserializes the header value from the IO stream
57
58
  #
58
- # @param io [IO] IO stream containing the message header.
59
- # @return [Array<Fixnum>] Array consisting of the deserialized
59
+ # @param [ String ] buffer Buffer containing the message header.
60
+ #
61
+ # @return [ Array<Fixnum> ] Array consisting of the deserialized
60
62
  # length, request id, response id, and op code.
61
- def self.deserialize(io)
62
- io.read(16).unpack(HEADER_PACK)
63
+ def self.deserialize(buffer)
64
+ buffer.get_bytes(16).unpack(HEADER_PACK)
63
65
  end
64
66
  end
65
67
 
@@ -70,12 +72,12 @@ module Mongo
70
72
 
71
73
  # Serializes a C style string into the buffer
72
74
  #
73
- # @param buffer [String] Buffer to receive the serialized CString.
74
- # @param value [String] The string to be serialized.
75
- # @return [String] Buffer with serialized value.
75
+ # @param buffer [ String ] Buffer to receive the serialized CString.
76
+ # @param value [ String ] The string to be serialized.
77
+ #
78
+ # @return [ String ] Buffer with serialized value.
76
79
  def self.serialize(buffer, value)
77
- buffer << value
78
- buffer << NULL
80
+ buffer.put_cstring(value)
79
81
  end
80
82
  end
81
83
 
@@ -86,11 +88,12 @@ module Mongo
86
88
 
87
89
  # Serializes a 32-bit Zero into the buffer
88
90
  #
89
- # @param buffer [String] Buffer to receive the serialized Zero.
90
- # @param value [Fixnum] Ignored value.
91
- # @return [String] Buffer with serialized value.
91
+ # @param buffer [ String ] Buffer to receive the serialized Zero.
92
+ # @param value [ Fixnum ] Ignored value.
93
+ #
94
+ # @return [ String ] Buffer with serialized value.
92
95
  def self.serialize(buffer, value)
93
- buffer << [ZERO].pack(INT32_PACK)
96
+ buffer.put_int32(ZERO)
94
97
  end
95
98
  end
96
99
 
@@ -101,19 +104,21 @@ module Mongo
101
104
 
102
105
  # Serializes a fixnum to a 4-byte 32-bit integer
103
106
  #
104
- # @param buffer [String] Buffer to receive the serialized Int32.
105
- # @param value [Fixnum] 32-bit integer to be serialized.
107
+ # @param buffer [ String ] Buffer to receive the serialized Int32.
108
+ # @param value [ Fixnum ] 32-bit integer to be serialized.
109
+ #
106
110
  # @return [String] Buffer with serialized value.
107
111
  def self.serialize(buffer, value)
108
- buffer << [value].pack(INT32_PACK)
112
+ buffer.put_int32(value)
109
113
  end
110
114
 
111
115
  # Deserializes a 32-bit Fixnum from the IO stream
112
116
  #
113
- # @param io [IO] IO stream containing the 32-bit integer
114
- # @return [Fixnum] Deserialized Int32
115
- def self.deserialize(io)
116
- io.read(4).unpack(INT32_PACK).first
117
+ # @param [ String ] buffer Buffer containing the 32-bit integer
118
+ #
119
+ # @return [ Fixnum ] Deserialized Int32
120
+ def self.deserialize(buffer)
121
+ buffer.get_int32
117
122
  end
118
123
  end
119
124
 
@@ -124,19 +129,21 @@ module Mongo
124
129
 
125
130
  # Serializes a fixnum to an 8-byte 64-bit integer
126
131
  #
127
- # @param buffer [String] Buffer to receive the serialized Int64.
128
- # @param value [Fixnum] 64-bit integer to be serialized.
129
- # @return [String] Buffer with serialized value.
132
+ # @param buffer [ String ] Buffer to receive the serialized Int64.
133
+ # @param value [ Fixnum ] 64-bit integer to be serialized.
134
+ #
135
+ # @return [ String ] Buffer with serialized value.
130
136
  def self.serialize(buffer, value)
131
- buffer << [value].pack(INT64_PACK)
137
+ buffer.put_int64(value)
132
138
  end
133
139
 
134
140
  # Deserializes a 64-bit Fixnum from the IO stream
135
141
  #
136
- # @param io [IO] IO stream containing the 64-bit integer.
142
+ # @param [ String ] buffer Buffer containing the 64-bit integer.
143
+ #
137
144
  # @return [Fixnum] Deserialized Int64.
138
- def self.deserialize(io)
139
- io.read(8).unpack(INT64_PACK).first
145
+ def self.deserialize(buffer)
146
+ buffer.get_int64
140
147
  end
141
148
  end
142
149
 
@@ -147,23 +154,25 @@ module Mongo
147
154
 
148
155
  # Serializes a document into the buffer
149
156
  #
150
- # @param buffer [String] Buffer to receive the BSON encoded document.
151
- # @param value [Hash] Document to serialize as BSON.
152
- # @return [String] Buffer with serialized value.
157
+ # @param buffer [ String ] Buffer to receive the BSON encoded document.
158
+ # @param value [ Hash ] Document to serialize as BSON.
159
+ #
160
+ # @return [ String ] Buffer with serialized value.
153
161
  def self.serialize(buffer, value, max_bson_size = nil)
154
- start_size = buffer.size
162
+ start_size = buffer.length
155
163
  value.to_bson(buffer)
156
- if max_bson_size && buffer.size - start_size > max_bson_size
164
+ if max_bson_size && buffer.length - start_size > max_bson_size
157
165
  raise Error::MaxBSONSize.new(max_bson_size)
158
166
  end
159
167
  end
160
168
 
161
169
  # Deserializes a document from the IO stream
162
170
  #
163
- # @param io [IO] IO stream containing the BSON encoded document.
164
- # @return [Hash] The decoded BSON document.
165
- def self.deserialize(io)
166
- BSON::Document.from_bson(io)
171
+ # @param [ String ] buffer Buffer containing the BSON encoded document.
172
+ #
173
+ # @return [ Hash ] The decoded BSON document.
174
+ def self.deserialize(buffer)
175
+ BSON::Document.from_bson(buffer)
167
176
  end
168
177
 
169
178
  # Whether there can be a size limit on this type after serialization.