Class: TDP::Engine

Inherits:
Object
  • Object
show all
Defined in:
lib/tdp.rb

Overview

Main class of the package.

Instance Method Summary collapse

Constructor Details

#initialize(db) ⇒ Engine

Creates a new Engine object.

db

must be one of:

  • instance of Sequel::Database class

  • database URL that can be passed to Sequel.connect()



326
327
328
329
# File 'lib/tdp.rb', line 326

def initialize(db)
  @dao = DAO.new(db)
  @patches = PatchSet.new
end

Instance Method Details

#<<(filename) ⇒ Object

Registers patch files in the engine.

filename

may be either a name of .sql file or a name

of directory (which would be recursively scanned for .sql files)



338
339
340
341
342
343
344
345
346
# File 'lib/tdp.rb', line 338

def <<(filename)
  if File.directory?(filename)
    Dir.foreach(filename) do |x|
      self << File.join(filename, x) unless x.start_with?('.')
    end
  elsif TDP.patch_file?(filename)
    @patches << Patch.new(filename)
  end
end

#bootstrapObject

Initializes database tables for keeping track of applied patches.



352
353
354
# File 'lib/tdp.rb', line 352

def bootstrap
  @dao.bootstrap
end

#planObject

Produces an ordered list of patches that need to be applied.

May raise MismatchError in case if signatures of any permanent patches that are present in the definition don’t match ones of the patches applied to the database.



363
364
365
366
367
368
369
370
371
# File 'lib/tdp.rb', line 363

def plan
  ref = @dao.applied_patches
  @patches.select do |patch|
    signature = ref[patch.name]
    next false if signature == patch.signature
    next true if signature.nil? || patch.volatile?
    raise MismatchError, patch
  end
end

#plan_renameObject

Produces an { old_name => new_name } hash for mass-renaming.



376
377
378
379
380
381
382
383
384
385
386
# File 'lib/tdp.rb', line 376

def plan_rename
  ref = @dao.applied_patches_inverse
  m = {}
  @patches.each do |patch|
    old_name = ref[patch.signature]
    raise NotAppliedError, patch if old_name.nil?
    raise DuplicateError, [patch.name, m[old_name]] if m.key?(old_name)
    m[old_name] = patch.name
  end
  m.select { |old_name, new_name| old_name != new_name }
end

#renameObject

Amends the data about applied patches after they were renamed (without content changes) in the configuration.



446
447
448
449
450
# File 'lib/tdp.rb', line 446

def rename
  plan_rename.each do |old_name, new_name|
    @dao.rename(old_name, new_name)
  end
end

#retrofitObject

Erases existing data about applied patches and replaces it with configured schema.



435
436
437
438
439
440
# File 'lib/tdp.rb', line 435

def retrofit
  @dao.erase
  @patches.each do |patch|
    @dao.register(patch)
  end
end

#upgradeObject

Applies all changes that need to be applied.



391
392
393
394
# File 'lib/tdp.rb', line 391

def upgrade
  validate_upgradable
  plan.each { |patch| @dao.apply(patch) }
end

#validate_compatibleObject

Validates that all patches are applied to the database.

May raise MismatchError, NotConfiguredError or NotAppliedError in case if there are any problems.



420
421
422
423
424
425
426
427
428
429
# File 'lib/tdp.rb', line 420

def validate_compatible
  validate_upgradable

  @patches.each do |patch|
    signature = @dao.patch_signature(patch.name)
    next if signature == patch.signature
    raise NotAppliedError, patch if signature.nil?
    raise MismatchError, patch
  end
end

#validate_upgradableObject

Validates that it is safe run upgrade the database. In particular, the following conditions must be met:

  • there is an .sql file for every patch that is marked as applied to database

  • every permanent patch has same signature as the corresponding .sql file.

May raise MismatchError or NotConfiguredError in case if those conditions aren’t met.



407
408
409
410
411
412
# File 'lib/tdp.rb', line 407

def validate_upgradable
  @dao.applied_patches.each_key do |name|
    raise NotConfiguredError, name unless @patches[name]
  end
  plan
end