Module: ColdStorage

Defined in:
lib/cold_storage.rb,
lib/cold_storage/run.rb,
lib/cold_storage/jobs.rb,
lib/cold_storage/model.rb,
lib/cold_storage/policy.rb,
lib/cold_storage/report.rb,
lib/cold_storage/logging.rb,
lib/cold_storage/railtie.rb,
lib/cold_storage/version.rb,
lib/cold_storage/archiver.rb,
lib/cold_storage/metadata.rb,
lib/cold_storage/registry.rb,
lib/cold_storage/restorer.rb,
lib/cold_storage/archivable.rb,
lib/cold_storage/row_reader.rb,
lib/cold_storage/archive_model.rb,
lib/cold_storage/configuration.rb,
lib/cold_storage/schema_mirror.rb,
lib/cold_storage/archive_record.rb,
lib/cold_storage/internal_schema.rb,
lib/cold_storage/association_tree.rb,
lib/generators/cold_storage/install/install_generator.rb

Overview

Moves rows that are past their retention window (or soft-deleted) out of the primary database and into a mirrored archive database.

class Payroll < ApplicationRecord
archivable after: 18.months, every: 1.month
end

See README.md for the full option list.

Defined Under Namespace

Modules: Archivable, ArchiveModel, Archived, AssociationTree, Generators, InternalSchema, Jobs, Logging, Model, Registry, RowReader Classes: ArchiveRecord, Archiver, Configuration, Metadata, Policy, Railtie, Report, Restorer, Run, SchemaMirror

Constant Summary collapse

Error =

Base class for every error raised by the gem.

Class.new(StandardError)
ConfigurationError =

Raised when the archive database is missing or misconfigured.

Class.new(Error)
NotArchivableError =

Raised when a model was never declared archivable.

Class.new(Error)
SchemaMissingError =

Raised when the archive database has no table for a model yet.

Class.new(Error)
InvalidPolicyError =

Raised when an archivable declaration is not usable.

Class.new(ArgumentError)
VERSION =
'0.1.0'

Class Method Summary collapse

Class Method Details

.archive(model, **options) ⇒ ColdStorage::Archiver::Result

Archives one model according to its policy.



81
82
83
# File 'lib/cold_storage.rb', line 81

def archive(model, **options)
  Archiver.new(model, **options).call
end

.archive_all(**options) ⇒ Array<ColdStorage::Archiver::Result>

Archives every registered model. Models whose every: window has not elapsed are skipped unless force: true.

Returns:



89
90
91
# File 'lib/cold_storage.rb', line 89

def archive_all(**options)
  models.map { |model| archive(model, **options) }
end

.archived_model(model) ⇒ Class

The archive-database counterpart of a model, for models that are not archivable themselves (a cascade child, say).

Returns:

  • (Class)


110
111
112
# File 'lib/cold_storage.rb', line 110

def archived_model(model)
  ArchiveModel.for(model)
end

.configColdStorage::Configuration



54
55
56
# File 'lib/cold_storage.rb', line 54

def config
  @config ||= Configuration.new
end

.configure {|config| ... } ⇒ Object

Yield Parameters:



59
60
61
62
# File 'lib/cold_storage.rb', line 59

def configure
  yield config
  config
end

.const_missing(name) ⇒ Object



56
57
58
59
60
# File 'lib/cold_storage/jobs.rb', line 56

def self.const_missing(name)
  return super unless Jobs::JOBS.include?(name) && Jobs.define!

  const_get(name)
end

.loggerLogger

Returns:

  • (Logger)


74
75
76
# File 'lib/cold_storage.rb', line 74

def logger
  config.logger ||= Logger.new($stdout)
end

.models(eager_load: true) ⇒ Array<Class>

Every model that called archivable, in declaration-independent order.

Parameters:

  • eager_load (Boolean) (defaults to: true)

    load the app's classes first so models that were never referenced in this process are still discovered.

Returns:

  • (Array<Class>)


69
70
71
# File 'lib/cold_storage.rb', line 69

def models(eager_load: true)
  Registry.models(eager_load: eager_load)
end

.report(**options) ⇒ String

Returns human readable status of every archivable model.

Returns:

  • (String)

    human readable status of every archivable model



130
131
132
# File 'lib/cold_storage.rb', line 130

def report(**options)
  Report.new(**options).to_s
end

.reset_config!Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



135
136
137
# File 'lib/cold_storage.rb', line 135

def reset_config!
  @config = Configuration.new
end

.restore(model, ids, **options) ⇒ Integer

Moves rows back from the archive database into the primary one.

ColdStorage.restore(Invoice, [1, 2])
ColdStorage.restore(Invoice, [1, 2], with: :all)
ColdStorage.restore(Invoice, Invoice.archived.where(year: 2019),
                     with: [:invoice_lines])

Parameters:

  • ids (Array, ActiveRecord::Relation)

Returns:

  • (Integer)

    number of restored rows, children included



102
103
104
# File 'lib/cold_storage.rb', line 102

def restore(model, ids, **options)
  Restorer.new(model, **options).call(ids)
end

.schema_drift(**options) ⇒ Array<ColdStorage::SchemaMirror::Change>

The changes sync_schema! would apply. Empty means the archive database is up to date.



125
126
127
# File 'lib/cold_storage.rb', line 125

def schema_drift(**options)
  SchemaMirror.new(**options).plan
end

.sync_schema!(**options) ⇒ Array<ColdStorage::SchemaMirror::Change>

Creates/updates the archive database tables for the archivable models.



117
118
119
# File 'lib/cold_storage.rb', line 117

def sync_schema!(**options)
  SchemaMirror.new(**options).sync!
end