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
@@ -0,0 +1,275 @@
1
+ require 'spec_helper'
2
+
3
+ describe Mongo::Grid::FSBucket::Stream::Read do
4
+
5
+ let(:fs_options) do
6
+ { }
7
+ end
8
+
9
+ let(:fs) do
10
+ authorized_client.database.fs(fs_options)
11
+ end
12
+
13
+ let(:options) do
14
+ { file_id: file_id }
15
+ end
16
+
17
+ let(:filename) do
18
+ 'specs.rb'
19
+ end
20
+
21
+ let!(:file_id) do
22
+ fs.upload_from_stream(filename, File.open(__FILE__))
23
+ end
24
+
25
+ after do
26
+ fs.files_collection.delete_many
27
+ fs.chunks_collection.delete_many
28
+ end
29
+
30
+ let(:stream) do
31
+ described_class.new(fs, options)
32
+ end
33
+
34
+ describe '#initialize' do
35
+
36
+ it 'sets the file id' do
37
+ expect(stream.file_id).to eq(file_id)
38
+ end
39
+
40
+ it 'sets the fs object' do
41
+ expect(stream.fs).to eq(fs)
42
+ end
43
+
44
+ context 'when there is a read preference set on the FSBucket' do
45
+
46
+ let(:fs_options) do
47
+ { read: { mode: :secondary } }
48
+ end
49
+
50
+ it 'uses the read preference of the fs as a default' do
51
+ expect(stream.read_preference).to eq(fs.read_preference)
52
+ end
53
+ end
54
+
55
+ it 'opens a stream' do
56
+ expect(stream.close).to eq(file_id)
57
+ end
58
+
59
+ context 'when provided options' do
60
+
61
+ context 'when provided read preference' do
62
+
63
+ let(:options) do
64
+ {
65
+ file_id: file_id,
66
+ read: { mode: :primary_preferred }
67
+ }
68
+ end
69
+
70
+ it 'sets the read preference' do
71
+ expect(stream.read_preference).to eq(Mongo::ServerSelector.get(options[:read]))
72
+ end
73
+
74
+ it 'sets the read preference on the view' do
75
+ expect(stream.send(:view).read).to eq(Mongo::ServerSelector.get(options[:read]))
76
+ end
77
+ end
78
+
79
+ context 'when provided a file_id' do
80
+
81
+ it 'sets the file id' do
82
+ expect(stream.file_id).to eq(options[:file_id])
83
+ end
84
+ end
85
+ end
86
+ end
87
+
88
+ describe '#each' do
89
+
90
+ let(:filename) do
91
+ 'specs.rb'
92
+ end
93
+
94
+ let!(:file_id) do
95
+ fs.upload_from_stream(filename, File.open(__FILE__))
96
+ end
97
+
98
+ after do
99
+ fs.files_collection.delete_many
100
+ fs.chunks_collection.delete_many
101
+ end
102
+
103
+ let(:fs_options) do
104
+ { chunk_size: 5 }
105
+ end
106
+
107
+ it 'iterates over all the chunks of the file' do
108
+ stream.each do |chunk|
109
+ expect(chunk).not_to be(nil)
110
+ end
111
+ end
112
+
113
+ context 'when the stream is closed' do
114
+
115
+ before do
116
+ stream.close
117
+ end
118
+
119
+ it 'does not allow further iteration' do
120
+ expect {
121
+ stream.to_a
122
+ }.to raise_error(Mongo::Error::ClosedStream)
123
+ end
124
+ end
125
+
126
+ context 'when a chunk is found out of order' do
127
+
128
+ before do
129
+ view = stream.fs.chunks_collection.find({ :files_id => file_id }, options).sort(:n => -1)
130
+ stream.instance_variable_set(:@view, view)
131
+ expect(stream).to receive(:close)
132
+ end
133
+
134
+ it 'raises an exception' do
135
+ expect {
136
+ stream.to_a
137
+ }.to raise_error(Mongo::Error::MissingFileChunk)
138
+ end
139
+
140
+ it 'closes the query' do
141
+ begin
142
+ stream.to_a
143
+ rescue Mongo::Error::MissingFileChunk
144
+ end
145
+ end
146
+ end
147
+
148
+ context 'when a chunk does not have the expected length' do
149
+
150
+ before do
151
+ stream.send(:file_info)
152
+ stream.instance_variable_get(:@file_info).document['chunkSize'] = 4
153
+ expect(stream).to receive(:close)
154
+ end
155
+
156
+ it 'raises an exception' do
157
+ expect {
158
+ stream.to_a
159
+ }.to raise_error(Mongo::Error::UnexpectedChunkLength)
160
+ end
161
+
162
+ it 'closes the query' do
163
+ begin
164
+ stream.to_a
165
+ rescue Mongo::Error::UnexpectedChunkLength
166
+ end
167
+ end
168
+ end
169
+
170
+ context 'when there is no files document found' do
171
+
172
+ before do
173
+ fs.files_collection.delete_many
174
+ end
175
+
176
+ it 'raises an Exception' do
177
+ expect{
178
+ stream.to_a
179
+ }.to raise_exception(Mongo::Error::FileNotFound)
180
+ end
181
+ end
182
+ end
183
+
184
+ describe '#read' do
185
+
186
+ let(:filename) do
187
+ 'specs.rb'
188
+ end
189
+
190
+ let(:file) do
191
+ File.open(__FILE__)
192
+ end
193
+
194
+ let(:file_id) do
195
+ fs.upload_from_stream(filename, file)
196
+ end
197
+
198
+ after do
199
+ fs.files_collection.delete_many
200
+ fs.chunks_collection.delete_many
201
+ end
202
+
203
+ it 'returns a string of all data' do
204
+ expect(stream.read.size).to eq(file.size)
205
+ end
206
+ end
207
+
208
+ describe '#file_info' do
209
+
210
+ it 'returns a files information document' do
211
+ expect(stream.file_info).to be_a(Mongo::Grid::File::Info)
212
+ end
213
+ end
214
+
215
+ describe '#close' do
216
+
217
+ let(:view) do
218
+ stream.instance_variable_get(:@view)
219
+ end
220
+
221
+ before do
222
+ stream.to_a
223
+ end
224
+
225
+ it 'returns the file id' do
226
+ expect(stream.close).to eq(file_id)
227
+ end
228
+
229
+ context 'when the stream is closed' do
230
+
231
+ before do
232
+ stream.to_a
233
+ expect(view).to receive(:close_query).and_call_original
234
+ end
235
+
236
+ it 'calls close_query on the view' do
237
+ expect(stream.close).to be_a(BSON::ObjectId)
238
+ end
239
+ end
240
+
241
+ context 'when the stream is already closed' do
242
+
243
+ before do
244
+ stream.close
245
+ end
246
+
247
+ it 'raises an exception' do
248
+ expect {
249
+ stream.close
250
+ }.to raise_error(Mongo::Error::ClosedStream)
251
+ end
252
+ end
253
+ end
254
+
255
+ describe '#closed?' do
256
+
257
+ context 'when the stream is closed' do
258
+
259
+ before do
260
+ stream.close
261
+ end
262
+
263
+ it 'returns true' do
264
+ expect(stream.closed?).to be(true)
265
+ end
266
+ end
267
+
268
+ context 'when the stream is still open' do
269
+
270
+ it 'returns false' do
271
+ expect(stream.closed?).to be(false)
272
+ end
273
+ end
274
+ end
275
+ end
@@ -0,0 +1,440 @@
1
+ require 'spec_helper'
2
+
3
+ describe Mongo::Grid::FSBucket::Stream::Write do
4
+
5
+ let(:file) do
6
+ File.open(__FILE__)
7
+ end
8
+
9
+ let(:file2) do
10
+ File.open(__FILE__)
11
+ end
12
+
13
+ let(:fs_options) do
14
+ { }
15
+ end
16
+
17
+ let(:fs) do
18
+ authorized_client.database.fs(fs_options)
19
+ end
20
+
21
+ let(:filename) do
22
+ 'specs.rb'
23
+ end
24
+
25
+ let(:extra_options) do
26
+ { }
27
+ end
28
+
29
+ let(:options) do
30
+ { filename: filename }.merge(extra_options)
31
+ end
32
+
33
+ after do
34
+ fs.files_collection.delete_many
35
+ fs.chunks_collection.delete_many
36
+ end
37
+
38
+ let(:stream) do
39
+ described_class.new(fs, options)
40
+ end
41
+
42
+ describe '#initialize' do
43
+
44
+ it 'sets the file id' do
45
+ expect(stream.file_id).to be_a(BSON::ObjectId)
46
+ end
47
+
48
+ it 'sets the fs object' do
49
+ expect(stream.fs).to eq(fs)
50
+ end
51
+
52
+ it 'opens a stream' do
53
+ expect(stream.close).to be_a(BSON::ObjectId)
54
+ end
55
+
56
+ context 'when the fs has a write concern', if: standalone? do
57
+
58
+ let(:fs_options) do
59
+ { write: { w: (WRITE_CONCERN[:w] + 1) } }
60
+ end
61
+
62
+ it 'uses the write concern of the fs as a default' do
63
+ expect{
64
+ stream.close
65
+ }.to raise_exception(Mongo::Error::OperationFailure)
66
+ end
67
+ end
68
+
69
+ context 'when provided options' do
70
+
71
+ context 'when provided a write option' do
72
+
73
+ let(:extra_options) do
74
+ {
75
+ write: { w: (WRITE_CONCERN[:w] + 1) }
76
+ }
77
+ end
78
+
79
+ let(:expected) do
80
+ Mongo::WriteConcern.get(options[:write]).options
81
+ end
82
+
83
+ it 'sets the write concern' do
84
+ expect(stream.write_concern.options).to eq(expected)
85
+ end
86
+
87
+ context 'when chunks are inserted' do
88
+
89
+ it 'uses that write concern' do
90
+ expect(stream.send(:chunks_collection).write_concern.options[:w]).to eq(expected[:w])
91
+ end
92
+ end
93
+
94
+ context 'when a files document is inserted' do
95
+
96
+ it 'uses that write concern' do
97
+ expect(stream.send(:files_collection).write_concern.options[:w]).to eq(expected[:w])
98
+ end
99
+ end
100
+ end
101
+
102
+ context 'when provided a metadata document' do
103
+
104
+ let(:options) do
105
+ {
106
+ metadata: { 'some_field' => 'test-file' }
107
+ }
108
+ end
109
+
110
+ it 'sets the metadata document' do
111
+ expect(stream.send(:file_info).metadata).to eq(options[:metadata])
112
+ end
113
+ end
114
+
115
+ context 'when provided a chunk size option' do
116
+
117
+ let(:options) do
118
+ {
119
+ chunk_size: 50
120
+ }
121
+ end
122
+
123
+ it 'sets the chunk size' do
124
+ expect(stream.send(:file_info).chunk_size).to eq(options[:chunk_size])
125
+ end
126
+
127
+ context 'when chunk size is also set on the FSBucket object' do
128
+
129
+ let(:fs_options) do
130
+ {
131
+ chunk_size: 100
132
+ }
133
+ end
134
+
135
+ it 'uses the write stream options' do
136
+ expect(stream.send(:file_info).chunk_size).to eq(options[:chunk_size])
137
+ end
138
+ end
139
+ end
140
+
141
+ context 'when provided a content type option' do
142
+
143
+ let(:options) do
144
+ {
145
+ content_type: 'text/plain'
146
+ }
147
+ end
148
+
149
+ it 'sets the content type' do
150
+ expect(stream.send(:file_info).content_type).to eq(options[:content_type])
151
+ end
152
+ end
153
+
154
+ context 'when provided an aliases option' do
155
+
156
+ let(:options) do
157
+ {
158
+ aliases: [ 'testing-file' ]
159
+ }
160
+ end
161
+
162
+ it 'sets the aliases' do
163
+ expect(stream.send(:file_info).document[:aliases]).to eq(options[:aliases])
164
+ end
165
+ end
166
+ end
167
+ end
168
+
169
+ describe '#write' do
170
+
171
+ after do
172
+ fs.files_collection.delete_many
173
+ fs.chunks_collection.delete_many
174
+ end
175
+
176
+ let(:file_from_db) do
177
+ fs.find_one(filename: filename)
178
+ end
179
+
180
+ context 'when the stream is written to' do
181
+
182
+ before do
183
+ stream.write(file)
184
+ end
185
+
186
+ it 'does not close the stream' do
187
+ expect(stream).not_to receive(:close)
188
+ end
189
+ end
190
+
191
+ context 'when indexes need to be ensured' do
192
+
193
+ context 'when the files collection is empty' do
194
+
195
+ before do
196
+ fs.files_collection.delete_many
197
+ fs.chunks_collection.delete_many
198
+ expect(fs.files_collection).to receive(:indexes).and_call_original
199
+ expect(fs.chunks_collection).to receive(:indexes).and_call_original
200
+ stream.write(file)
201
+ end
202
+
203
+ let(:chunks_index) do
204
+ fs.database[fs.chunks_collection.name].indexes.get(:files_id => 1, :n => 1)
205
+ end
206
+
207
+ let(:files_index) do
208
+ fs.database[fs.files_collection.name].indexes.get(:filename => 1, :uploadDate => 1)
209
+ end
210
+
211
+ it 'creates an index on the files collection' do
212
+ expect(files_index[:name]).to eq('filename_1_uploadDate_1')
213
+ end
214
+
215
+ it 'creates an index on the chunks collection' do
216
+ expect(chunks_index[:name]).to eq('files_id_1_n_1')
217
+ end
218
+
219
+ context 'when write is called more than once' do
220
+
221
+ before do
222
+ expect(fs).not_to receive(:ensure_indexes!)
223
+ end
224
+
225
+ it 'only creates the indexes the first time' do
226
+ stream.write(file2)
227
+ end
228
+ end
229
+ end
230
+
231
+ context 'when the files collection is not empty' do
232
+
233
+ before do
234
+ fs.files_collection.insert_one(a: 1)
235
+ expect(fs.files_collection).not_to receive(:indexes)
236
+ expect(fs.chunks_collection).not_to receive(:indexes)
237
+ stream.write(file)
238
+ end
239
+
240
+ after do
241
+ fs.files_collection.delete_many
242
+ fs.chunks_collection.delete_many
243
+ end
244
+
245
+ let(:files_index) do
246
+ fs.database[fs.files_collection.name].indexes.get(:filename => 1, :uploadDate => 1)
247
+ end
248
+
249
+ it 'assumes indexes already exist' do
250
+ expect(files_index[:name]).to eq('filename_1_uploadDate_1')
251
+ end
252
+ end
253
+
254
+ context 'when the index creation encounters an error', if: write_command_enabled? do
255
+
256
+ before do
257
+ fs.chunks_collection.drop
258
+ fs.chunks_collection.indexes.create_one(Mongo::Grid::FSBucket::CHUNKS_INDEX, :unique => false)
259
+ expect(fs.chunks_collection).to receive(:indexes).and_call_original
260
+ expect(fs.files_collection).not_to receive(:indexes)
261
+ end
262
+
263
+ after do
264
+ fs.database[fs.chunks_collection.name].indexes.drop_one('files_id_1_n_1')
265
+ end
266
+
267
+ it 'raises the error to the user' do
268
+ expect {
269
+ stream.write(file)
270
+ }.to raise_error(Mongo::Error::OperationFailure)
271
+ end
272
+ end
273
+ end
274
+
275
+ context 'when provided an io stream' do
276
+
277
+ before do
278
+ stream.write(file)
279
+ stream.close
280
+ end
281
+
282
+ it 'writes the contents of the stream' do
283
+ expect(file_from_db.data.size).to eq(file.size)
284
+ end
285
+
286
+ it 'updates the length written' do
287
+ expect(stream.send(:file_info).document['length']).to eq(file.size)
288
+ end
289
+
290
+ it 'updates the position (n)' do
291
+ expect(stream.instance_variable_get(:@n)).to eq(1)
292
+ end
293
+
294
+ context 'when the user file contains no data' do
295
+
296
+ let(:file) do
297
+ StringIO.new('')
298
+ end
299
+
300
+ let(:files_coll_doc) do
301
+ stream.fs.files_collection.find(filename: filename).to_a.first
302
+ end
303
+
304
+ let(:chunks_documents) do
305
+ stream.fs.chunks_collection.find(files_id: stream.file_id).to_a
306
+ end
307
+
308
+ it 'creates a files document' do
309
+ expect(files_coll_doc).not_to be(nil)
310
+ end
311
+
312
+ it 'sets length to 0 in the files document' do
313
+ expect(files_coll_doc['length']).to eq(0)
314
+ end
315
+
316
+ it 'does not insert any chunks' do
317
+ expect(file_from_db.data.size).to eq(file.size)
318
+ end
319
+ end
320
+ end
321
+
322
+ context 'when the stream is written to multiple times' do
323
+
324
+ before do
325
+ stream.write(file)
326
+ stream.write(file2)
327
+ stream.close
328
+ end
329
+
330
+ it 'writes the contents of the stream' do
331
+ expect(file_from_db.data.size).to eq(file.size * 2)
332
+ end
333
+
334
+ it 'updates the length written' do
335
+ expect(stream.send(:file_info).document['length']).to eq(file.size * 2)
336
+ end
337
+
338
+ it 'updates the position (n)' do
339
+ expect(stream.instance_variable_get(:@n)).to eq(2)
340
+ end
341
+ end
342
+
343
+ context 'when the stream is closed' do
344
+
345
+ before do
346
+ stream.close
347
+ end
348
+
349
+ it 'does not allow further writes' do
350
+ expect {
351
+ stream.write(file)
352
+ }.to raise_error(Mongo::Error::ClosedStream)
353
+ end
354
+ end
355
+ end
356
+
357
+ describe '#close' do
358
+
359
+ let(:file_content) do
360
+ File.open(__FILE__).read
361
+ end
362
+
363
+ context 'when close is called on the stream' do
364
+
365
+ before do
366
+ stream.write(file)
367
+ end
368
+
369
+ let(:file_id) do
370
+ stream.file_id
371
+ end
372
+
373
+ it 'returns the file id' do
374
+ expect(stream.close).to eq(file_id)
375
+ end
376
+ end
377
+
378
+ context 'when the stream is closed' do
379
+
380
+ before do
381
+ stream.write(file)
382
+ stream.close
383
+ end
384
+
385
+ let(:md5) do
386
+ Digest::MD5.new.update(file_content).hexdigest
387
+ end
388
+
389
+ let(:files_coll_doc) do
390
+ stream.fs.files_collection.find(filename: filename).to_a.first
391
+ end
392
+
393
+ it 'inserts a file documents in the files collection' do
394
+ expect(files_coll_doc['_id']).to eq(stream.file_id)
395
+ end
396
+
397
+ it 'updates the length in the files collection file document' do
398
+ expect(stream.send(:file_info).document[:length]).to eq(file.size)
399
+ end
400
+
401
+ it 'updates the md5 in the files collection file document' do
402
+ expect(stream.send(:file_info).document[:md5]).to eq(md5)
403
+ end
404
+ end
405
+
406
+ context 'when the stream is already closed' do
407
+
408
+ before do
409
+ stream.close
410
+ end
411
+
412
+ it 'raises an exception' do
413
+ expect {
414
+ stream.close
415
+ }.to raise_error(Mongo::Error::ClosedStream)
416
+ end
417
+ end
418
+ end
419
+
420
+ describe '#closed?' do
421
+
422
+ context 'when the stream is closed' do
423
+
424
+ before do
425
+ stream.close
426
+ end
427
+
428
+ it 'returns true' do
429
+ expect(stream.closed?).to be(true)
430
+ end
431
+ end
432
+
433
+ context 'when the stream is still open' do
434
+
435
+ it 'returns false' do
436
+ expect(stream.closed?).to be(false)
437
+ end
438
+ end
439
+ end
440
+ end