class MassEncryption::Batch

Constants

DEFAULT_BATCH_SIZE

Attributes

from_id[R]
size[R]
track[R]
tracks_count[R]

Public Class Methods

new(klass:, from_id:, size: DEFAULT_BATCH_SIZE, track: 0, tracks_count: 1) click to toggle source
# File lib/mass_encryption/batch.rb, line 8
def initialize(klass:, from_id:, size: DEFAULT_BATCH_SIZE, track: 0, tracks_count: 1)
  @class_name = klass.name # not storing class as instance variable as it causes stack overflow error with json serialization
  @from_id = from_id
  @size = size
  @track = track
  @tracks_count = tracks_count
end

Public Instance Methods

encrypt_later(auto_enqueue_next: false) click to toggle source
# File lib/mass_encryption/batch.rb, line 31
def encrypt_later(auto_enqueue_next: false)
  MassEncryption::BatchEncryptionJob.perform_later(self, auto_enqueue_next: auto_enqueue_next)
end
encrypt_now() click to toggle source
# File lib/mass_encryption/batch.rb, line 20
def encrypt_now
  if klass.encrypted_attributes.present? && present?
    validate_encrypting_is_allowed
    encrypt_records
  end
end
klass() click to toggle source
# File lib/mass_encryption/batch.rb, line 16
def klass
  @class_name.constantize
end
next() click to toggle source
# File lib/mass_encryption/batch.rb, line 41
def next
  self.class.new(klass: klass, from_id: next_track_records.last.id + 1, size: size, track: track, tracks_count: tracks_count)
end
present?() click to toggle source
# File lib/mass_encryption/batch.rb, line 35
def present?
  # we deliberately load the association to avoid 2 queries when checking if there are records
  # before encrypting in +MassEncryption::BatchEncryptionJob+
  records.present?
end
records() click to toggle source
# File lib/mass_encryption/batch.rb, line 45
def records
  @records ||= klass.where("id >= ?", determine_from_id).order(id: :asc).limit(size)
end
to_s() click to toggle source
# File lib/mass_encryption/batch.rb, line 49
def to_s
  "<#{klass}> from: #{from_id} size: #{size} (track=#{track}, tracks_count=#{tracks_count}) | #{records.first.id} - #{records.last.id}"
end
validate_encrypting_is_allowed() click to toggle source
# File lib/mass_encryption/batch.rb, line 27
def validate_encrypting_is_allowed
  raise ActiveRecord::Encryption::Errors::Configuration, "can't mass encrypt while in protected mode" if ActiveRecord::Encryption.context.frozen_encryption?
end

Private Instance Methods

determine_from_id() click to toggle source
# File lib/mass_encryption/batch.rb, line 77
def determine_from_id
  if track == 0
    from_id # save a query to determine the id for the first track
  else
    last_track_id.present? ? (last_track_id + 1) : from_id
  end
end
encrypt_record_by_record() click to toggle source
# File lib/mass_encryption/batch.rb, line 65
def encrypt_record_by_record
  errors_by_record = {}

  records.each do |record|
    record.encrypt
  rescue StandardError => error
    errors_by_record[record] = error
  end

  raise MassEncryption::BatchEncryptionError.new(errors_by_record) if errors_by_record.present?
end
encrypt_records() click to toggle source
# File lib/mass_encryption/batch.rb, line 54
def encrypt_records
  encrypt_using_upsert
rescue StandardError => error
  logger.error "Upsert failed with #{error.inspect}. Trying to encrypt record by record..."
  encrypt_record_by_record
end
encrypt_using_upsert() click to toggle source
# File lib/mass_encryption/batch.rb, line 61
def encrypt_using_upsert
  klass.upsert_all records.collect(&:attributes), update_only: klass.encrypted_attributes, record_timestamps: false
end
ids_in_the_same_track() click to toggle source
# File lib/mass_encryption/batch.rb, line 93
def ids_in_the_same_track
  klass.where("id >= ?", from_id).order(id: :asc).limit(offset).ids
end
last_track_id() click to toggle source
# File lib/mass_encryption/batch.rb, line 85
def last_track_id
  @last_track_id ||= ids_in_the_same_track.last
end
next_track_records() click to toggle source
# File lib/mass_encryption/batch.rb, line 97
def next_track_records
  klass.where("id >= ?", from_id).order(id: :asc).limit(size * tracks_count)
end
offset() click to toggle source
# File lib/mass_encryption/batch.rb, line 89
def offset
  track * size
end