RUBY-284 document :read API
This commit is contained in:
parent
5d83ab2460
commit
50c38c6c6b
|
@ -34,6 +34,11 @@ module Mongo
|
||||||
# for insert, update, and remove method called on this Collection instance. If no
|
# for insert, update, and remove method called on this Collection instance. If no
|
||||||
# value is provided, the default value set on this instance's DB will be used. This
|
# value is provided, the default value set on this instance's DB will be used. This
|
||||||
# default can be overridden for any invocation of insert, update, or remove.
|
# default can be overridden for any invocation of insert, update, or remove.
|
||||||
|
# @option options [:primary, :secondary] :read The default read preference for queries
|
||||||
|
# initiates from this connection object. If +:secondary+ is chosen, reads will be sent
|
||||||
|
# to one of the closest available secondary nodes. If a secondary node cannot be located, the
|
||||||
|
# read will be sent to the primary. If this option is left unspecified, the value of the read
|
||||||
|
# preference for this collection's associated Mongo::DB object will be used.
|
||||||
#
|
#
|
||||||
# @raise [InvalidNSName]
|
# @raise [InvalidNSName]
|
||||||
# if collection name is empty, contains '$', or starts or ends with '.'
|
# if collection name is empty, contains '$', or starts or ends with '.'
|
||||||
|
@ -84,8 +89,12 @@ module Mongo
|
||||||
@cache = Hash.new(0)
|
@cache = Hash.new(0)
|
||||||
unless pk_factory
|
unless pk_factory
|
||||||
@safe = opts.fetch(:safe, @db.safe)
|
@safe = opts.fetch(:safe, @db.safe)
|
||||||
@read = opts.fetch(:read, @db.read_preference)
|
if value = opts[:read]
|
||||||
@read_preference = @read.is_a?(Hash) ? @read.dup : @read
|
Mongo::Support.validate_read_preference(value)
|
||||||
|
else
|
||||||
|
value = @db.read_preference
|
||||||
|
end
|
||||||
|
@read_preference = value.is_a?(Hash) ? value.dup : value
|
||||||
end
|
end
|
||||||
@pk_factory = pk_factory || opts[:pk] || BSON::ObjectId
|
@pk_factory = pk_factory || opts[:pk] || BSON::ObjectId
|
||||||
@hint = nil
|
@hint = nil
|
||||||
|
@ -157,6 +166,11 @@ module Mongo
|
||||||
# you can cut down on network traffic and decoding time. If using a Hash, keys should be field
|
# you can cut down on network traffic and decoding time. If using a Hash, keys should be field
|
||||||
# names and values should be either 1 or 0, depending on whether you want to include or exclude
|
# names and values should be either 1 or 0, depending on whether you want to include or exclude
|
||||||
# the given field.
|
# the given field.
|
||||||
|
# @option opts [:primary, :secondary] :read The default read preference for queries
|
||||||
|
# initiates from this connection object. If +:secondary+ is chosen, reads will be sent
|
||||||
|
# to one of the closest available secondary nodes. If a secondary node cannot be located, the
|
||||||
|
# read will be sent to the primary. If this option is left unspecified, the value of the read
|
||||||
|
# preference for this Collection object will be used.
|
||||||
# @option opts [Integer] :skip number of documents to skip from the beginning of the result set
|
# @option opts [Integer] :skip number of documents to skip from the beginning of the result set
|
||||||
# @option opts [Integer] :limit maximum number of documents to return
|
# @option opts [Integer] :limit maximum number of documents to return
|
||||||
# @option opts [Array] :sort an array of [key, direction] pairs to sort by. Direction should
|
# @option opts [Array] :sort an array of [key, direction] pairs to sort by. Direction should
|
||||||
|
|
|
@ -685,6 +685,7 @@ module Mongo
|
||||||
@connect_timeout = opts[:connect_timeout] || nil
|
@connect_timeout = opts[:connect_timeout] || nil
|
||||||
|
|
||||||
# Mutex for synchronizing pool access
|
# Mutex for synchronizing pool access
|
||||||
|
# TODO: remove this.
|
||||||
@connection_mutex = Mutex.new
|
@connection_mutex = Mutex.new
|
||||||
|
|
||||||
# Global safe option. This is false by default.
|
# Global safe option. This is false by default.
|
||||||
|
|
|
@ -70,8 +70,12 @@ module Mongo
|
||||||
@query_run = false
|
@query_run = false
|
||||||
|
|
||||||
@transformer = opts[:transformer]
|
@transformer = opts[:transformer]
|
||||||
read = opts[:read] || collection.read_preference
|
if value = opts[:read]
|
||||||
@read_preference = read.is_a?(Hash) ? read.dup : read
|
Mongo::Support.validate_read_preference(value)
|
||||||
|
else
|
||||||
|
value = collection.read_preference
|
||||||
|
end
|
||||||
|
@read_preference = value.is_a?(Hash) ? value.dup : value
|
||||||
batch_size(opts[:batch_size] || 0)
|
batch_size(opts[:batch_size] || 0)
|
||||||
|
|
||||||
@full_collection_name = "#{@collection.db.name}.#{@collection.name}"
|
@full_collection_name = "#{@collection.db.name}.#{@collection.name}"
|
||||||
|
|
|
@ -82,8 +82,12 @@ module Mongo
|
||||||
@strict = opts[:strict]
|
@strict = opts[:strict]
|
||||||
@pk_factory = opts[:pk]
|
@pk_factory = opts[:pk]
|
||||||
@safe = opts.fetch(:safe, @connection.safe)
|
@safe = opts.fetch(:safe, @connection.safe)
|
||||||
read = opts.fetch(:read, @connection.read_preference)
|
if value = opts[:read]
|
||||||
@read_preference = read.is_a?(Hash) ? read.dup : read
|
Mongo::Support.validate_read_preference(value)
|
||||||
|
else
|
||||||
|
value = @connection.read_preference
|
||||||
|
end
|
||||||
|
@read_preference = value.is_a?(Hash) ? value.dup : value
|
||||||
@cache_time = opts[:cache_time] || 300 #5 minutes.
|
@cache_time = opts[:cache_time] || 300 #5 minutes.
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -41,8 +41,10 @@ module Mongo
|
||||||
# propogated to DB objects instantiated off of this Connection. This
|
# propogated to DB objects instantiated off of this Connection. This
|
||||||
# default can be overridden upon instantiation of any DB by explicity setting a :safe value
|
# default can be overridden upon instantiation of any DB by explicity setting a :safe value
|
||||||
# on initialization.
|
# on initialization.
|
||||||
# @option options [Boolean] :read_secondary(false) If true, a random secondary node will be chosen,
|
# @option options [:primary, :secondary] :read (:primary) The default read preference for Mongo::DB
|
||||||
# and all reads will be directed to that node.
|
# objects created from this connection object. If +:secondary+ is chosen, reads will be sent
|
||||||
|
# to one of the closest available secondary nodes. If a secondary node cannot be located, the
|
||||||
|
# read will be sent to the primary.
|
||||||
# @option options [Logger, #debug] :logger (nil) Logger instance to receive driver operation log.
|
# @option options [Logger, #debug] :logger (nil) Logger instance to receive driver operation log.
|
||||||
# @option options [Integer] :pool_size (1) The maximum number of socket connections allowed per
|
# @option options [Integer] :pool_size (1) The maximum number of socket connections allowed per
|
||||||
# connection pool. Note: this setting is relevant only for multi-threaded applications.
|
# connection pool. Note: this setting is relevant only for multi-threaded applications.
|
||||||
|
@ -125,6 +127,7 @@ module Mongo
|
||||||
@read = :secondary
|
@read = :secondary
|
||||||
else
|
else
|
||||||
@read = opts.fetch(:read, :primary)
|
@read = opts.fetch(:read, :primary)
|
||||||
|
Mongo::Support.validate_read_preference(@read)
|
||||||
end
|
end
|
||||||
|
|
||||||
@connected = false
|
@connected = false
|
||||||
|
|
|
@ -44,7 +44,6 @@ module Mongo
|
||||||
Digest::MD5.hexdigest("#{username}:mongo:#{plaintext}")
|
Digest::MD5.hexdigest("#{username}:mongo:#{plaintext}")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
def validate_db_name(db_name)
|
def validate_db_name(db_name)
|
||||||
unless [String, Symbol].include?(db_name.class)
|
unless [String, Symbol].include?(db_name.class)
|
||||||
raise TypeError, "db_name must be a string or symbol"
|
raise TypeError, "db_name must be a string or symbol"
|
||||||
|
@ -59,6 +58,15 @@ module Mongo
|
||||||
db_name
|
db_name
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def validate_read_preference(value)
|
||||||
|
if [:primary, :secondary, nil].include?(value)
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
raise MongoArgumentError, "#{value} is not a valid read preference. " +
|
||||||
|
"Please specify either :primary or :secondary."
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def format_order_clause(order)
|
def format_order_clause(order)
|
||||||
case order
|
case order
|
||||||
when String, Symbol then string_as_sort_parameters(order)
|
when String, Symbol then string_as_sort_parameters(order)
|
||||||
|
|
|
@ -1,41 +1,43 @@
|
||||||
$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
||||||
require './test/replica_sets/rs_test_helper'
|
require './test/replica_sets/rs_test_helper'
|
||||||
|
|
||||||
|
# TODO: enable this once we enable reads from tags.
|
||||||
class ReadPreferenceTest < Test::Unit::TestCase
|
class ReadPreferenceTest < Test::Unit::TestCase
|
||||||
include Mongo
|
include Mongo
|
||||||
|
|
||||||
def setup
|
#def setup
|
||||||
@conn = ReplSetConnection.new([RS.host, RS.ports[0], RS.host, RS.ports[1]], :read => :secondary, :pool_size => 50)
|
# @conn = ReplSetConnection.new([RS.host, RS.ports[0], RS.host, RS.ports[1]], :read => :secondary, :pool_size => 50)
|
||||||
@db = @conn.db(MONGO_TEST_DB)
|
# @db = @conn.db(MONGO_TEST_DB)
|
||||||
@db.drop_collection("test-sets")
|
# @db.drop_collection("test-sets")
|
||||||
end
|
#end
|
||||||
|
|
||||||
def test_query_tagged
|
# TODO: enable this once we enable reads from tags.
|
||||||
col = @db['mongo-test']
|
# def test_query_tagged
|
||||||
|
# col = @db['mongo-test']
|
||||||
|
|
||||||
col.insert({:a => 1}, :safe => {:w => 3})
|
# col.insert({:a => 1}, :safe => {:w => 3})
|
||||||
col.find_one({}, :read => {:db => "main"})
|
# col.find_one({}, :read => {:db => "main"})
|
||||||
col.find_one({}, :read => {:dc => "ny"})
|
# col.find_one({}, :read => {:dc => "ny"})
|
||||||
col.find_one({}, :read => {:dc => "sf"})
|
# col.find_one({}, :read => {:dc => "sf"})
|
||||||
|
|
||||||
assert_raise Mongo::NodeWithTagsNotFound do
|
# assert_raise Mongo::NodeWithTagsNotFound do
|
||||||
col.find_one({}, :read => {:foo => "bar"})
|
# col.find_one({}, :read => {:foo => "bar"})
|
||||||
end
|
# end
|
||||||
|
|
||||||
threads = []
|
# threads = []
|
||||||
100.times do
|
# 100.times do
|
||||||
threads << Thread.new do
|
# threads << Thread.new do
|
||||||
col.find_one({}, :read => {:dc => "sf"})
|
# col.find_one({}, :read => {:dc => "sf"})
|
||||||
end
|
# end
|
||||||
end
|
# end
|
||||||
|
|
||||||
threads.each {|t| t.join }
|
# threads.each {|t| t.join }
|
||||||
|
|
||||||
col.remove
|
# col.remove
|
||||||
end
|
# end
|
||||||
|
|
||||||
def teardown
|
#def teardown
|
||||||
RS.restart_killed_nodes
|
# RS.restart_killed_nodes
|
||||||
end
|
#end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -87,11 +87,14 @@ class ReadTest < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
should "allow override alternate value on query" do
|
should "allow override alternate value on query" do
|
||||||
@con.expects(:receive_message).with do |o, m, l, s, c, r|
|
# TODO: enable this test once we enable reading from tags.
|
||||||
tags = {:dc => "ny"}
|
# @con.expects(:receive_message).with do |o, m, l, s, c, r|
|
||||||
end.returns([[], 0, 0])
|
# tags = {:dc => "ny"}
|
||||||
|
# end.returns([[], 0, 0])
|
||||||
|
|
||||||
@col.find_one({:a => 1}, :read => {:dc => "ny"})
|
assert_raise MongoArgumentError do
|
||||||
|
@col.find_one({:a => 1}, :read => {:dc => "ny"})
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue