mongo 2.1.0.beta → 2.1.0.rc0

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 (253) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/Rakefile +2 -2
  5. data/lib/mongo.rb +2 -3
  6. data/lib/mongo/address.rb +7 -5
  7. data/lib/mongo/address/unix.rb +2 -2
  8. data/lib/mongo/auth/ldap/conversation.rb +6 -2
  9. data/lib/mongo/auth/scram/conversation.rb +8 -2
  10. data/lib/mongo/auth/user/view.rb +21 -0
  11. data/lib/mongo/bulk_write.rb +155 -23
  12. data/lib/mongo/bulk_write/combineable.rb +51 -0
  13. data/lib/mongo/bulk_write/ordered_combiner.rb +55 -0
  14. data/lib/mongo/bulk_write/result.rb +61 -8
  15. data/lib/mongo/bulk_write/result_combiner.rb +117 -0
  16. data/lib/mongo/bulk_write/transformable.rb +117 -0
  17. data/lib/mongo/bulk_write/unordered_combiner.rb +52 -0
  18. data/lib/mongo/bulk_write/validatable.rb +62 -0
  19. data/lib/mongo/client.rb +7 -3
  20. data/lib/mongo/cluster.rb +3 -3
  21. data/lib/mongo/cluster/topology/replica_set.rb +8 -6
  22. data/lib/mongo/cluster/topology/unknown.rb +5 -2
  23. data/lib/mongo/collection.rb +75 -4
  24. data/lib/mongo/collection/view.rb +1 -2
  25. data/lib/mongo/collection/view/aggregation.rb +13 -8
  26. data/lib/mongo/collection/view/immutable.rb +6 -6
  27. data/lib/mongo/collection/view/iterable.rb +13 -4
  28. data/lib/mongo/collection/view/map_reduce.rb +22 -17
  29. data/lib/mongo/collection/view/readable.rb +121 -70
  30. data/lib/mongo/cursor.rb +5 -1
  31. data/lib/mongo/database.rb +3 -3
  32. data/lib/mongo/database/view.rb +1 -1
  33. data/lib/mongo/error.rb +7 -0
  34. data/lib/mongo/{bulk_write/unordered_bulk_write.rb → error/closed_stream.rb} +12 -21
  35. data/lib/mongo/{bulk_write/ordered_bulk_write.rb → error/extra_file_chunk.rb} +13 -27
  36. data/lib/mongo/error/file_not_found.rb +37 -0
  37. data/lib/mongo/error/invalid_file.rb +2 -2
  38. data/lib/mongo/error/invalid_file_revision.rb +37 -0
  39. data/lib/mongo/error/invalid_uri.rb +5 -4
  40. data/lib/mongo/error/missing_file_chunk.rb +38 -0
  41. data/lib/mongo/error/operation_failure.rb +1 -1
  42. data/lib/mongo/error/unchangeable_collection_option.rb +38 -0
  43. data/lib/mongo/error/unexpected_chunk_length.rb +39 -0
  44. data/lib/mongo/grid.rb +2 -1
  45. data/lib/mongo/grid/file.rb +12 -9
  46. data/lib/mongo/grid/file/chunk.rb +6 -6
  47. data/lib/mongo/grid/file/{metadata.rb → info.rb} +41 -39
  48. data/lib/mongo/grid/fs_bucket.rb +441 -0
  49. data/lib/mongo/grid/stream.rb +64 -0
  50. data/lib/mongo/grid/stream/read.rb +208 -0
  51. data/lib/mongo/grid/stream/write.rb +187 -0
  52. data/lib/mongo/index/view.rb +1 -1
  53. data/lib/mongo/loggable.rb +34 -57
  54. data/lib/mongo/logger.rb +16 -78
  55. data/lib/mongo/monitoring.rb +1 -5
  56. data/lib/mongo/monitoring/command_log_subscriber.rb +35 -17
  57. data/lib/mongo/monitoring/event/command_succeeded.rb +20 -1
  58. data/lib/mongo/monitoring/publishable.rb +22 -12
  59. data/lib/mongo/operation.rb +3 -6
  60. data/lib/mongo/operation/commands.rb +24 -0
  61. data/lib/mongo/operation/{aggregate.rb → commands/aggregate.rb} +3 -41
  62. data/lib/mongo/operation/{aggregate → commands/aggregate}/result.rb +0 -0
  63. data/lib/mongo/operation/commands/collections_info.rb +66 -0
  64. data/lib/mongo/operation/{command.rb → commands/command.rb} +2 -18
  65. data/lib/mongo/operation/commands/indexes.rb +70 -0
  66. data/lib/mongo/operation/commands/list_collections.rb +54 -0
  67. data/lib/mongo/operation/commands/list_collections/result.rb +112 -0
  68. data/lib/mongo/operation/commands/list_indexes.rb +56 -0
  69. data/lib/mongo/operation/commands/list_indexes/result.rb +115 -0
  70. data/lib/mongo/operation/{map_reduce.rb → commands/map_reduce.rb} +3 -41
  71. data/lib/mongo/operation/{map_reduce → commands/map_reduce}/result.rb +0 -0
  72. data/lib/mongo/operation/{parallel_scan.rb → commands/parallel_scan.rb} +3 -23
  73. data/lib/mongo/operation/{parallel_scan → commands/parallel_scan}/result.rb +0 -0
  74. data/lib/mongo/operation/commands/user_query.rb +69 -0
  75. data/lib/mongo/operation/commands/users_info.rb +53 -0
  76. data/lib/mongo/operation/commands/users_info/result.rb +36 -0
  77. data/lib/mongo/operation/executable.rb +4 -68
  78. data/lib/mongo/operation/kill_cursors.rb +3 -3
  79. data/lib/mongo/operation/read.rb +0 -4
  80. data/lib/mongo/operation/read/get_more.rb +2 -22
  81. data/lib/mongo/operation/read/query.rb +2 -21
  82. data/lib/mongo/operation/{read_preferrable.rb → read_preference.rb} +3 -2
  83. data/lib/mongo/operation/specifiable.rb +24 -0
  84. data/lib/mongo/operation/write.rb +2 -0
  85. data/lib/mongo/operation/write/bulk.rb +6 -3
  86. data/lib/mongo/operation/write/bulk/bulkable.rb +82 -0
  87. data/lib/mongo/operation/write/bulk/delete.rb +71 -0
  88. data/lib/mongo/operation/write/bulk/delete/result.rb +74 -0
  89. data/lib/mongo/operation/write/bulk/insert.rb +96 -0
  90. data/lib/mongo/operation/write/bulk/insert/result.rb +129 -0
  91. data/lib/mongo/operation/write/bulk/legacy_mergable.rb +87 -0
  92. data/lib/mongo/operation/write/bulk/mergable.rb +71 -0
  93. data/lib/mongo/operation/write/bulk/update.rb +81 -0
  94. data/lib/mongo/operation/write/bulk/update/result.rb +174 -0
  95. data/lib/mongo/operation/write/command/create_index.rb +0 -1
  96. data/lib/mongo/operation/write/command/create_user.rb +0 -1
  97. data/lib/mongo/operation/write/command/delete.rb +0 -1
  98. data/lib/mongo/operation/write/command/drop_index.rb +0 -1
  99. data/lib/mongo/operation/write/command/insert.rb +0 -1
  100. data/lib/mongo/operation/write/command/remove_user.rb +0 -1
  101. data/lib/mongo/operation/write/command/update.rb +0 -1
  102. data/lib/mongo/operation/write/command/update_user.rb +0 -1
  103. data/lib/mongo/operation/write/command/writable.rb +13 -18
  104. data/lib/mongo/operation/write/create_index.rb +4 -27
  105. data/lib/mongo/operation/write/create_user.rb +4 -30
  106. data/lib/mongo/operation/write/delete.rb +5 -28
  107. data/lib/mongo/operation/write/drop_index.rb +3 -3
  108. data/lib/mongo/operation/write/gle.rb +48 -0
  109. data/lib/mongo/operation/write/idable.rb +5 -0
  110. data/lib/mongo/operation/write/insert.rb +2 -24
  111. data/lib/mongo/operation/write/remove_user.rb +4 -27
  112. data/lib/mongo/operation/write/update.rb +4 -32
  113. data/lib/mongo/operation/write/update_user.rb +4 -30
  114. data/lib/mongo/operation/write/write_command_enabled.rb +53 -0
  115. data/lib/mongo/options/mapper.rb +4 -2
  116. data/lib/mongo/protocol/delete.rb +68 -3
  117. data/lib/mongo/protocol/get_more.rb +54 -2
  118. data/lib/mongo/protocol/insert.rb +59 -1
  119. data/lib/mongo/protocol/kill_cursors.rb +53 -4
  120. data/lib/mongo/protocol/message.rb +12 -12
  121. data/lib/mongo/protocol/query.rb +139 -65
  122. data/lib/mongo/protocol/reply.rb +69 -1
  123. data/lib/mongo/protocol/update.rb +70 -1
  124. data/lib/mongo/server/connection.rb +11 -3
  125. data/lib/mongo/server/description.rb +29 -0
  126. data/lib/mongo/server/description/features.rb +2 -1
  127. data/lib/mongo/server/monitor.rb +2 -2
  128. data/lib/mongo/server_selector.rb +14 -10
  129. data/lib/mongo/server_selector/selectable.rb +24 -22
  130. data/lib/mongo/socket.rb +6 -3
  131. data/lib/mongo/socket/tcp.rb +2 -2
  132. data/lib/mongo/socket/unix.rb +5 -8
  133. data/lib/mongo/uri.rb +243 -139
  134. data/lib/mongo/version.rb +1 -1
  135. data/spec/mongo/address/unix_spec.rb +1 -1
  136. data/spec/mongo/address_spec.rb +25 -0
  137. data/spec/mongo/auth/ldap/conversation_spec.rb +43 -0
  138. data/spec/mongo/auth/user/view_spec.rb +26 -1
  139. data/spec/mongo/bulk_write/ordered_combiner_spec.rb +271 -0
  140. data/spec/mongo/bulk_write/unordered_combiner_spec.rb +239 -0
  141. data/spec/mongo/bulk_write_spec.rb +332 -166
  142. data/spec/mongo/client_spec.rb +25 -0
  143. data/spec/mongo/cluster/topology/replica_set_spec.rb +2 -0
  144. data/spec/mongo/collection/view/aggregation_spec.rb +65 -0
  145. data/spec/mongo/collection/view/immutable_spec.rb +103 -0
  146. data/spec/mongo/collection/view/map_reduce_spec.rb +98 -3
  147. data/spec/mongo/collection/view/readable_spec.rb +17 -30
  148. data/spec/mongo/collection/view_spec.rb +233 -7
  149. data/spec/mongo/collection_spec.rb +360 -18
  150. data/spec/mongo/command_monitoring_spec.rb +51 -0
  151. data/spec/mongo/connection_string_spec.rb +137 -0
  152. data/spec/mongo/database_spec.rb +27 -11
  153. data/spec/mongo/grid/file/chunk_spec.rb +5 -5
  154. data/spec/mongo/grid/file/{metadata_spec.rb → info_spec.rb} +29 -17
  155. data/spec/mongo/grid/file_spec.rb +8 -8
  156. data/spec/mongo/grid/fs_bucket_spec.rb +1020 -0
  157. data/spec/mongo/grid/stream/read_spec.rb +275 -0
  158. data/spec/mongo/grid/stream/write_spec.rb +440 -0
  159. data/spec/mongo/grid/stream_spec.rb +48 -0
  160. data/spec/mongo/gridfs_spec.rb +50 -0
  161. data/spec/mongo/logger_spec.rb +0 -40
  162. data/spec/mongo/monitoring/command_log_subscriber_spec.rb +76 -0
  163. data/spec/mongo/operation/{aggregate_spec.rb → commands/aggregate_spec.rb} +0 -42
  164. data/spec/mongo/operation/{read → commands}/collections_info_spec.rb +1 -1
  165. data/spec/mongo/operation/{command_spec.rb → commands/command_spec.rb} +0 -0
  166. data/spec/mongo/operation/{read → commands}/indexes_spec.rb +1 -1
  167. data/spec/mongo/operation/{map_reduce_spec.rb → commands/map_reduce_spec.rb} +0 -18
  168. data/spec/mongo/operation/kill_cursors_spec.rb +1 -1
  169. data/spec/mongo/operation/{read_preferrable_spec.rb → read_preference_spec.rb} +11 -11
  170. data/spec/mongo/operation/write/bulk/{bulk_delete_spec.rb → delete_spec.rb} +1 -12
  171. data/spec/mongo/operation/write/bulk/{bulk_insert_spec.rb → insert_spec.rb} +1 -12
  172. data/spec/mongo/operation/write/bulk/{bulk_update_spec.rb → update_spec.rb} +1 -12
  173. data/spec/mongo/operation/write/insert_spec.rb +0 -11
  174. data/spec/mongo/protocol/kill_cursors_spec.rb +5 -3
  175. data/spec/mongo/server/description_spec.rb +42 -0
  176. data/spec/mongo/server/monitor_spec.rb +21 -0
  177. data/spec/mongo/server_discovery_and_monitoring_spec.rb +1 -0
  178. data/spec/mongo/server_selection_spec.rb +3 -3
  179. data/spec/mongo/server_selector/nearest_spec.rb +34 -27
  180. data/spec/mongo/server_selector/primary_preferred_spec.rb +31 -30
  181. data/spec/mongo/server_selector/primary_spec.rb +14 -13
  182. data/spec/mongo/server_selector/secondary_preferred_spec.rb +27 -26
  183. data/spec/mongo/server_selector/secondary_spec.rb +23 -22
  184. data/spec/mongo/server_selector_spec.rb +87 -24
  185. data/spec/mongo/socket/unix_spec.rb +52 -0
  186. data/spec/mongo/uri_spec.rb +251 -39
  187. data/spec/spec_helper.rb +11 -4
  188. data/spec/support/authorization.rb +4 -5
  189. data/spec/support/command_monitoring.rb +365 -0
  190. data/spec/support/command_monitoring/bulkWrite.yml +73 -0
  191. data/spec/support/command_monitoring/command.yml +42 -0
  192. data/spec/support/command_monitoring/deleteMany.yml +55 -0
  193. data/spec/support/command_monitoring/deleteOne.yml +55 -0
  194. data/spec/support/command_monitoring/find.yml +219 -0
  195. data/spec/support/command_monitoring/insertMany.yml +81 -0
  196. data/spec/support/command_monitoring/insertOne.yml +51 -0
  197. data/spec/support/command_monitoring/updateMany.yml +67 -0
  198. data/spec/support/command_monitoring/updateOne.yml +95 -0
  199. data/spec/support/connection_string.rb +228 -0
  200. data/spec/support/connection_string_tests/invalid-uris.yml +193 -0
  201. data/spec/support/connection_string_tests/valid-auth.yml +256 -0
  202. data/spec/support/connection_string_tests/valid-host_identifiers.yml +121 -0
  203. data/spec/support/connection_string_tests/valid-options.yml +30 -0
  204. data/spec/support/connection_string_tests/valid-unix_socket-absolute.yml +197 -0
  205. data/spec/support/connection_string_tests/valid-unix_socket-relative.yml +213 -0
  206. data/spec/support/connection_string_tests/valid-warnings.yml +55 -0
  207. data/spec/support/crud.rb +3 -1
  208. data/spec/support/crud/read.rb +14 -10
  209. data/spec/support/crud/write.rb +36 -9
  210. data/spec/support/gridfs.rb +637 -0
  211. data/spec/support/gridfs_tests/delete.yml +157 -0
  212. data/spec/support/gridfs_tests/download.yml +210 -0
  213. data/spec/support/gridfs_tests/download_by_name.yml +113 -0
  214. data/spec/support/gridfs_tests/upload.yml +158 -0
  215. data/spec/support/sdam/rs/equal_electionids.yml +1 -2
  216. data/spec/support/sdam/rs/new_primary_new_electionid.yml +0 -3
  217. data/spec/support/sdam/rs/primary_mismatched_me.yml +37 -0
  218. data/spec/support/sdam/rs/primary_to_no_primary_mismatched_me.yml +75 -0
  219. data/spec/support/sdam/rs/secondary_mismatched_me.yml +37 -0
  220. data/spec/support/sdam/single/direct_connection_rsarbiter.yml +1 -1
  221. data/spec/support/sdam/single/direct_connection_rsprimary.yml +1 -1
  222. data/spec/support/sdam/single/direct_connection_rssecondary.yml +1 -1
  223. data/spec/support/sdam/single/direct_connection_slave.yml +1 -1
  224. data/spec/support/sdam/single/direct_connection_standalone.yml +1 -1
  225. data/spec/support/sdam/single/not_ok_response.yml +0 -1
  226. data/spec/support/server_discovery_and_monitoring.rb +3 -1
  227. data/spec/support/server_selection.rb +3 -1
  228. data/spec/support/shared/bulk_write.rb +192 -0
  229. data/spec/support/shared/server_selector.rb +21 -12
  230. metadata +147 -57
  231. metadata.gz.sig +0 -0
  232. data/lib/mongo/bulk_write/bulk_writable.rb +0 -252
  233. data/lib/mongo/bulk_write/deletable.rb +0 -57
  234. data/lib/mongo/bulk_write/insertable.rb +0 -49
  235. data/lib/mongo/bulk_write/replacable.rb +0 -58
  236. data/lib/mongo/bulk_write/updatable.rb +0 -69
  237. data/lib/mongo/grid/fs.rb +0 -146
  238. data/lib/mongo/operation/list_collections/result.rb +0 -114
  239. data/lib/mongo/operation/list_indexes/result.rb +0 -118
  240. data/lib/mongo/operation/read/collections_info.rb +0 -68
  241. data/lib/mongo/operation/read/indexes.rb +0 -69
  242. data/lib/mongo/operation/read/list_collections.rb +0 -76
  243. data/lib/mongo/operation/read/list_indexes.rb +0 -78
  244. data/lib/mongo/operation/write/bulk/bulk_delete.rb +0 -145
  245. data/lib/mongo/operation/write/bulk/bulk_delete/result.rb +0 -75
  246. data/lib/mongo/operation/write/bulk/bulk_insert.rb +0 -132
  247. data/lib/mongo/operation/write/bulk/bulk_insert/result.rb +0 -130
  248. data/lib/mongo/operation/write/bulk/bulk_mergable.rb +0 -67
  249. data/lib/mongo/operation/write/bulk/bulk_update.rb +0 -154
  250. data/lib/mongo/operation/write/bulk/bulk_update/result.rb +0 -174
  251. data/lib/mongo/operation/write/bulk/legacy_bulk_mergable.rb +0 -83
  252. data/spec/mongo/grid/fs_spec.rb +0 -160
  253. data/spec/mongo/loggable_spec.rb +0 -63
@@ -114,6 +114,17 @@ module Mongo
114
114
  fields.map { |field| instance_variable_get(field[:name]) }.hash
115
115
  end
116
116
 
117
+ # Generates a request id for a message
118
+ #
119
+ # @return [Fixnum] a request id used for sending a message to the
120
+ # server. The server will put this id in the response_to field of
121
+ # a reply.
122
+ def set_request_id
123
+ @@id_lock.synchronize do
124
+ @request_id = @@request_id += 1
125
+ end
126
+ end
127
+
117
128
  private
118
129
 
119
130
  @@request_id = 0
@@ -158,17 +169,6 @@ module Mongo
158
169
  end
159
170
  end
160
171
 
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
172
  # Serializes the header of the message consisting of 4 32bit integers
173
173
  #
174
174
  # The integers represent a message length placeholder (calculation of
@@ -181,7 +181,7 @@ module Mongo
181
181
  # @param buffer [String] Buffer to receive the header
182
182
  # @return [String] Serialized header
183
183
  def serialize_header(buffer)
184
- set_request_id
184
+ set_request_id unless @request_id
185
185
  Header.serialize(buffer, [0, request_id, 0, op_code])
186
186
  end
187
187
 
@@ -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,130 @@ 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
+ }
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
+ }
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
+ }
192
+
193
+ # @return [ String ] collection The name of the collection.
194
+ attr_reader :collection
195
+
196
+ # @return [ BSON::Document, Hash ] filter The query filter or command.
197
+ attr_reader :filter
198
+
199
+ # @return [ BSON::Document, Hash ] options The options.
200
+ attr_reader :options
201
+
202
+ # @return [ Array<Symbol> ] flags The flags.
203
+ attr_reader :flags
204
+
205
+ # Instantiate the upconverter.
206
+ #
207
+ # @example Instantiate the upconverter.
208
+ # Upconverter.new('users', { name: 'test' }, { skip: 10 })
209
+ #
210
+ # @param [ String ] collection The name of the collection.
211
+ # @param [ BSON::Document, Hash ] filter The filter or command.
212
+ # @param [ BSON::Document, Hash ] options The options.
213
+ # @param [ Array<Symbol> ] flags The flags.
214
+ #
215
+ # @since 2.1.0
216
+ def initialize(collection, filter, options, flags)
217
+ @collection = collection
218
+ @filter = filter
219
+ @options = options
220
+ @flags = flags
221
+ end
222
+
223
+ # Get the upconverted command.
224
+ #
225
+ # @example Get the command.
226
+ # upconverter.command
227
+ #
228
+ # @return [ BSON::Document ] The upconverted command.
229
+ #
230
+ # @since 2.1.0
231
+ def command
232
+ command? ? op_command : find_command
233
+ end
234
+
235
+ # Get the name of the command. If the collection is $cmd then it's the
236
+ # first key in the filter, otherwise it's a find.
237
+ #
238
+ # @example Get the command name.
239
+ # upconverter.command_name
240
+ #
241
+ # @return [ String, Symbol ] The command name.
242
+ #
243
+ # @since 2.1.0
244
+ def command_name
245
+ command? ? filter.keys.first : 'find'
246
+ end
247
+
248
+ private
249
+
250
+ def command?
251
+ collection == Database::COMMAND
252
+ end
253
+
254
+ def op_command
255
+ BSON::Document.new(filter)
256
+ end
257
+
258
+ def find_command
259
+ document = BSON::Document.new
260
+ document[:find] = collection
261
+ document[:filter] = filter[:$query] ? filter[:$query] : filter
262
+ OPTION_MAPPINGS.each do |legacy, option|
263
+ document[option] = options[legacy] unless options[legacy].nil?
264
+ end
265
+ SPECIAL_FIELD_MAPPINGS.each do |special, normal|
266
+ document[normal] = filter[special] unless filter[special].nil?
267
+ end
268
+ FLAG_MAPPINGS.each do |legacy, flag|
269
+ document[flag] = true if flags.include?(legacy)
270
+ end
271
+ document
272
+ end
273
+ end
200
274
  end
201
275
  end
202
276
  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,70 @@ 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
+ # @return [ Array<BSON::Document> ] documents The documents.
105
+ attr_reader :documents
106
+
107
+ # @return [ Integer ] cursor_id The cursor id.
108
+ attr_reader :cursor_id
109
+
110
+ # @return [ Integer ] starting_from The starting point in the cursor.
111
+ attr_reader :starting_from
112
+
113
+ # Initialize the new upconverter.
114
+ #
115
+ # @example Create the upconverter.
116
+ # Upconverter.new(docs, 1, 3)
117
+ #
118
+ # @param [ Array<BSON::Document> ] documents The documents.
119
+ # @param [ Integer ] cursor_id The cursor id.
120
+ # @param [ Integer ] starting_from The starting position.
121
+ #
122
+ # @since 2.1.0
123
+ def initialize(documents, cursor_id, starting_from)
124
+ @documents = documents
125
+ @cursor_id = cursor_id
126
+ @starting_from = starting_from
127
+ end
128
+
129
+ # Get the upconverted command.
130
+ #
131
+ # @example Get the command.
132
+ # upconverter.command
133
+ #
134
+ # @return [ BSON::Document ] The command.
135
+ #
136
+ # @since 2.1.0
137
+ def command
138
+ command? ? op_command : find_command
139
+ end
140
+
141
+ private
142
+
143
+ def batch_field
144
+ starting_from > 0 ? :nextBatch : :firstBatch
145
+ end
146
+
147
+ def command?
148
+ !documents.empty? && documents.first.key?('ok')
149
+ end
150
+
151
+ def find_command
152
+ BSON::Document.new(
153
+ ok: 1,
154
+ cursor: BSON::Document.new(id: cursor_id, batch_field => documents)
155
+ )
156
+ end
157
+
158
+ def op_command
159
+ documents.first
160
+ end
161
+ end
94
162
  end
95
163
  end
96
164
  end
@@ -53,10 +53,12 @@ module Mongo
53
53
  # Supported flags: +:upsert+, +:multi_update+
54
54
  def initialize(database, collection, selector, update, options = {})
55
55
  @database = database
56
+ @collection = collection
56
57
  @namespace = "#{database}.#{collection}"
57
58
  @selector = selector
58
59
  @update = update
59
60
  @flags = options[:flags] || []
61
+ @upconverter = Upconverter.new(collection, selector, update, flags)
60
62
  end
61
63
 
62
64
  # Return the event payload for monitoring.
@@ -71,13 +73,15 @@ module Mongo
71
73
  {
72
74
  command_name: 'update',
73
75
  database_name: @database,
74
- command: { filter: selector, update: update },
76
+ command: upconverter.command,
75
77
  request_id: request_id
76
78
  }
77
79
  end
78
80
 
79
81
  private
80
82
 
83
+ attr_reader :upconverter
84
+
81
85
  # The operation code required to specify an Update message.
82
86
  # @return [Fixnum] the operation code.
83
87
  def op_code
@@ -105,6 +109,71 @@ module Mongo
105
109
  # @!attribute
106
110
  # @return [Hash] The update for this Delete message.
107
111
  field :update, Document
112
+
113
+ # Converts legacy update messages to the appropriare OP_COMMAND style
114
+ # message.
115
+ #
116
+ # @since 2.1.0
117
+ class Upconverter
118
+
119
+ # @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
108
177
  end
109
178
  end
110
179
  end