mongo 2.0.6 → 2.1.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 (317) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +5 -2
  3. data/lib/mongo/address/ipv4.rb +6 -1
  4. data/lib/mongo/address/unix.rb +2 -2
  5. data/lib/mongo/address.rb +18 -10
  6. data/lib/mongo/auth/cr/conversation.rb +1 -1
  7. data/lib/mongo/auth/ldap/conversation.rb +7 -3
  8. data/lib/mongo/auth/scram/conversation.rb +9 -3
  9. data/lib/mongo/auth/user/view.rb +23 -2
  10. data/lib/mongo/auth/x509/conversation.rb +1 -1
  11. data/lib/mongo/bulk_write/combineable.rb +51 -0
  12. data/lib/mongo/bulk_write/ordered_combiner.rb +55 -0
  13. data/lib/mongo/bulk_write/result.rb +191 -0
  14. data/lib/mongo/bulk_write/result_combiner.rb +117 -0
  15. data/lib/mongo/bulk_write/transformable.rb +132 -0
  16. data/lib/mongo/bulk_write/unordered_combiner.rb +52 -0
  17. data/lib/mongo/bulk_write/validatable.rb +62 -0
  18. data/lib/mongo/bulk_write.rb +159 -23
  19. data/lib/mongo/client.rb +52 -16
  20. data/lib/mongo/cluster/topology/replica_set.rb +27 -9
  21. data/lib/mongo/cluster/topology/sharded.rb +1 -1
  22. data/lib/mongo/cluster/topology/unknown.rb +5 -2
  23. data/lib/mongo/cluster.rb +42 -7
  24. data/lib/mongo/collection/view/aggregation.rb +48 -9
  25. data/lib/mongo/collection/view/immutable.rb +6 -6
  26. data/lib/mongo/collection/view/iterable.rb +18 -4
  27. data/lib/mongo/collection/view/map_reduce.rb +58 -17
  28. data/lib/mongo/collection/view/readable.rb +173 -42
  29. data/lib/mongo/collection/view/writable.rb +37 -23
  30. data/lib/mongo/collection/view.rb +2 -2
  31. data/lib/mongo/collection.rb +370 -33
  32. data/lib/mongo/cursor.rb +15 -3
  33. data/lib/mongo/database/view.rb +5 -4
  34. data/lib/mongo/database.rb +14 -4
  35. data/lib/mongo/dbref.rb +113 -0
  36. data/lib/mongo/error/closed_stream.rb +34 -0
  37. data/lib/mongo/error/extra_file_chunk.rb +34 -0
  38. data/lib/mongo/error/{invalid_uri_option.rb → file_not_found.rb} +11 -12
  39. data/lib/mongo/error/invalid_file.rb +2 -2
  40. data/lib/mongo/error/invalid_file_revision.rb +37 -0
  41. data/lib/mongo/error/invalid_uri.rb +5 -4
  42. data/lib/mongo/error/missing_file_chunk.rb +38 -0
  43. data/lib/mongo/error/operation_failure.rb +1 -1
  44. data/lib/mongo/error/parser.rb +1 -1
  45. data/lib/mongo/error/unchangeable_collection_option.rb +38 -0
  46. data/lib/mongo/error/unexpected_chunk_length.rb +39 -0
  47. data/lib/mongo/error.rb +13 -2
  48. data/lib/mongo/event/description_changed.rb +1 -1
  49. data/lib/mongo/grid/file/chunk.rb +6 -6
  50. data/lib/mongo/grid/file/{metadata.rb → info.rb} +41 -39
  51. data/lib/mongo/grid/file.rb +13 -10
  52. data/lib/mongo/grid/fs_bucket.rb +448 -0
  53. data/lib/mongo/grid/stream/read.rb +208 -0
  54. data/lib/mongo/grid/stream/write.rb +187 -0
  55. data/lib/mongo/grid/stream.rb +64 -0
  56. data/lib/mongo/grid.rb +2 -1
  57. data/lib/mongo/index/view.rb +3 -3
  58. data/lib/mongo/index.rb +5 -0
  59. data/lib/mongo/loggable.rb +34 -57
  60. data/lib/mongo/logger.rb +16 -78
  61. data/lib/mongo/monitoring/command_log_subscriber.rb +112 -0
  62. data/lib/mongo/monitoring/event/command_failed.rb +96 -0
  63. data/lib/mongo/monitoring/event/command_started.rb +89 -0
  64. data/lib/mongo/monitoring/event/command_succeeded.rb +118 -0
  65. data/lib/mongo/monitoring/event/secure.rb +58 -0
  66. data/lib/mongo/monitoring/event.rb +18 -0
  67. data/lib/mongo/monitoring/publishable.rb +106 -0
  68. data/lib/mongo/monitoring.rb +195 -0
  69. data/lib/mongo/operation/{aggregate.rb → commands/aggregate.rb} +3 -41
  70. data/lib/mongo/operation/commands/collections_info/result.rb +39 -0
  71. data/lib/mongo/operation/commands/collections_info.rb +68 -0
  72. data/lib/mongo/operation/{command.rb → commands/command.rb} +2 -18
  73. data/lib/mongo/operation/commands/indexes.rb +70 -0
  74. data/lib/mongo/operation/commands/list_collections/result.rb +112 -0
  75. data/lib/mongo/operation/commands/list_collections.rb +54 -0
  76. data/lib/mongo/operation/commands/list_indexes/result.rb +116 -0
  77. data/lib/mongo/operation/commands/list_indexes.rb +56 -0
  78. data/lib/mongo/operation/{map_reduce → commands/map_reduce}/result.rb +1 -1
  79. data/lib/mongo/operation/{map_reduce.rb → commands/map_reduce.rb} +3 -41
  80. data/lib/mongo/operation/commands/parallel_scan/result.rb +72 -0
  81. data/lib/mongo/operation/commands/parallel_scan.rb +56 -0
  82. data/lib/mongo/operation/commands/user_query.rb +69 -0
  83. data/lib/mongo/{bulk_write/ordered_bulk_write.rb → operation/commands/users_info/result.rb} +18 -30
  84. data/lib/mongo/operation/commands/users_info.rb +53 -0
  85. data/lib/mongo/operation/commands.rb +24 -0
  86. data/lib/mongo/operation/executable.rb +4 -68
  87. data/lib/mongo/operation/kill_cursors.rb +3 -3
  88. data/lib/mongo/operation/read/get_more.rb +2 -22
  89. data/lib/mongo/{bulk_write/unordered_bulk_write.rb → operation/read/query/result.rb} +20 -26
  90. data/lib/mongo/operation/read/query.rb +4 -21
  91. data/lib/mongo/operation/read.rb +0 -4
  92. data/lib/mongo/operation/{read_preferrable.rb → read_preference.rb} +3 -2
  93. data/lib/mongo/operation/result.rb +13 -1
  94. data/lib/mongo/operation/specifiable.rb +42 -0
  95. data/lib/mongo/operation/write/bulk/bulkable.rb +82 -0
  96. data/lib/mongo/operation/write/bulk/delete/result.rb +74 -0
  97. data/lib/mongo/operation/write/bulk/delete.rb +71 -0
  98. data/lib/mongo/operation/write/bulk/insert/result.rb +129 -0
  99. data/lib/mongo/operation/write/bulk/insert.rb +96 -0
  100. data/lib/mongo/operation/write/bulk/legacy_mergable.rb +87 -0
  101. data/lib/mongo/operation/write/bulk/mergable.rb +71 -0
  102. data/lib/mongo/operation/write/bulk/update/result.rb +174 -0
  103. data/lib/mongo/operation/write/bulk/update.rb +81 -0
  104. data/lib/mongo/operation/write/bulk.rb +6 -3
  105. data/lib/mongo/operation/write/command/create_index.rb +0 -1
  106. data/lib/mongo/operation/write/command/create_user.rb +0 -1
  107. data/lib/mongo/operation/write/command/delete.rb +0 -1
  108. data/lib/mongo/operation/write/command/drop_index.rb +0 -1
  109. data/lib/mongo/operation/write/command/insert.rb +0 -1
  110. data/lib/mongo/operation/write/command/remove_user.rb +0 -1
  111. data/lib/mongo/operation/write/command/update.rb +0 -1
  112. data/lib/mongo/operation/write/command/update_user.rb +0 -1
  113. data/lib/mongo/operation/write/command/writable.rb +13 -18
  114. data/lib/mongo/operation/write/create_index.rb +4 -27
  115. data/lib/mongo/operation/write/create_user.rb +4 -30
  116. data/lib/mongo/operation/write/delete.rb +6 -29
  117. data/lib/mongo/operation/write/drop_index.rb +3 -3
  118. data/lib/mongo/operation/write/gle.rb +48 -0
  119. data/lib/mongo/operation/write/idable.rb +5 -0
  120. data/lib/mongo/operation/write/insert.rb +2 -24
  121. data/lib/mongo/operation/write/remove_user.rb +4 -27
  122. data/lib/mongo/operation/write/update.rb +13 -36
  123. data/lib/mongo/operation/write/update_user.rb +4 -30
  124. data/lib/mongo/operation/write/write_command_enabled.rb +53 -0
  125. data/lib/mongo/operation/write.rb +2 -0
  126. data/lib/mongo/operation.rb +32 -4
  127. data/lib/mongo/options/mapper.rb +4 -2
  128. data/lib/mongo/options/redacted.rb +156 -0
  129. data/lib/mongo/options.rb +1 -0
  130. data/lib/mongo/protocol/delete.rb +75 -15
  131. data/lib/mongo/protocol/get_more.rb +65 -13
  132. data/lib/mongo/protocol/insert.rb +85 -13
  133. data/lib/mongo/protocol/kill_cursors.rb +59 -14
  134. data/lib/mongo/protocol/message.rb +12 -12
  135. data/lib/mongo/protocol/query.rb +163 -37
  136. data/lib/mongo/protocol/reply.rb +103 -0
  137. data/lib/mongo/protocol/serializers.rb +1 -1
  138. data/lib/mongo/protocol/update.rb +82 -14
  139. data/lib/mongo/retryable.rb +83 -0
  140. data/lib/mongo/server/connectable.rb +21 -25
  141. data/lib/mongo/server/connection.rb +75 -4
  142. data/lib/mongo/server/connection_pool/queue.rb +15 -0
  143. data/lib/mongo/server/connection_pool.rb +12 -0
  144. data/lib/mongo/server/description/features.rb +2 -1
  145. data/lib/mongo/server/description.rb +52 -1
  146. data/lib/mongo/server/monitor/connection.rb +26 -2
  147. data/lib/mongo/server/monitor.rb +19 -3
  148. data/lib/mongo/server.rb +39 -5
  149. data/lib/mongo/server_selector/selectable.rb +40 -31
  150. data/lib/mongo/server_selector.rb +19 -10
  151. data/lib/mongo/socket/ssl.rb +28 -16
  152. data/lib/mongo/socket/tcp.rb +3 -3
  153. data/lib/mongo/socket/unix.rb +5 -8
  154. data/lib/mongo/socket.rb +11 -4
  155. data/lib/mongo/uri.rb +248 -137
  156. data/lib/mongo/version.rb +1 -1
  157. data/lib/mongo.rb +5 -3
  158. data/spec/mongo/address/unix_spec.rb +1 -1
  159. data/spec/mongo/address_spec.rb +25 -0
  160. data/spec/mongo/auth/cr_spec.rb +9 -1
  161. data/spec/mongo/auth/ldap/conversation_spec.rb +43 -0
  162. data/spec/mongo/auth/ldap_spec.rb +9 -1
  163. data/spec/mongo/auth/scram_spec.rb +9 -1
  164. data/spec/mongo/auth/user/view_spec.rb +26 -1
  165. data/spec/mongo/auth/x509_spec.rb +9 -1
  166. data/spec/mongo/bulk_write/ordered_combiner_spec.rb +271 -0
  167. data/spec/mongo/bulk_write/unordered_combiner_spec.rb +239 -0
  168. data/spec/mongo/bulk_write_spec.rb +428 -0
  169. data/spec/mongo/client_spec.rb +167 -17
  170. data/spec/mongo/cluster/topology/replica_set_spec.rb +18 -9
  171. data/spec/mongo/cluster/topology/sharded_spec.rb +11 -3
  172. data/spec/mongo/cluster/topology/single_spec.rb +12 -4
  173. data/spec/mongo/cluster_spec.rb +55 -10
  174. data/spec/mongo/collection/view/aggregation_spec.rb +188 -1
  175. data/spec/mongo/collection/view/explainable_spec.rb +1 -1
  176. data/spec/mongo/collection/view/immutable_spec.rb +103 -0
  177. data/spec/mongo/collection/view/map_reduce_spec.rb +99 -4
  178. data/spec/mongo/collection/view/readable_spec.rb +238 -6
  179. data/spec/mongo/collection/view/writable_spec.rb +4 -4
  180. data/spec/mongo/collection/view_spec.rb +459 -71
  181. data/spec/mongo/collection_spec.rb +1291 -9
  182. data/spec/mongo/command_monitoring_spec.rb +51 -0
  183. data/spec/mongo/connection_string_spec.rb +115 -0
  184. data/spec/mongo/crud_spec.rb +2 -2
  185. data/spec/mongo/cursor_spec.rb +3 -3
  186. data/spec/mongo/database_spec.rb +47 -11
  187. data/spec/mongo/dbref_spec.rb +149 -0
  188. data/spec/mongo/grid/file/chunk_spec.rb +5 -5
  189. data/spec/mongo/grid/file/{metadata_spec.rb → info_spec.rb} +29 -17
  190. data/spec/mongo/grid/file_spec.rb +8 -8
  191. data/spec/mongo/grid/fs_bucket_spec.rb +1020 -0
  192. data/spec/mongo/grid/stream/read_spec.rb +275 -0
  193. data/spec/mongo/grid/stream/write_spec.rb +440 -0
  194. data/spec/mongo/grid/stream_spec.rb +48 -0
  195. data/spec/mongo/gridfs_spec.rb +50 -0
  196. data/spec/mongo/logger_spec.rb +0 -40
  197. data/spec/mongo/monitoring/command_log_subscriber_spec.rb +76 -0
  198. data/spec/mongo/monitoring/event/command_started_spec.rb +26 -0
  199. data/spec/mongo/monitoring/event/command_succeeded_spec.rb +26 -0
  200. data/spec/mongo/monitoring/event/secure_spec.rb +57 -0
  201. data/spec/mongo/monitoring_spec.rb +168 -0
  202. data/spec/mongo/operation/commands/aggregate_spec.rb +69 -0
  203. data/spec/mongo/operation/{read → commands}/collections_info_spec.rb +1 -1
  204. data/spec/mongo/operation/{command_spec.rb → commands/command_spec.rb} +0 -18
  205. data/spec/mongo/operation/{read → commands}/indexes_spec.rb +1 -1
  206. data/spec/mongo/operation/{map_reduce_spec.rb → commands/map_reduce_spec.rb} +1 -19
  207. data/spec/mongo/operation/kill_cursors_spec.rb +1 -17
  208. data/spec/mongo/operation/read/get_more_spec.rb +0 -16
  209. data/spec/mongo/operation/read/query_spec.rb +19 -16
  210. data/spec/mongo/operation/{read_preferrable_spec.rb → read_preference_spec.rb} +11 -11
  211. data/spec/mongo/operation/write/bulk/{bulk_delete_spec.rb → delete_spec.rb} +18 -29
  212. data/spec/mongo/operation/write/bulk/{bulk_insert_spec.rb → insert_spec.rb} +3 -14
  213. data/spec/mongo/operation/write/bulk/{bulk_update_spec.rb → update_spec.rb} +8 -19
  214. data/spec/mongo/operation/write/command/delete_spec.rb +0 -16
  215. data/spec/mongo/operation/write/command/insert_spec.rb +0 -16
  216. data/spec/mongo/operation/write/command/update_spec.rb +0 -16
  217. data/spec/mongo/operation/write/delete_spec.rb +4 -4
  218. data/spec/mongo/operation/write/insert_spec.rb +2 -13
  219. data/spec/mongo/operation/write/update_spec.rb +7 -7
  220. data/spec/mongo/options/redacted_spec.rb +350 -0
  221. data/spec/mongo/protocol/kill_cursors_spec.rb +5 -3
  222. data/spec/mongo/protocol/query_spec.rb +15 -30
  223. data/spec/mongo/retryable_spec.rb +147 -0
  224. data/spec/mongo/server/connection_pool/queue_spec.rb +16 -0
  225. data/spec/mongo/server/connection_pool_spec.rb +50 -6
  226. data/spec/mongo/server/connection_spec.rb +49 -4
  227. data/spec/mongo/server/description_spec.rb +49 -3
  228. data/spec/mongo/server/monitor_spec.rb +51 -0
  229. data/spec/mongo/server_discovery_and_monitoring_spec.rb +32 -59
  230. data/spec/mongo/server_selection_rtt_spec.rb +37 -57
  231. data/spec/mongo/server_selection_spec.rb +19 -9
  232. data/spec/mongo/server_selector/nearest_spec.rb +35 -27
  233. data/spec/mongo/server_selector/primary_preferred_spec.rb +32 -30
  234. data/spec/mongo/server_selector/primary_spec.rb +21 -14
  235. data/spec/mongo/server_selector/secondary_preferred_spec.rb +28 -26
  236. data/spec/mongo/server_selector/secondary_spec.rb +24 -22
  237. data/spec/mongo/server_selector_spec.rb +87 -24
  238. data/spec/mongo/server_spec.rb +94 -8
  239. data/spec/mongo/socket/ssl_spec.rb +123 -13
  240. data/spec/mongo/socket/unix_spec.rb +52 -0
  241. data/spec/mongo/uri_spec.rb +295 -67
  242. data/spec/spec_helper.rb +40 -24
  243. data/spec/support/authorization.rb +23 -9
  244. data/spec/support/certificates/client.pem +4 -4
  245. data/spec/support/command_monitoring/bulkWrite.yml +73 -0
  246. data/spec/support/command_monitoring/command.yml +42 -0
  247. data/spec/support/command_monitoring/deleteMany.yml +55 -0
  248. data/spec/support/command_monitoring/deleteOne.yml +55 -0
  249. data/spec/support/command_monitoring/find.yml +219 -0
  250. data/spec/support/command_monitoring/insertMany.yml +81 -0
  251. data/spec/support/command_monitoring/insertOne.yml +51 -0
  252. data/spec/support/command_monitoring/updateMany.yml +67 -0
  253. data/spec/support/command_monitoring/updateOne.yml +95 -0
  254. data/spec/support/command_monitoring.rb +365 -0
  255. data/spec/support/connection_string.rb +228 -0
  256. data/spec/support/connection_string_tests/invalid-uris.yml +193 -0
  257. data/spec/support/connection_string_tests/valid-auth.yml +256 -0
  258. data/spec/support/connection_string_tests/valid-host_identifiers.yml +121 -0
  259. data/spec/support/connection_string_tests/valid-options.yml +30 -0
  260. data/spec/support/connection_string_tests/valid-unix_socket-absolute.yml +197 -0
  261. data/spec/support/connection_string_tests/valid-unix_socket-relative.yml +213 -0
  262. data/spec/support/connection_string_tests/valid-warnings.yml +55 -0
  263. data/spec/support/crud/read.rb +22 -19
  264. data/spec/support/crud/write.rb +58 -27
  265. data/spec/support/crud.rb +10 -2
  266. data/spec/support/gridfs.rb +637 -0
  267. data/spec/support/gridfs_tests/delete.yml +157 -0
  268. data/spec/support/gridfs_tests/download.yml +210 -0
  269. data/spec/support/gridfs_tests/download_by_name.yml +113 -0
  270. data/spec/support/gridfs_tests/upload.yml +158 -0
  271. data/spec/support/matchers.rb +1 -1
  272. data/spec/support/sdam/rs/equal_electionids.yml +44 -0
  273. data/spec/support/sdam/rs/new_primary_new_electionid.yml +95 -0
  274. data/spec/support/sdam/rs/null_election_id.yml +144 -0
  275. data/spec/support/sdam/rs/primary_disconnect_electionid.yml +124 -0
  276. data/spec/support/sdam/rs/primary_mismatched_me.yml +37 -0
  277. data/spec/support/sdam/rs/primary_to_no_primary_mismatched_me.yml +75 -0
  278. data/spec/support/sdam/rs/secondary_mismatched_me.yml +37 -0
  279. data/spec/support/sdam/sharded/mongos_disconnect.yml +104 -0
  280. data/spec/support/sdam/single/direct_connection_rsarbiter.yml +1 -1
  281. data/spec/support/sdam/single/direct_connection_rsprimary.yml +1 -1
  282. data/spec/support/sdam/single/direct_connection_rssecondary.yml +1 -1
  283. data/spec/support/sdam/single/direct_connection_slave.yml +1 -1
  284. data/spec/support/sdam/single/direct_connection_standalone.yml +1 -1
  285. data/spec/support/sdam/single/not_ok_response.yml +0 -1
  286. data/spec/support/server_discovery_and_monitoring.rb +22 -3
  287. data/spec/support/server_selection.rb +3 -1
  288. data/spec/support/shared/bulk_write.rb +218 -22
  289. data/spec/support/shared/server_selector.rb +80 -14
  290. data.tar.gz.sig +0 -0
  291. metadata +188 -59
  292. metadata.gz.sig +0 -0
  293. data/lib/mongo/bulk_write/bulk_writable.rb +0 -196
  294. data/lib/mongo/bulk_write/deletable.rb +0 -56
  295. data/lib/mongo/bulk_write/insertable.rb +0 -48
  296. data/lib/mongo/bulk_write/replacable.rb +0 -57
  297. data/lib/mongo/bulk_write/updatable.rb +0 -68
  298. data/lib/mongo/grid/fs.rb +0 -149
  299. data/lib/mongo/operation/list_collections/result.rb +0 -114
  300. data/lib/mongo/operation/list_indexes/result.rb +0 -118
  301. data/lib/mongo/operation/read/collections_info.rb +0 -68
  302. data/lib/mongo/operation/read/indexes.rb +0 -69
  303. data/lib/mongo/operation/read/list_collections.rb +0 -76
  304. data/lib/mongo/operation/read/list_indexes.rb +0 -78
  305. data/lib/mongo/operation/write/bulk/bulk_delete/result.rb +0 -75
  306. data/lib/mongo/operation/write/bulk/bulk_delete.rb +0 -145
  307. data/lib/mongo/operation/write/bulk/bulk_insert/result.rb +0 -130
  308. data/lib/mongo/operation/write/bulk/bulk_insert.rb +0 -132
  309. data/lib/mongo/operation/write/bulk/bulk_mergable.rb +0 -67
  310. data/lib/mongo/operation/write/bulk/bulk_update/result.rb +0 -162
  311. data/lib/mongo/operation/write/bulk/bulk_update.rb +0 -154
  312. data/lib/mongo/operation/write/bulk/legacy_bulk_mergable.rb +0 -83
  313. data/spec/mongo/bulk/bulk_write_spec.rb +0 -262
  314. data/spec/mongo/grid/fs_spec.rb +0 -160
  315. data/spec/mongo/loggable_spec.rb +0 -63
  316. data/spec/mongo/operation/aggregate_spec.rb +0 -127
  317. /data/lib/mongo/operation/{aggregate → commands/aggregate}/result.rb +0 -0
@@ -52,33 +52,36 @@ module Mongo
52
52
  #
53
53
  # Supported flags: +:upsert+, +:multi_update+
54
54
  def initialize(database, collection, selector, update, options = {})
55
+ @database = database
56
+ @collection = collection
55
57
  @namespace = "#{database}.#{collection}"
56
58
  @selector = selector
57
59
  @update = update
58
60
  @flags = options[:flags] || []
61
+ @upconverter = Upconverter.new(collection, selector, update, flags)
59
62
  end
60
63
 
61
- # The log message for an update operation.
64
+ # Return the event payload for monitoring.
62
65
  #
63
- # @example Get the log message.
64
- # update.log_message
66
+ # @example Return the event payload.
67
+ # message.payload
65
68
  #
66
- # @return [ String ] The log message
69
+ # @return [ Hash ] The event payload.
67
70
  #
68
- # @since 2.0.0
69
- def log_message
70
- fields = []
71
- fields << ["%s |", "UPDATE"]
72
- fields << ["namespace=%s", namespace]
73
- fields << ["selector=%s", selector.inspect]
74
- fields << ["udpdate=%s", update.inspect]
75
- fields << ["flags=%s", flags.inspect]
76
- f, v = fields.transpose
77
- f.join(" ") % v
71
+ # @since 2.1.0
72
+ def payload
73
+ {
74
+ command_name: 'update',
75
+ database_name: @database,
76
+ command: upconverter.command,
77
+ request_id: request_id
78
+ }
78
79
  end
79
80
 
80
81
  private
81
82
 
83
+ attr_reader :upconverter
84
+
82
85
  # The operation code required to specify an Update message.
83
86
  # @return [Fixnum] the operation code.
84
87
  def op_code
@@ -106,6 +109,71 @@ module Mongo
106
109
  # @!attribute
107
110
  # @return [Hash] The update for this Delete message.
108
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
+ # @return [ String ] collection The name of the collection.
120
+ attr_reader :collection
121
+
122
+ # @return [ Hash ] filter The filter.
123
+ attr_reader :filter
124
+
125
+ # @return [ Hash ] update The update.
126
+ attr_reader :update
127
+
128
+ # @return [ Array<Symbol> ] flags The flags.
129
+ attr_reader :flags
130
+
131
+ # Instantiate the upconverter.
132
+ #
133
+ # @example Instantiate the upconverter.
134
+ # Upconverter.new(
135
+ # 'users',
136
+ # { name: 'test' },
137
+ # { '$set' => { 'name' => 't' }},
138
+ # []
139
+ # )
140
+ #
141
+ # @param [ String ] collection The name of the collection.
142
+ # @param [ Hash ] filter The filter.
143
+ # @param [ Hash ] update The update.
144
+ # @param [ Array<Symbol> ] flags The flags.
145
+ #
146
+ # @since 2.1.0
147
+ def initialize(collection, filter, update, flags)
148
+ @collection = collection
149
+ @filter = filter
150
+ @update = update
151
+ @flags = flags
152
+ end
153
+
154
+ # Get the upconverted command.
155
+ #
156
+ # @example Get the command.
157
+ # upconverter.command
158
+ #
159
+ # @return [ BSON::Document ] The upconverted command.
160
+ #
161
+ # @since 2.1.0
162
+ def command
163
+ BSON::Document.new(
164
+ update: collection,
165
+ ordered: true,
166
+ updates: [
167
+ BSON::Document.new(
168
+ q: filter,
169
+ u: update,
170
+ multi: flags.include?(:multi_update),
171
+ upsert: flags.include?(:upsert),
172
+ )
173
+ ]
174
+ )
175
+ end
176
+ end
109
177
  end
110
178
  end
111
179
  end
@@ -0,0 +1,83 @@
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
+ # @example Execute the read.
30
+ # read_with_retry do
31
+ # ...
32
+ # end
33
+ #
34
+ # @note This only retries read operations on socket errors.
35
+ #
36
+ # @param [ Proc ] block The block to execute.
37
+ #
38
+ # @return [ Result ] The result of the operation.
39
+ #
40
+ # @since 2.1.0
41
+ def read_with_retry(&block)
42
+ begin
43
+ block.call
44
+ rescue Error::SocketError, Error::SocketTimeoutError
45
+ retry_operation(&block)
46
+ end
47
+ end
48
+
49
+ # Execute a write operation with a retry.
50
+ #
51
+ # @example Execute the write.
52
+ # write_with_retry do
53
+ # ...
54
+ # end
55
+ #
56
+ # @note This only retries operations on not master failures, since it is
57
+ # the only case we can be sure a partial write did not already occur.
58
+ #
59
+ # @param [ Proc ] block The block to execute.
60
+ #
61
+ # @return [ Result ] The result of the operation.
62
+ #
63
+ # @since 2.1.0
64
+ def write_with_retry(&block)
65
+ begin
66
+ block.call
67
+ rescue Error::OperationFailure => e
68
+ if e.message.include?(NOT_MASTER)
69
+ retry_operation(&block)
70
+ else
71
+ raise e
72
+ end
73
+ end
74
+ end
75
+
76
+ private
77
+
78
+ def retry_operation(&block)
79
+ cluster.scan!
80
+ block.call
81
+ end
82
+ end
83
+ end
@@ -19,7 +19,11 @@ module Mongo
19
19
  #
20
20
  # @since 2.0.0
21
21
  module Connectable
22
- include Loggable
22
+
23
+ # The ssl option prefix.
24
+ #
25
+ # @since 2.1.0
26
+ SSL = 'ssl'.freeze
23
27
 
24
28
  # The default time in seconds to timeout a connection attempt.
25
29
  #
@@ -35,6 +39,19 @@ module Mongo
35
39
  # @return [ Integer ] pid The process id when the connection was created.
36
40
  attr_reader :pid
37
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
+
38
55
  # Determine if the connection is currently connected.
39
56
  #
40
57
  # @example Is the connection connected?
@@ -42,32 +59,11 @@ module Mongo
42
59
  #
43
60
  # @return [ true, false ] If connected.
44
61
  #
45
- # @since 2.0.0
62
+ # @deprecated Use #connectable? instead
46
63
  def connected?
47
64
  !!@socket && @socket.alive?
48
65
  end
49
66
 
50
- # Dispatch the provided messages to the connection. If the last message
51
- # requires a response a reply will be returned.
52
- #
53
- # @example Dispatch the messages.
54
- # connection.dispatch([ insert, command ])
55
- #
56
- # @note This method is named dispatch since 'send' is a core Ruby method on
57
- # all objects.
58
- #
59
- # @param [ Array<Message> ] messages The messages to dispatch.
60
- #
61
- # @return [ Protocol::Reply ] The reply if needed.
62
- #
63
- # @since 2.0.0
64
- def dispatch(messages)
65
- log_debug(messages) do |msgs|
66
- write(msgs)
67
- msgs.last.replyable? ? read : nil
68
- end
69
- end
70
-
71
67
  # Get the connection timeout.
72
68
  #
73
69
  # @example Get the connection timeout.
@@ -90,10 +86,10 @@ module Mongo
90
86
 
91
87
  def ensure_connected
92
88
  ensure_same_process!
93
- connect! if socket.nil? || !socket.alive?
89
+ connect!
94
90
  begin
95
91
  yield socket
96
- rescue Error::SocketError, Error::SocketTimeoutError => e
92
+ rescue Exception => e
97
93
  disconnect!
98
94
  raise e
99
95
  end
@@ -20,8 +20,24 @@ module Mongo
20
20
  # @since 2.0.0
21
21
  class Connection
22
22
  include Connectable
23
+ include Monitoring::Publishable
23
24
  extend Forwardable
24
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.freeze
40
+
25
41
  # @return [ Mongo::Auth::CR, Mongo::Auth::X509, Mongo::Auth:LDAP, Mongo::Auth::SCRAM ]
26
42
  # authenticator The authentication strategy.
27
43
  attr_reader :authenticator
@@ -59,7 +75,7 @@ module Mongo
59
75
  def connect!
60
76
  unless socket
61
77
  @socket = address.socket(timeout, ssl_options)
62
- @socket.connect!
78
+ socket.connect!
63
79
  if authenticator
64
80
  authenticator.login(self)
65
81
  @authenticated = true
@@ -88,36 +104,91 @@ module Mongo
88
104
  true
89
105
  end
90
106
 
107
+ # Dispatch the provided messages to the connection. If the last message
108
+ # requires a response a reply will be returned.
109
+ #
110
+ # @example Dispatch the messages.
111
+ # connection.dispatch([ insert, command ])
112
+ #
113
+ # @note This method is named dispatch since 'send' is a core Ruby method on
114
+ # all objects.
115
+ #
116
+ # @param [ Array<Message> ] messages The messages to dispatch.
117
+ # @param [ Integer ] operation_id The operation id to link messages.
118
+ #
119
+ # @return [ Protocol::Reply ] The reply if needed.
120
+ #
121
+ # @since 2.0.0
122
+ def dispatch(messages, operation_id = 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)
129
+ end
130
+ end
131
+
91
132
  # Initialize a new socket connection from the client to the server.
92
133
  #
134
+ # @api private
135
+ #
93
136
  # @example Create the connection.
94
137
  # Connection.new(server)
95
138
  #
139
+ # @note Connection must never be directly instantiated outside of a
140
+ # Server.
141
+ #
96
142
  # @param [ Mongo::Server ] server The server the connection is for.
97
143
  # @param [ Hash ] options The connection options.
98
144
  #
99
145
  # @since 2.0.0
100
146
  def initialize(server, options = {})
101
147
  @address = server.address
148
+ @monitoring = server.monitoring
102
149
  @options = options.freeze
103
150
  @server = server
104
- @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) }
105
152
  @socket = nil
106
153
  @pid = Process.pid
107
154
  setup_authentication!
108
155
  end
109
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
+
110
176
  private
111
177
 
178
+ def deliver(messages)
179
+ write(messages)
180
+ messages.last.replyable? ? read : nil
181
+ end
182
+
112
183
  def setup_authentication!
113
184
  if options[:user]
114
185
  default_mechanism = @server.features.scram_sha_1_enabled? ? :scram : :mongodb_cr
115
- user = Auth::User.new({ :auth_mech => default_mechanism }.merge(options))
186
+ user = Auth::User.new(Options::Redacted.new(:auth_mech => default_mechanism).merge(options))
116
187
  @authenticator = Auth.get(user)
117
188
  end
118
189
  end
119
190
 
120
- def write(messages, buffer = '')
191
+ def write(messages, buffer = ''.force_encoding(BSON::BINARY))
121
192
  start_size = 0
122
193
  messages.each do |message|
123
194
  message.serialize(buffer, max_bson_object_size)
@@ -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.
@@ -54,6 +54,18 @@ module Mongo
54
54
  queue.dequeue
55
55
  end
56
56
 
57
+ # Disconnect the connection pool.
58
+ #
59
+ # @example Disconnect the connection pool.
60
+ # pool.disconnect!
61
+ #
62
+ # @return [ true ] true.
63
+ #
64
+ # @since 2.1.0
65
+ def disconnect!
66
+ queue.disconnect!
67
+ end
68
+
57
69
  # Create the new connection pool.
58
70
  #
59
71
  # @example Create the new connection pool.
@@ -28,7 +28,8 @@ module Mongo
28
28
  :list_collections => 3,
29
29
  :list_indexes => 3,
30
30
  :scram_sha_1 => 3,
31
- :write_command => 2
31
+ :write_command => 2,
32
+ :users_info => 2
32
33
  }.freeze
33
34
 
34
35
  # The wire protocol versions that this version of the driver supports.
@@ -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
@@ -124,10 +129,20 @@ module Mongo
124
129
  # @since 2.0.0
125
130
  TAGS = 'tags'.freeze
126
131
 
132
+ # Constant for reading electionID info from config.
133
+ #
134
+ # @since 2.1.0
135
+ ELECTION_ID = 'electionId'.freeze
136
+
137
+ # Constant for reading localTime info from config.
138
+ #
139
+ # @since 2.1.0
140
+ LOCAL_TIME = 'localTime'.freeze
141
+
127
142
  # Fields to exclude when comparing two descriptions.
128
143
  #
129
144
  # @since 2.0.6
130
- EXCLUDE_FOR_COMPARISON = [ 'localTime' ]
145
+ EXCLUDE_FOR_COMPARISON = [ LOCAL_TIME, ELECTION_ID ]
131
146
 
132
147
  # @return [ Address ] address The server's address.
133
148
  attr_reader :address
@@ -292,6 +307,18 @@ module Mongo
292
307
  config[MIN_WIRE_VERSION] || LEGACY_WIRE_VERSION
293
308
  end
294
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
+
295
322
  # Get the tags configured for the server.
296
323
  #
297
324
  # @example Get the tags.
@@ -304,6 +331,18 @@ module Mongo
304
331
  config[TAGS] || {}
305
332
  end
306
333
 
334
+ # Get the electionId from the config.
335
+ #
336
+ # @example Get the electionId.
337
+ # description.election_id
338
+ #
339
+ # @return [ BSON::ObjectId ] The election id.
340
+ #
341
+ # @since 2.1.0
342
+ def election_id
343
+ config[ELECTION_ID]
344
+ end
345
+
307
346
  # Is the server a mongos?
308
347
  #
309
348
  # @example Is the server a mongos?
@@ -489,6 +528,18 @@ module Mongo
489
528
  !(standalone? || mongos?)
490
529
  end
491
530
 
531
+ # Check if there is a mismatch between the address host and the me field.
532
+ #
533
+ # @example Check if there is a mismatch.
534
+ # description.me_mismatch?
535
+ #
536
+ # @return [ true, false ] If there is a mismatch between the me field and the address host.
537
+ #
538
+ # @since 2.0.6
539
+ def me_mismatch?
540
+ !!(address.to_s != me if me)
541
+ end
542
+
492
543
  # Check equality of two descriptions.
493
544
  #
494
545
  # @example Check description equality.
@@ -36,7 +36,7 @@ module Mongo
36
36
  def connect!
37
37
  unless socket
38
38
  @socket = address.socket(timeout, ssl_options)
39
- @socket.connect!
39
+ socket.connect!
40
40
  end
41
41
  true
42
42
  end
@@ -60,11 +60,35 @@ module Mongo
60
60
  true
61
61
  end
62
62
 
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
+
63
82
  # Initialize a new socket connection from the client to the server.
64
83
  #
84
+ # @api private
85
+ #
65
86
  # @example Create the connection.
66
87
  # Connection.new(address)
67
88
  #
89
+ # @note Connection must never be directly instantiated outside of a
90
+ # Monitor.
91
+ #
68
92
  # @param [ Mongo::Address ] address The address the connection is for.
69
93
  # @param [ Hash ] options The connection options.
70
94
  #
@@ -72,7 +96,7 @@ module Mongo
72
96
  def initialize(address, options = {})
73
97
  @address = address
74
98
  @options = options.freeze
75
- @ssl_options = options.reject { |k, v| !k.to_s.start_with?('ssl') }
99
+ @ssl_options = options.reject { |k, v| !k.to_s.start_with?(SSL) }
76
100
  @socket = nil
77
101
  @pid = Process.pid
78
102
  end
@@ -91,9 +91,13 @@ module Mongo
91
91
 
92
92
  # Create the new server monitor.
93
93
  #
94
+ # @api private
95
+ #
94
96
  # @example Create the server monitor.
95
97
  # Mongo::Server::Monitor.new(address, listeners)
96
98
  #
99
+ # @note Monitor must never be directly instantiated outside of a Server.
100
+ #
97
101
  # @param [ Address ] address The address to monitor.
98
102
  # @param [ Event::Listeners ] listeners The event listeners.
99
103
  # @param [ Hash ] options The options.
@@ -112,7 +116,7 @@ module Mongo
112
116
  # server.
113
117
  #
114
118
  # @example Run the monitor.
115
- # monito.run
119
+ # monitor.run
116
120
  #
117
121
  # @return [ Thread ] The thread the monitor runs on.
118
122
  #
@@ -136,7 +140,19 @@ module Mongo
136
140
  #
137
141
  # @since 2.0.0
138
142
  def stop!
139
- @thread.kill && @thread.stop?
143
+ connection.disconnect! && @thread.kill && @thread.stop?
144
+ end
145
+
146
+ # Restarts the server monitor unless the current thread is alive.
147
+ #
148
+ # @example Restart the monitor.
149
+ # monitor.restart!
150
+ #
151
+ # @return [ Thread ] The thread the monitor runs on.
152
+ #
153
+ # @since 2.1.0
154
+ def restart!
155
+ @thread.alive? ? @thread : run!
140
156
  end
141
157
 
142
158
  private
@@ -157,7 +173,7 @@ module Mongo
157
173
  result = connection.dispatch([ ISMASTER ]).documents[0]
158
174
  return result, calculate_average_round_trip_time(start)
159
175
  rescue Exception => e
160
- log_debug([ e.message ])
176
+ log_debug(e.message)
161
177
  return {}, calculate_average_round_trip_time(start)
162
178
  end
163
179
  end