Module: Mongo::Collection::View::Writable
Relationships & Source Files | |
Extension / Inclusion / Inheritance Descendants | |
Included In:
| |
Defined in: | lib/mongo/collection/view/writable.rb |
Overview
Defines write related behavior for collection view.
Constant Summary
-
ARRAY_FILTERS =
The array filters field constant.
'array_filters'.freeze
Instance Method Summary
-
#delete_many(opts = {}) ⇒ Result
Remove documents from the collection.
-
#delete_one(opts = {}) ⇒ Result
Remove a document from the collection.
-
#find_one_and_delete(opts = {}) ⇒ BSON::Document?
Finds a single document in the database via findAndModify and deletes it, returning the original document.
-
#find_one_and_replace(replacement, opts = {}) ⇒ BSON::Document
Finds a single document and replaces it.
-
#find_one_and_update(document, opts = {}) ⇒ BSON::Document | nil
Finds a single document and updates it.
-
#replace_one(replacement, opts = {}) ⇒ Result
Replaces a single document in the database with the new document.
-
#update_many(spec, opts = {}) ⇒ Result
Update documents in the collection.
-
#update_one(spec, opts = {}) ⇒ Result
Update a single document in the collection.
-
#validate_replacement_documents!(spec)
private
Check the replacement documents to make sure they don’t have atomic modifiers.
-
#validate_update_documents!(spec)
private
Checks the update documents to make sure they only have atomic modifiers.
Instance Method Details
#delete_many(opts = {}) ⇒ Result
Remove documents from the collection.
# File 'lib/mongo/collection/view/writable.rb', line 257
def delete_many(opts = {}) with_session(opts) do |session| write_concern = if opts[:write_concern] WriteConcern.get(opts[:write_concern]) else write_concern_with_session(session) end QueryCache.clear_namespace(collection.namespace) delete_doc = { Operation::Q => filter, Operation::LIMIT => 0, hint: opts[:hint], collation: opts[:collation] || opts['collation'] || collation, }.compact context = Operation::Context.new( client: client, session: session, operation_timeouts: operation_timeouts(opts) ) nro_write_with_retry(write_concern, context: context) do |connection, txn_num, context| gte_4_4 = connection.server.description.server_version_gte?('4.4') if !gte_4_4 && opts[:hint] && write_concern && !write_concern.acknowledged? raise Error::UnsupportedOption.hint_error(unacknowledged_write: true) end Operation::Delete.new( deletes: [ delete_doc ], db_name: collection.database.name, coll_name: collection.name, write_concern: write_concern, bypass_document_validation: !!opts[:bypass_document_validation], session: session, let: opts[:let], comment: opts[:comment], ).execute_with_connection(connection, context: context) end end end
#delete_one(opts = {}) ⇒ Result
Remove a document from the collection.
# File 'lib/mongo/collection/view/writable.rb', line 323
def delete_one(opts = {}) with_session(opts) do |session| write_concern = if opts[:write_concern] WriteConcern.get(opts[:write_concern]) else write_concern_with_session(session) end QueryCache.clear_namespace(collection.namespace) delete_doc = { Operation::Q => filter, Operation::LIMIT => 1, hint: opts[:hint], collation: opts[:collation] || opts['collation'] || collation, }.compact context = Operation::Context.new( client: client, session: session, operation_timeouts: operation_timeouts(opts) ) write_with_retry(write_concern, context: context) do |connection, txn_num, context| gte_4_4 = connection.server.description.server_version_gte?('4.4') if !gte_4_4 && opts[:hint] && write_concern && !write_concern.acknowledged? raise Error::UnsupportedOption.hint_error(unacknowledged_write: true) end Operation::Delete.new( deletes: [ delete_doc ], db_name: collection.database.name, coll_name: collection.name, write_concern: write_concern, bypass_document_validation: !!opts[:bypass_document_validation], session: session, txn_num: txn_num, let: opts[:let], comment: opts[:comment], ).execute_with_connection(connection, context: context) end end end
#find_one_and_delete(opts = {}) ⇒ BSON::Document
?
Finds a single document in the database via findAndModify and deletes it, returning the original document.
# File 'lib/mongo/collection/view/writable.rb', line 64
def find_one_and_delete(opts = {}) with_session(opts) do |session| write_concern = if opts[:write_concern] WriteConcern.get(opts[:write_concern]) else write_concern_with_session(session) end QueryCache.clear_namespace(collection.namespace) cmd = { findAndModify: collection.name, query: filter, remove: true, fields: projection, sort: sort, maxTimeMS: max_time_ms, bypassDocumentValidation: opts[:bypass_document_validation], hint: opts[:hint], collation: opts[:collation] || opts['collation'] || collation, let: opts[:let], comment: opts[:comment], }.compact context = Operation::Context.new( client: client, session: session, operation_timeouts: operation_timeouts(opts) ) write_with_retry(write_concern, context: context) do |connection, txn_num, context| gte_4_4 = connection.server.description.server_version_gte?('4.4') if !gte_4_4 && opts[:hint] && write_concern && !write_concern.acknowledged? raise Error::UnsupportedOption.hint_error(unacknowledged_write: true) end Operation::WriteCommand.new( selector: cmd, db_name: database.name, write_concern: write_concern, session: session, txn_num: txn_num, ).execute_with_connection(connection, context: context) end end.first&.fetch('value', nil) end
#find_one_and_replace(replacement, opts = {}) ⇒ BSON::Document
Finds a single document and replaces it.
# File 'lib/mongo/collection/view/writable.rb', line 140
def find_one_and_replace(replacement, opts = {}) find_one_and_update(replacement, opts) end
#find_one_and_update(document, opts = {}) ⇒ BSON::Document
| nil
Finds a single document and updates it.
an update should apply.
# File 'lib/mongo/collection/view/writable.rb', line 182
def find_one_and_update(document, opts = {}) value = with_session(opts) do |session| write_concern = if opts[:write_concern] WriteConcern.get(opts[:write_concern]) else write_concern_with_session(session) end QueryCache.clear_namespace(collection.namespace) cmd = { findAndModify: collection.name, query: filter, arrayFilters: opts[:array_filters] || opts['array_filters'], update: document, fields: projection, sort: sort, new: !!(opts[:return_document] && opts[:return_document] == :after), upsert: opts[:upsert], maxTimeMS: max_time_ms, bypassDocumentValidation: opts[:bypass_document_validation], hint: opts[:hint], collation: opts[:collation] || opts['collation'] || collation, let: opts[:let], comment: opts[:comment] }.compact context = Operation::Context.new( client: client, session: session, operation_timeouts: operation_timeouts(opts) ) write_with_retry(write_concern, context: context) do |connection, txn_num, context| gte_4_4 = connection.server.description.server_version_gte?('4.4') if !gte_4_4 && opts[:hint] && write_concern && !write_concern.acknowledged? raise Error::UnsupportedOption.hint_error(unacknowledged_write: true) end Operation::WriteCommand.new( selector: cmd, db_name: database.name, write_concern: write_concern, session: session, txn_num: txn_num, ).execute_with_connection(connection, context: context) end end.first&.fetch('value', nil) value unless value.nil? || value.empty? end
#replace_one(replacement, opts = {}) ⇒ Result
Replaces a single document in the database with the new document.
# File 'lib/mongo/collection/view/writable.rb', line 396
def replace_one(replacement, opts = {}) with_session(opts) do |session| write_concern = if opts[:write_concern] WriteConcern.get(opts[:write_concern]) else write_concern_with_session(session) end validate_replacement_documents!(replacement) QueryCache.clear_namespace(collection.namespace) update_doc = { Operation::Q => filter, arrayFilters: opts[:array_filters] || opts['array_filters'], Operation::U => replacement, hint: opts[:hint], collation: opts[:collation] || opts['collation'] || collation, }.compact if opts[:upsert] update_doc['upsert'] = true end context = Operation::Context.new( client: client, session: session, operation_timeouts: operation_timeouts(opts) ) write_with_retry(write_concern, context: context) do |connection, txn_num, context| gte_4_2 = connection.server.description.server_version_gte?('4.2') if !gte_4_2 && opts[:hint] && write_concern && !write_concern.acknowledged? raise Error::UnsupportedOption.hint_error(unacknowledged_write: true) end Operation::Update.new( updates: [ update_doc ], db_name: collection.database.name, coll_name: collection.name, write_concern: write_concern, bypass_document_validation: !!opts[:bypass_document_validation], session: session, txn_num: txn_num, let: opts[:let], comment: opts[:comment], ).execute_with_connection(connection, context: context) end end end
#update_many(spec, opts = {}) ⇒ Result
Update documents in the collection.
# File 'lib/mongo/collection/view/writable.rb', line 476
def update_many(spec, opts = {}) with_session(opts) do |session| write_concern = if opts[:write_concern] WriteConcern.get(opts[:write_concern]) else write_concern_with_session(session) end validate_update_documents!(spec) QueryCache.clear_namespace(collection.namespace) update_doc = { Operation::Q => filter, arrayFilters: opts[:array_filters] || opts['array_filters'], Operation::U => spec, Operation::MULTI => true, hint: opts[:hint], collation: opts[:collation] || opts['collation'] || collation, }.compact if opts[:upsert] update_doc['upsert'] = true end context = Operation::Context.new( client: client, session: session, operation_timeouts: operation_timeouts(opts) ) nro_write_with_retry(write_concern, context: context) do |connection, txn_num, context| gte_4_2 = connection.server.description.server_version_gte?('4.2') if !gte_4_2 && opts[:hint] && write_concern && !write_concern.acknowledged? raise Error::UnsupportedOption.hint_error(unacknowledged_write: true) end Operation::Update.new( updates: [ update_doc ], db_name: collection.database.name, coll_name: collection.name, write_concern: write_concern, bypass_document_validation: !!opts[:bypass_document_validation], session: session, let: opts[:let], comment: opts[:comment], ).execute_with_connection(connection, context: context) end end end
#update_one(spec, opts = {}) ⇒ Result
Update a single document in the collection.
# File 'lib/mongo/collection/view/writable.rb', line 556
def update_one(spec, opts = {}) with_session(opts) do |session| write_concern = if opts[:write_concern] WriteConcern.get(opts[:write_concern]) else write_concern_with_session(session) end validate_update_documents!(spec) QueryCache.clear_namespace(collection.namespace) update_doc = { Operation::Q => filter, arrayFilters: opts[:array_filters] || opts['array_filters'], Operation::U => spec, hint: opts[:hint], collation: opts[:collation] || opts['collation'] || collation, }.compact if opts[:upsert] update_doc['upsert'] = true end context = Operation::Context.new( client: client, session: session, operation_timeouts: operation_timeouts(opts) ) write_with_retry(write_concern, context: context) do |connection, txn_num, context| gte_4_2 = connection.server.description.server_version_gte?('4.2') if !gte_4_2 && opts[:hint] && write_concern && !write_concern.acknowledged? raise Error::UnsupportedOption.hint_error(unacknowledged_write: true) end Operation::Update.new( updates: [ update_doc ], db_name: collection.database.name, coll_name: collection.name, write_concern: write_concern, bypass_document_validation: !!opts[:bypass_document_validation], session: session, txn_num: txn_num, let: opts[:let], comment: opts[:comment], ).execute_with_connection(connection, context: context) end end end
#validate_replacement_documents!(spec) (private)
Check the replacement documents to make sure they don’t have atomic modifiers. Note that as per the spec, we only have to examine the first element in the replacement document.
# File 'lib/mongo/collection/view/writable.rb', line 636
def validate_replacement_documents!(spec) if replace = spec.is_a?(Array) ? spec&.first : spec if key = replace.keys&.first if key.to_s.start_with?("$") if Mongo.validate_update_replace raise Error::InvalidReplacementDocument.new(key: key) else Error::InvalidReplacementDocument.warn(Logger.logger, key) end end end end end
#validate_update_documents!(spec) (private)
Checks the update documents to make sure they only have atomic modifiers. Note that as per the spec, we only have to examine the first element in the update document.
# File 'lib/mongo/collection/view/writable.rb', line 614
def validate_update_documents!(spec) if update = spec.is_a?(Array) ? spec&.first : spec if key = update.keys&.first unless key.to_s.start_with?("$") if Mongo.validate_update_replace raise Error::InvalidUpdateDocument.new(key: key) else Error::InvalidUpdateDocument.warn(Logger.logger, key) end end end end end