module Mongo::Collection::QueryableEncryption

This module contains methods for creating and dropping auxiliary collections for queryable encryption.

@api private

Constants

QE2_MIN_WIRE_VERSION

The minimum wire version for QE2 support

Public Instance Methods

maybe_create_qe_collections(encrypted_fields, client, session) { || ... } click to toggle source

Creates auxiliary collections and indices for queryable encryption if necessary.

@param [ Hash | nil ] encrypted_fields Encrypted fields hash that was

provided to `create` collection helper.

@param [ Client ] client Mongo client to be used to create auxiliary collections. @param [ Session ] session Session to be used to create auxiliary collections.

@return [ Result ] The result of provided block.

# File lib/mongo/collection/queryable_encryption.rb, line 35
def maybe_create_qe_collections(encrypted_fields, client, session)
  encrypted_fields = encrypted_fields_from(encrypted_fields)
  return yield if encrypted_fields.empty?

  server = next_primary(nil, session)
  context = Operation::Context.new(client: client, session: session)
  server.with_connection do |connection|
    check_wire_version!(connection)
    emm_collections(encrypted_fields).each do |coll|
      create_operation_for(coll)
        .execute_with_connection(connection, context: context)
    end
  end

  yield(encrypted_fields).tap do |result|
    indexes.create_one(__safeContent__: 1) if result
  end
end
maybe_drop_emm_collections(encrypted_fields, client, session) { || ... } click to toggle source

Drops auxiliary collections and indices for queryable encryption if necessary.

@param [ Hash | nil ] encrypted_fields Encrypted fields hash that was

provided to `create` collection helper.

@param [ Client ] client Mongo client to be used to drop auxiliary collections. @param [ Session ] session Session to be used to drop auxiliary collections.

@return [ Result ] The result of provided block.

# File lib/mongo/collection/queryable_encryption.rb, line 62
def maybe_drop_emm_collections(encrypted_fields, client, session)
  encrypted_fields = if encrypted_fields
                       encrypted_fields
                     elsif encrypted_fields_map
                       encrypted_fields_for_drop_from_map
                     else
                       {}
                     end

  return yield if encrypted_fields.empty?

  emm_collections(encrypted_fields).each do |coll|
    context = Operation::Context.new(client: client, session: session)
    operation = Operation::Drop.new(
      selector: { drop: coll },
      db_name: database.name,
      session: session
    )
    do_drop(operation, session, context)
  end

  yield
end

Private Instance Methods

check_wire_version!(connection) click to toggle source

Creating encrypted collections is only supported on 7.0.0 and later (wire version 21+).

@param [ Mongo::Connection ] connection The connection to check

the wire version of.

@raise [ Mongo::Error ] if the wire version is not

recent enough
# File lib/mongo/collection/queryable_encryption.rb, line 109
def check_wire_version!(connection)
  return unless connection.description.max_wire_version < QE2_MIN_WIRE_VERSION

  raise Mongo::Error,
        'Driver support of Queryable Encryption is incompatible with server. ' \
        'Upgrade server to use Queryable Encryption.'
end
create_operation_for(coll) click to toggle source

Returns a new create operation for the given collection.

@param [ String ] coll the name of the collection to create.

@return [ Operation::Create ] the new create operation.

# File lib/mongo/collection/queryable_encryption.rb, line 148
def create_operation_for(coll)
  Operation::Create.new(
    selector: {
      create: coll,
      clusteredIndex: {
        key: { _id: 1 },
        unique: true
      }
    },
    db_name: database.name
  )
end
emm_collections(encrypted_fields) click to toggle source

Checks if names for auxiliary collections are set and returns them, otherwise returns default names.

@param [ Hash ] encrypted_fields Encrypted fields hash.

@return [ Array <String> ] Array of auxiliary collections names.

# File lib/mongo/collection/queryable_encryption.rb, line 94
def emm_collections(encrypted_fields)
  [
    encrypted_fields['escCollection'] || "enxcol_.#{name}.esc",
    encrypted_fields['ecocCollection'] || "enxcol_.#{name}.ecoc",
  ]
end
encrypted_fields_for_drop_from_map() click to toggle source

Tries to return the encrypted fields from the {{encrypted_fields_map}} value, for the current namespace.

@return [ Hash | nil ] the encrypted fields, if found

# File lib/mongo/collection/queryable_encryption.rb, line 134
def encrypted_fields_for_drop_from_map
  encrypted_fields_map[namespace] ||
    database.list_collections(filter: { name: name })
            .first
            &.fetch(:options, {})
            &.fetch(:encryptedFields, {}) ||
    {}
end
encrypted_fields_from(fields) click to toggle source

Tries to return the encrypted fields from the argument. If the argument is nil, tries to find the encrypted fields from the encrypted_fields_map.

@param [ Hash | nil ] fields the encrypted fields

@return [ Hash ] the encrypted fields

# File lib/mongo/collection/queryable_encryption.rb, line 124
def encrypted_fields_from(fields)
  fields ||
    (encrypted_fields_map && encrypted_fields_map[namespace]) ||
    {}
end