Class: RocketJob::Jobs::ReEncrypt::RelationalJob

Inherits:
RocketJob::Job show all
Includes:
Batch
Defined in:
lib/rocket_job/jobs/re_encrypt/relational_job.rb

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Batch::IO

#download, #input, #output, #upload, #upload_arel, #upload_integer_range, #upload_integer_range_in_reverse_order, #upload_mongo_query, #upload_slice, #write_output

Methods included from Batch::Worker

#rocket_job_active_workers, #rocket_job_batch_callbacks, #rocket_job_batch_complete?, #rocket_job_batch_fail!, #rocket_job_batch_perform, #rocket_job_batch_run_after_callbacks, #rocket_job_batch_run_before_callbacks, #rocket_job_batch_throttled?, #rocket_job_perform_slice, #rocket_job_process_slice, #rocket_job_work, #work_first_slice

Methods included from Batch::StateMachine

#cleanup!, #pausable?

Methods included from Batch::Model

#compressed?, #encrypted?, #percent_complete, #status, #worker_count, #worker_names

Methods included from Plugins::Job::Throttle

#throttle_filter_class, #throttle_filter_id

Methods included from Plugins::Job::Worker

#fail_on_exception!, #perform_now, #rocket_job_active_workers, #rocket_job_work

Methods included from Plugins::Job::StateMachine

#pausable?

Methods included from Plugins::Job::Persistence

#reload

Methods included from Plugins::Job::Model

#as_json, #collect_nil_output?, #collect_output?, #duration, #expired?, #run_now!, #scheduled?, #scheduled_at, #seconds, #sleeping?, #status, #worker_count, #worker_names, #worker_on_server?

Class Method Details

.connectionObject

Returns a database connection.

Override this method to support other ways of obtaining a thread specific database connection.



106
107
108
# File 'lib/rocket_job/jobs/re_encrypt/relational_job.rb', line 106

def self.connection
  ActiveRecord::Base.connection
end

.start(**args) ⇒ Object

Re-encrypt all ‘encrypted_` columns in the relational database. Queues a Job for each table that needs re-encryption.



57
58
59
60
61
# File 'lib/rocket_job/jobs/re_encrypt/relational_job.rb', line 57

def self.start(**args)
  encrypted_columns.keys.collect do |table|
    create!(table_name: table, description: table, **args)
  end
end

Instance Method Details

#perform(range) ⇒ Object

Re-encrypt all encrypted columns for the named table. Does not use AR models since we do not have models for all tables.



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/rocket_job/jobs/re_encrypt/relational_job.rb', line 65

def perform(range)
  start_id, end_id = range

  columns = self.class.encrypted_columns[table_name]
  unless columns&.size&.positive?
    logger.error "No columns for table: #{table_name} from #{start_id} to #{end_id}"
    return
  end

  logger.info "Processing: #{table_name} from #{start_id} to #{end_id}"
  sql = "select id, #{columns.join(',')} from #{quoted_table_name} where id >= #{start_id} and id <= #{end_id}"

  # Use AR to fetch all the records
  self.class.connection.select_rows(sql).each do |row|
    row     = row.unshift(nil)
    index   = 1
    sql     = "update #{quoted_table_name} set "
    updates = []
    columns.collect do |column|
      index += 1
      value = row[index]
      # Prevent re-encryption
      unless value.blank?
        new_value = re_encrypt(value)
        updates << "#{column} = \"#{new_value}\"" if new_value != value
      end
    end
    if updates.size.positive?
      sql << updates.join(", ")
      sql << " where id=#{row[1]}"
      logger.trace sql
      self.class.connection.execute sql
    else
      logger.trace { "Skipping empty values #{table_name}:#{row[1]}" }
    end
  end
end