mongo 2.6.0 → 2.6.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8c5dc91c26dc7d6d0a6c9f50e39c6d7b53130d08e75611d9f2a81162ed5a53e2
4
- data.tar.gz: ceb6c12c3e4a7e5b9552fa8501b8faa6835ce110a6f32e6df8e8c65f53599b76
3
+ metadata.gz: d8e500892649b1d8d1817ec229c1d56d97837e252452654af04e995d1416082a
4
+ data.tar.gz: 5fa8c7ca6caa84c0c81ed9f8ab3cd6566f579fc10ac28f510628f2de790040c7
5
5
  SHA512:
6
- metadata.gz: 94c8eeb0c0afa60bd77ad0fc8139bfa818e9b3d1ac1d7e1656d92cf91e50d0481d3e9bb275bd3f5143b540036e5acc314e573e79c5891ad85003b05eadfc695e
7
- data.tar.gz: 94e7a7f089b67ec901c8182f96d9a020ba67143b5e0823d3c39f0fa7dfa8cc7e0132a40df65a64c2c308b2d255316dbac4e20180b70bbeaa5680b3ef55e6f70e
6
+ metadata.gz: 725de14593b44d0bf8b370f53a5e18a8f5d033efddd2e05096ec561b69f51b01b70394d3c8ebab1e89dbb7ecbb7784dbb161376d1194130ae6d016afd39344ae
7
+ data.tar.gz: 989ee85302acac376637d777e1c83cff4e7fa5d932fc62d489b3192d0b7336875fe831a0742d9953892108d2cb86c5b825f84d73a1779c0149fef2ffbb04aa05
Binary file
data.tar.gz.sig CHANGED
@@ -1 +1,3 @@
1
- ���.,�1��[+��>4��v�1��8�9+ *�7{R�'���E�R �@�ج�����t$����52eh��?��jG!��E��:�x��47Dr]��&�=Ϗl›�-�m:e�� ��Y��+����$���S l%@|L���BB�/��1�3^Ε��a'�N'azn ۝�@����Oy[��ԫ c�,��&<��2'����3] цY=�����ӌa6 �e��H`����Np4�����q� ו��Y9��
1
+ ���6Ș�����>in{��M�(����Jʐ4���E�tm}WBA8�������y��z���W�S��^<~6���&%q�`��M��(����<�7��Kݰxj�����d�\����f���f�f��EML�|3tKDЂ9�J<3-�,���<�Q��!Eg>L>��8Yf95��֙<i�lgu������mx[=�f
2
+ ��;�|klr�؁�n
3
+ v�a����gn���0�O�I�S���r�PowVo`�
@@ -42,3 +42,4 @@ require 'mongo/socket'
42
42
  require 'mongo/uri'
43
43
  require 'mongo/version'
44
44
  require 'mongo/write_concern'
45
+ require 'mongo/lint'
@@ -142,7 +142,7 @@ module Mongo
142
142
  # @param [ Float ] socket_timeout The socket timeout.
143
143
  # @param [ Hash ] ssl_options SSL options.
144
144
  #
145
- # @return [ Pool::Socket::SSL, Pool::Socket::TCP, Pool::Socket::Unix ] The socket.
145
+ # @return [ Mongo::Socket::SSL, Mongo::Socket::TCP, Mongo::Socket::Unix ] The socket.
146
146
  #
147
147
  # @since 2.0.0
148
148
  def socket(socket_timeout, ssl_options = {})
@@ -80,7 +80,7 @@ module Mongo
80
80
  # @param [ Float ] socket_timeout The socket timeout.
81
81
  # @param [ Hash ] ssl_options SSL options.
82
82
  #
83
- # @return [ Pool::Socket::SSL, Pool::Socket::TCP ] The socket.
83
+ # @return [ Mongo::Socket::SSL, Mongo::Socket::TCP ] The socket.
84
84
  #
85
85
  # @since 2.0.0
86
86
  def socket(socket_timeout, ssl_options = {})
@@ -96,7 +96,7 @@ module Mongo
96
96
  # @param [ Float ] socket_timeout The socket timeout.
97
97
  # @param [ Hash ] ssl_options SSL options.
98
98
  #
99
- # @return [ Pool::Socket::SSL, Pool::Socket::TCP ] The socket.
99
+ # @return [ Mongo::Socket::SSL, Mongo::Socket::TCP ] The socket.
100
100
  #
101
101
  # @since 2.0.0
102
102
  def socket(socket_timeout, ssl_options = {})
@@ -65,7 +65,7 @@ module Mongo
65
65
  # @param [ Float ] socket_timeout The socket timeout.
66
66
  # @param [ Hash ] ssl_options SSL options - ignored.
67
67
  #
68
- # @return [ Pool::Socket::Unix ] The socket.
68
+ # @return [ Mongo::Socket::Unix ] The socket.
69
69
  #
70
70
  # @since 2.0.0
71
71
  def socket(socket_timeout, ssl_options = {})
@@ -193,7 +193,7 @@ module Mongo
193
193
  # supports 'zlib'.
194
194
  # @option options [ Hash ] :read The read preference options. The hash
195
195
  # may have the following items:
196
- # - *:read* -- read preference specified as a symbol; valid values are
196
+ # - *:mode* -- read preference specified as a symbol; valid values are
197
197
  # *:primary*, *:primary_preferred*, *:secondary*, *:secondary_preferred*
198
198
  # and *:nearest*.
199
199
  # - *:tag_sets* -- an array of hashes.
@@ -219,18 +219,18 @@ module Mongo
219
219
  # @option options [ OpenSSL::PKey ] :ssl_key_object The private key used to identify the
220
220
  # connection against MongoDB
221
221
  # @option options [ String ] :ssl_key_pass_phrase A passphrase for the private key.
222
- # @option options [ true, false ] :ssl_verify Whether or not to do peer certification
222
+ # @option options [ true, false ] :ssl_verify Whether to do peer certificate
223
223
  # validation.
224
- # @option options [ String ] :ssl_ca_cert The file containing a set of concatenated
225
- # certification authority certifications used to validate certs passed from the
224
+ # @option options [ String ] :ssl_ca_cert The file containing concatenated
225
+ # certificate authority certificates used to validate certs passed from the
226
226
  # other end of the connection. One of :ssl_ca_cert, :ssl_ca_cert_string or
227
227
  # :ssl_ca_cert_object (in order of priority) is required for :ssl_verify.
228
- # @option options [ String ] :ssl_ca_cert_string A string containing a set of concatenated
229
- # certification authority certifications used to validate certs passed from the
228
+ # @option options [ String ] :ssl_ca_cert_string A string containing concatenated
229
+ # certificate authority certificates used to validate certs passed from the
230
230
  # other end of the connection. One of :ssl_ca_cert, :ssl_ca_cert_string or
231
231
  # :ssl_ca_cert_object (in order of priority) is required for :ssl_verify.
232
232
  # @option options [ Array<OpenSSL::X509::Certificate> ] :ssl_ca_cert_object An array of
233
- # OpenSSL::X509::Certificate representing the certification authority certifications used
233
+ # OpenSSL::X509::Certificate representing the certificate authority certificates used
234
234
  # to validate certs passed from the other end of the connection. One of :ssl_ca_cert,
235
235
  # :ssl_ca_cert_string or :ssl_ca_cert_object (in order of priority) is required for :ssl_verify.
236
236
  # @option options [ Float ] :socket_timeout The timeout, in seconds, to
@@ -261,6 +261,7 @@ module Mongo
261
261
  #
262
262
  # @since 2.0.0
263
263
  def initialize(addresses_or_uri, options = Options::Redacted.new)
264
+ Mongo::Lint.validate_underscore_read_preference(options[:read])
264
265
  if addresses_or_uri.is_a?(::String)
265
266
  create_from_uri(addresses_or_uri, validate_options!(options))
266
267
  else
@@ -301,6 +302,12 @@ module Mongo
301
302
  # client.read_preference
302
303
  #
303
304
  # @return [ BSON::Document ] The user-defined read preference.
305
+ # The document may have the following fields:
306
+ # - *:read* -- read preference specified as a symbol; valid values are
307
+ # *:primary*, *:primary_preferred*, *:secondary*, *:secondary_preferred*
308
+ # and *:nearest*.
309
+ # - *:tag_sets* -- an array of hashes.
310
+ # - *:local_threshold*.
304
311
  #
305
312
  # @since 2.0.0
306
313
  def read_preference
@@ -68,7 +68,15 @@ module Mongo
68
68
  end
69
69
 
70
70
  def read_pref_formatted
71
- @read_formatted ||= ServerSelector.get(read).to_mongos if read
71
+ @read_formatted ||= begin
72
+ if read
73
+ read_pref = ServerSelector.get(read).to_mongos
74
+ Mongo::Lint.validate_camel_case_read_preference(read_pref)
75
+ read_pref
76
+ else
77
+ nil
78
+ end
79
+ end
72
80
  end
73
81
 
74
82
  def special_filter
@@ -139,6 +139,7 @@ module Mongo
139
139
  cmd[:limit] = opts[:limit] if opts[:limit]
140
140
  cmd[:maxTimeMS] = opts[:max_time_ms] if opts[:max_time_ms]
141
141
  cmd[:readConcern] = collection.read_concern if collection.read_concern
142
+ Mongo::Lint.validate_underscore_read_preference(opts[:read])
142
143
  read_pref = opts[:read] || read_preference
143
144
  selector = ServerSelector.get(read_pref || server_selector)
144
145
  with_session(opts) do |session|
@@ -203,6 +204,7 @@ module Mongo
203
204
  cmd = { count: collection.name }
204
205
  cmd[:maxTimeMS] = opts[:max_time_ms] if opts[:max_time_ms]
205
206
  cmd[:readConcern] = collection.read_concern if collection.read_concern
207
+ Mongo::Lint.validate_underscore_read_preference(opts[:read])
206
208
  read_pref = opts[:read] || read_preference
207
209
  selector = ServerSelector.get(read_pref || server_selector)
208
210
  with_session(opts) do |session|
@@ -240,6 +242,7 @@ module Mongo
240
242
  :query => filter }
241
243
  cmd[:maxTimeMS] = opts[:max_time_ms] if opts[:max_time_ms]
242
244
  cmd[:readConcern] = collection.read_concern if collection.read_concern
245
+ Mongo::Lint.validate_underscore_read_preference(opts[:read])
243
246
  read_pref = opts[:read] || read_preference
244
247
  selector = ServerSelector.get(read_pref || server_selector)
245
248
  with_session(opts) do |session|
@@ -537,11 +540,13 @@ module Mongo
537
540
  end
538
541
 
539
542
  def read_preference
540
- if options[:session] && options[:session].in_transaction?
541
- options[:session].send(:txn_read_pref) || collection.client.read_preference
543
+ rp = if options[:session] && options[:session].in_transaction?
544
+ options[:session].txn_read_preference || collection.client.read_preference
542
545
  else
543
546
  @read_preference ||= (options[:read] || collection.read_preference)
544
547
  end
548
+ Mongo::Lint.validate_underscore_read_preference(rp)
549
+ rp
545
550
  end
546
551
 
547
552
  def server_selector
@@ -153,7 +153,8 @@ module Mongo
153
153
  #
154
154
  # @return [ Hash ] The result of the command execution.
155
155
  def command(operation, opts = {})
156
- txn_read_pref = opts[:session] && opts[:session].in_transaction? && opts[:session].txn_read_pref
156
+ txn_read_pref = opts[:session] && opts[:session].in_transaction? && opts[:session].txn_read_preference
157
+ Mongo::Lint.validate_underscore_read_preference(txn_read_pref)
157
158
  preference = ServerSelector.get(txn_read_pref || opts[:read] || ServerSelector::PRIMARY)
158
159
  server = preference.select_server(cluster)
159
160
 
@@ -151,6 +151,7 @@ require 'mongo/error/invalid_update_document'
151
151
  require 'mongo/error/invalid_uri'
152
152
  require 'mongo/error/invalid_write_concern'
153
153
  require 'mongo/error/insufficient_iteration_count'
154
+ require 'mongo/error/lint_error'
154
155
  require 'mongo/error/max_bson_size'
155
156
  require 'mongo/error/max_message_size'
156
157
  require 'mongo/error/mismatched_domain'
@@ -0,0 +1,35 @@
1
+ # Copyright (C) 2018 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
+ class Error
17
+
18
+ # Raised when the driver is used incorrectly.
19
+ #
20
+ # Normally the driver passes certain data to the server and lets the
21
+ # server return an error if the data is invalid. This makes it possible
22
+ # for the server to add functionality in the future and for older
23
+ # driver versions to support such functionality transparently, but
24
+ # also complicates debugging.
25
+ #
26
+ # Setting the environment variable MONGO_RUBY_DRIVER_LINT to 1, true
27
+ # or yes will make the driver perform additional checks on data it passes
28
+ # to the server, to flag failures sooner. This exception is raised on
29
+ # such failures.
30
+ #
31
+ # @since 2.7.0
32
+ class LintError < Error
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,45 @@
1
+ module Mongo
2
+ # @api private
3
+ module Lint
4
+ def validate_underscore_read_preference(read_pref)
5
+ return unless enabled?
6
+ if read_pref
7
+ validate_underscore_read_preference_mode(read_pref[:mode] || read_pref['mode'])
8
+ end
9
+ end
10
+ module_function :validate_underscore_read_preference
11
+
12
+ def validate_underscore_read_preference_mode(mode)
13
+ return unless enabled?
14
+ if mode
15
+ unless %w(primary primary_preferred secondary secondary_preferred nearest).include?(mode.to_s)
16
+ raise Error::LintError, "Invalid read preference mode: #{mode}"
17
+ end
18
+ end
19
+ end
20
+ module_function :validate_underscore_read_preference_mode
21
+
22
+ def validate_camel_case_read_preference(read_pref)
23
+ return unless enabled?
24
+ if read_pref
25
+ validate_camel_case_read_preference_mode(read_pref[:mode] || read_pref['mode'])
26
+ end
27
+ end
28
+ module_function :validate_camel_case_read_preference
29
+
30
+ def validate_camel_case_read_preference_mode(mode)
31
+ return unless enabled?
32
+ if mode
33
+ unless %w(primary primaryPreferred secondary secondaryPreferred nearest).include?(mode.to_s)
34
+ raise Error::LintError, "Invalid read preference mode: #{mode}"
35
+ end
36
+ end
37
+ end
38
+ module_function :validate_camel_case_read_preference_mode
39
+
40
+ def enabled?
41
+ ENV['MONGO_RUBY_DRIVER_LINT'] && %w(1 yes true).include?(ENV['MONGO_RUBY_DRIVER_LINT'].downcase)
42
+ end
43
+ module_function :enabled?
44
+ end
45
+ end
@@ -30,8 +30,9 @@ module Mongo
30
30
 
31
31
  def update_selector_for_read_pref(sel, server)
32
32
  if read && server.mongos? && read_pref = read.to_mongos
33
+ Mongo::Lint.validate_camel_case_read_preference(read_pref)
33
34
  sel = sel[:$query] ? sel : {:$query => sel}
34
- sel.merge(:$readPreference => read_pref)
35
+ sel = sel.merge(:$readPreference => read_pref)
35
36
  else
36
37
  sel
37
38
  end
@@ -24,8 +24,6 @@ module Mongo
24
24
 
25
25
  ZERO_TIMESTAMP = BSON::Timestamp.new(0, 0)
26
26
 
27
- READ_PREFERENCE = '$readPreference'.freeze
28
-
29
27
  READ_COMMANDS = [
30
28
  :aggregate,
31
29
  :collStats,
@@ -101,8 +99,8 @@ module Mongo
101
99
  session.suppress_read_write_concern!(selector)
102
100
  end
103
101
 
104
- def validate_read_pref!(selector)
105
- session.validate_read_pref!(selector) if read_command?(selector)
102
+ def validate_read_preference!(selector)
103
+ session.validate_read_preference!(selector) if read_command?(selector)
106
104
  end
107
105
 
108
106
  def update_session_state!
@@ -113,7 +111,7 @@ module Mongo
113
111
  sel = selector(server)
114
112
  add_write_concern!(sel)
115
113
  sel[Protocol::Msg::DATABASE_IDENTIFIER] = db_name
116
- sel[READ_PREFERENCE] = read.to_doc if read
114
+ sel['$readPreference'] = read.to_doc if read
117
115
 
118
116
  if server.features.sessions_enabled?
119
117
  apply_cluster_time!(sel, server)
@@ -125,7 +123,7 @@ module Mongo
125
123
  apply_autocommit!(sel)
126
124
  apply_txn_opts!(sel)
127
125
  suppress_read_write_concern!(sel)
128
- validate_read_pref!(sel)
126
+ validate_read_preference!(sel)
129
127
  update_session_state!
130
128
  apply_txn_num!(sel)
131
129
  end
@@ -138,7 +136,7 @@ module Mongo
138
136
  apply_autocommit!(sel)
139
137
  apply_txn_opts!(sel)
140
138
  suppress_read_write_concern!(sel)
141
- validate_read_pref!(sel)
139
+ validate_read_preference!(sel)
142
140
  update_session_state!
143
141
  apply_txn_num!(sel)
144
142
  end
@@ -301,6 +301,7 @@ module Mongo
301
301
  OPTION_MAPPINGS.each do |legacy, option|
302
302
  document.store(option, options[legacy]) unless options[legacy].nil?
303
303
  end
304
+ Mongo::Lint.validate_camel_case_read_preference(filter['readPreference'])
304
305
  SPECIAL_FIELD_MAPPINGS.each do |special, normal|
305
306
  document.store(normal, filter[special]) unless filter[special].nil?
306
307
  end
@@ -201,7 +201,7 @@ module Mongo
201
201
  # @example Get the connection pool for the server.
202
202
  # server.pool
203
203
  #
204
- # @return [ Mongo::Pool ] The connection pool.
204
+ # @return [ Mongo::Server::ConnectionPool ] The connection pool.
205
205
  #
206
206
  # @since 2.0.0
207
207
  def pool
@@ -47,7 +47,7 @@ module Mongo
47
47
  # @example Check a connection out from the pool.
48
48
  # pool.checkout
49
49
  #
50
- # @return [ Mongo::Pool::Connection ] The checked out connection.
50
+ # @return [ Mongo::Server::Connection ] The checked out connection.
51
51
  #
52
52
  # @since 2.0.0
53
53
  def checkout
@@ -120,14 +120,14 @@ module Mongo
120
120
 
121
121
  class << self
122
122
 
123
- # Get a connection pool for the provided server.
123
+ # Creates a new connection pool for the provided server.
124
124
  #
125
- # @example Get a connection pool.
126
- # Mongo::Pool.get(server)
125
+ # @example Create a new connection pool.
126
+ # Mongo::Server::ConnectionPool.get(server)
127
127
  #
128
128
  # @param [ Mongo::Server ] server The server.
129
129
  #
130
- # @return [ Mongo::Pool ] The connection pool.
130
+ # @return [ Mongo::Server::ConnectionPool ] The connection pool.
131
131
  #
132
132
  # @since 2.0.0
133
133
  def get(server)
@@ -53,7 +53,7 @@ module Mongo
53
53
  # @example Dequeue a connection.
54
54
  # queue.dequeue
55
55
  #
56
- # @return [ Mongo::Pool::Connection ] The next connection.
56
+ # @return [ Mongo::Server::Connection ] The next connection.
57
57
  #
58
58
  # @since 2.0.0
59
59
  def dequeue
@@ -82,7 +82,7 @@ module Mongo
82
82
  # @example Enqueue a connection.
83
83
  # queue.enqueue(connection)
84
84
  #
85
- # @param [ Mongo::Pool::Connection ] connection The connection.
85
+ # @param [ Mongo::Server::Connection ] connection The connection.
86
86
  #
87
87
  # @since 2.0.0
88
88
  def enqueue(connection)
@@ -96,7 +96,7 @@ module Mongo
96
96
  # the initial size of the queue.
97
97
  #
98
98
  # @example Create the queue.
99
- # Mongo::Pool::Queue.new(max_pool_size: 5) { Connection.new }
99
+ # Mongo::Server::ConnectionPool::Queue.new(max_pool_size: 5) { Connection.new }
100
100
  #
101
101
  # @param [ Hash ] options The options.
102
102
  #
@@ -124,7 +124,7 @@ module Mongo
124
124
  #
125
125
  # @since 2.0.0
126
126
  def inspect
127
- "#<Mongo::Pool::Queue:0x#{object_id} min_size=#{min_size} max_size=#{max_size} " +
127
+ "#<Mongo::Server::ConnectionPool::Queue:0x#{object_id} min_size=#{min_size} max_size=#{max_size} " +
128
128
  "wait_timeout=#{wait_timeout} current_size=#{queue.size}>"
129
129
  end
130
130
 
@@ -71,6 +71,7 @@ module Mongo
71
71
  # @since 2.0.0
72
72
  def get(preference = {})
73
73
  return preference if PREFERENCES.values.include?(preference.class)
74
+ Mongo::Lint.validate_underscore_read_preference(preference)
74
75
  PREFERENCES.fetch((preference[:mode] || :primary).to_sym).new(preference)
75
76
  end
76
77
  end
@@ -110,9 +110,16 @@ module Mongo
110
110
  # @param [ Client ] client The client through which this session is created.
111
111
  # @param [ Hash ] options The options for this session.
112
112
  #
113
+ # @option options [ Hash ] :read_preference The read preference options hash,
114
+ # with the following optional keys:
115
+ # - *:mode* -- the read preference as a string or symbol; valid values are
116
+ # *:primary*, *:primary_preferred*, *:secondary*, *:secondary_preferred*
117
+ # and *:nearest*.
118
+ #
113
119
  # @since 2.5.0
114
120
  def initialize(server_session, client, options = {})
115
121
  @server_session = server_session
122
+ options = options.dup
116
123
 
117
124
  # Because the read preference will need to be inserted into a command as a string, we convert
118
125
  # it from a symbol immediately upon receiving it.
@@ -121,7 +128,7 @@ module Mongo
121
128
  end
122
129
 
123
130
  @client = client.use(:admin)
124
- @options = options.dup.freeze
131
+ @options = options.freeze
125
132
  @cluster_time = nil
126
133
  @state = NO_TRANSACTION_STATE
127
134
  end
@@ -232,7 +239,13 @@ module Mongo
232
239
  def add_txn_opts!(command, read)
233
240
  command.tap do |c|
234
241
  # The read preference should be added for all read operations.
235
- c['$readPreference'] = txn_read_pref if read && txn_read_pref
242
+ if read && txn_read_pref = txn_read_preference
243
+ Mongo::Lint.validate_underscore_read_preference(txn_read_pref)
244
+ txn_read_pref = txn_read_pref.dup
245
+ txn_read_pref[:mode] = txn_read_pref[:mode].to_s.gsub(/(_\w)/) { |match| match[1].upcase }
246
+ Mongo::Lint.validate_camel_case_read_preference(txn_read_pref)
247
+ c['$readPreference'] = txn_read_pref
248
+ end
236
249
 
237
250
  # The read concern should be added to any command that starts a transaction.
238
251
  if starting_transaction? && txn_read_concern
@@ -277,14 +290,14 @@ module Mongo
277
290
  # Ensure that the read preference of a command primary.
278
291
  #
279
292
  # @example
280
- # session.validate_read_pref!(command)
293
+ # session.validate_read_preference!(command)
281
294
  #
282
295
  # @raise [ Mongo::Error::InvalidTransactionOperation ] If the read preference of the command is
283
296
  # not primary.
284
297
  #
285
298
  # @since 2.6.0
286
- def validate_read_pref!(command)
287
- return unless in_transaction? && non_primary_readpref?(command)
299
+ def validate_read_preference!(command)
300
+ return unless in_transaction? && non_primary_read_preference_mode?(command)
288
301
 
289
302
  raise Mongo::Error::InvalidTransactionOperation.new(
290
303
  Mongo::Error::InvalidTransactionOperation::INVALID_READ_PREFERENCE)
@@ -452,14 +465,29 @@ module Mongo
452
465
 
453
466
  # Start a new transaction.
454
467
  #
455
- # Note that the transaction will not be started on the server until an operation is performed
456
- # after start_transaction is called.
468
+ # Note that the transaction will not be started on the server until an
469
+ # operation is performed after start_transaction is called.
457
470
  #
458
471
  # @example Start a new transaction
459
472
  # session.start_transaction(options)
460
473
  #
461
- # @raise [ InvalidTransactionOperation ] If a transaction is already in progress or if the
462
- # write concern is unacknowledged.
474
+ # @param [ Hash ] options The options for the transaction being started.
475
+ #
476
+ # @option options [ Hash ] read_concern The read concern options hash, with the following
477
+ # optional keys:
478
+ # - *:level* -- the read preference level as a symbol; valid values are *:local*, *:majority*,
479
+ # and *:snapshot*
480
+ # - *:after_cluster_time* -- the cluster time BSON::Document or hash specifying which cluster
481
+ # time reads should occur after
482
+ # @option options [ Hash ] :write_concern The write concern options. Can be :w =>
483
+ # Integer|String, :fsync => Boolean, :j => Boolean.
484
+ # @option options [ Hash ] :read The read preference options. The hash may have the following
485
+ # items:
486
+ # - *:mode* -- read preference specified as a symbol; the only valid value is
487
+ # *:primary*.
488
+ #
489
+ # @raise [ InvalidTransactionOperation ] If a transaction is already in
490
+ # progress or if the write concern is unacknowledged.
463
491
  #
464
492
  # @since 2.6.0
465
493
  def start_transaction(options = nil)
@@ -594,18 +622,21 @@ module Mongo
594
622
  within_states?(STARTING_TRANSACTION_STATE, TRANSACTION_IN_PROGRESS_STATE)
595
623
  end
596
624
 
597
- # Get the read preference document the session will use in the currently active transaction.
625
+ # Get the read preference the session will use in the currently
626
+ # active transaction.
627
+ #
628
+ # This is a driver style hash with underscore keys.
598
629
  #
599
630
  # @example Get the transaction's read preference
600
- # session.txn_read_pref
631
+ # session.txn_read_preference
601
632
  #
602
- # @return [ Hash ] The read preference document of the transaction.
633
+ # @return [ Hash ] The read preference of the transaction.
603
634
  #
604
635
  # @since 2.6.0
605
- def txn_read_pref
606
- rp = (txn_options && txn_options[:read_preference] && txn_options[:read_preference].dup) ||
607
- (@client.read_preference && @client.read_preference.dup)
608
- rp[:mode] = rp[:mode].to_s if rp
636
+ def txn_read_preference
637
+ rp = txn_options && txn_options[:read_preference] ||
638
+ @client.read_preference
639
+ Mongo::Lint.validate_underscore_read_preference(rp)
609
640
  rp
610
641
  end
611
642
 
@@ -639,7 +670,7 @@ module Mongo
639
670
  (@client.write_concern && @client.write_concern.options)
640
671
  end
641
672
 
642
- def non_primary_readpref?(command)
673
+ def non_primary_read_preference_mode?(command)
643
674
  return false unless command['$readPreference']
644
675
 
645
676
  mode = command['$readPreference']['mode'] || command['$readPreference'][:mode]