lib/mongo/database/view.rb in mongo-2.9.2 vs lib/mongo/database/view.rb in mongo-2.10.0.rc0
- old
+ new
@@ -22,10 +22,12 @@
extend Forwardable
include Enumerable
include Retryable
def_delegators :@database, :cluster, :read_preference, :client
+ # @api private
+ def_delegators :@database, :server_selector, :read_concern
def_delegators :cluster, :next_primary
# @return [ Integer ] batch_size The size of the batch of results
# when sending the listCollections command.
attr_reader :batch_size
@@ -36,12 +38,12 @@
# @return [ Collection ] collection The command collection.
attr_reader :collection
# Get all the names of the non-system collections in the database.
#
- # @example Get the collection names.
- # database.collection_names
+ # @note The set of returned collection names depends on the version of
+ # MongoDB server that fulfills the request.
#
# @param [ Hash ] options Options for the listCollections command.
#
# @option options [ Integer ] :batch_size The batch size for results
# returned from the listCollections command.
@@ -50,34 +52,40 @@
#
# @since 2.0.0
def collection_names(options = {})
@batch_size = options[:batch_size]
session = client.send(:get_session, options)
- cursor = read_with_retry_cursor(session, ServerSelector.get(mode: :primary), self) do |server|
+ cursor = read_with_retry_cursor(session, ServerSelector.primary, self) do |server|
send_initial_query(server, session, name_only: true)
end
cursor.map do |info|
if cursor.server.features.list_collections_enabled?
- info[Database::NAME]
+ info['name']
else
- (info[Database::NAME] &&
- info[Database::NAME].sub("#{@database.name}.", ''))
+ (info['name'] &&
+ info['name'].sub("#{@database.name}.", ''))
end
+ end.reject do |name|
+ name.start_with?('system.') || name.include?('$')
end
end
# Get info on all the collections in the database.
#
+ # @note The set of collections returned, and the schema of the
+ # information hash per collection, depends on the MongoDB server
+ # version that fulfills the request.
+ #
# @example Get info on each collection.
# database.list_collections
#
# @return [ Array<Hash> ] Info for each collection in the database.
#
# @since 2.0.5
def list_collections
session = client.send(:get_session)
- collections_info(session, ServerSelector.get(mode: :primary))
+ collections_info(session, ServerSelector.primary)
end
# Create the new database view.
#
# @example Create the new database view.
@@ -91,21 +99,56 @@
@batch_size = nil
@limit = nil
@collection = @database[Database::COMMAND]
end
+ # @api private
+ attr_reader :database
+
+ # Execute an aggregation on the database view.
+ #
+ # @example Aggregate documents.
+ # view.aggregate([
+ # { "$listLocalSessions" => {} }
+ # ])
+ #
+ # @param [ Array<Hash> ] pipeline The aggregation pipeline.
+ # @param [ Hash ] options The aggregation options.
+ #
+ # @return [ Aggregation ] The aggregation object.
+ #
+ # @since 2.10.0
+ # @api private
+ def aggregate(pipeline, options = {})
+ Collection::View::Aggregation.new(self, pipeline, options)
+ end
+
private
def collections_info(session, server_selector, options = {}, &block)
+ description = nil
cursor = read_with_retry_cursor(session, server_selector, self) do |server|
+ # TODO take description from the connection used to send the query
+ # once https://jira.mongodb.org/browse/RUBY-1601 is fixed.
+ description = server.description
send_initial_query(server, session, options)
end
- if block_given?
- cursor.each do |doc|
- yield doc
+ # On 3.0+ servers, we get just the collection names.
+ # On 2.6 server, we get collection names prefixed with the database
+ # name. We need to filter system collections out here because
+ # in the caller we don't know which server version executed the
+ # command and thus what the proper filtering logic should be
+ # (it is valid for collection names to have dots, thus filtering out
+ # collections named system.* here for 2.6 servers would actually
+ # filter out collections in the system database).
+ if description.server_version_gte?('3.0')
+ cursor.reject do |doc|
+ doc['name'].start_with?('system.') || doc['name'].include?('$')
end
else
- cursor.to_enum
+ docs = cursor.reject do |doc|
+ doc['name'].start_with?("#{database.name}.system") || doc['name'].include?('$')
+ end
end
end
def collections_info_spec(session, options = {})
{ selector: {