Class: Promotion::Evolver
- Inherits:
-
Object
- Object
- Promotion::Evolver
- Defined in:
- lib/promotion/evolver.rb
Overview
The Evolver class evolves the database by executing migration scripts from the evolve folder of the project being promoted
This class may be invoked via promote or via evolve or devolve commands
Instance Method Summary collapse
-
#devolve ⇒ Object
Returns the database to an earlier schema version: - find all of the relevant schema migration files in the
devolve
folder - execute in sequence all migrations from the current version down to the target version - update the version file with the new version number. -
#evolve ⇒ Object
Starts the database evolution: - find all of the relevant schema migration files in the
evolve
folder - execute in sequence all migrations after the current version, updating the version file with the latest successful version number. -
#get_spec ⇒ Object
The deployment descriptor for an application should contain a single Database element in order to make use of the
evolve
command. -
#initialize(appname, evolve = true, targetVersion = nil) ⇒ Evolver
constructor
Creates a new Evolver.
-
#start ⇒ Object
Gets the current version from the version file and calls evolve or devolve as required.
Constructor Details
#initialize(appname, evolve = true, targetVersion = nil) ⇒ Evolver
Creates a new Evolver
9 10 11 12 13 14 15 16 17 18 |
# File 'lib/promotion/evolver.rb', line 9 def initialize(appname, evolve=true, targetVersion=nil) @appname = appname @evolve = (evolve == true) @target = targetVersion.to_i() @currentVersion = nil @spec = get_spec() db = @spec.elements["Database"] @dbms = db.text() @database = db.attributes["database"] || "" end |
Instance Method Details
#devolve ⇒ Object
Returns the database to an earlier schema version:
-
find all of the relevant schema migration files in the
devolve
folder -
execute in sequence all migrations from the current version down to the target version
-
update the version file with the new version number
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/promotion/evolver.rb', line 95 def devolve() $log.info("\n#{'_'*40}\nDevolving the database #{@database}\n") devolveFolder = File.("#{@appname}/devolve", Folders::Staging) Dir.chdir(devolveFolder) migrations = Dir["*.sql"].collect { |f| f.sub(".sql","").to_i() }.sort() migrations.reject! { |v| v > @currentVersion } migrations.reject! { |v| v <= @target } # after devolving we are at the previous version migrations.reverse! if @target < @currentVersion print("Devolving the database") else puts("Already at version #{@currentVersion}.") exit 0 end completed = @currentVersion migrations.each { |v| success = system("#{@dbms} #{@database} < #{v}.sql") if success $log.info("Devolved the database from version #{v}") completed = v else $log.error("Failed to devolve the database from version #{v}.") break end } return(completed-1) # after devolving we are at the previous version end |
#evolve ⇒ Object
Starts the database evolution:
-
find all of the relevant schema migration files in the
evolve
folder -
execute in sequence all migrations after the current version, updating the version file with the latest successful version number
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/promotion/evolver.rb', line 64 def evolve() $log.info("\n#{'_'*40}\nEvolving the database #{@database}\n") evolveFolder = File.("#{@appname}/evolve", Folders::Staging) Dir.chdir(evolveFolder) migrations = Dir["*.sql"].collect { |f| f.sub(".sql","").to_i() }.sort() migrations.reject! { |v| v <= @currentVersion } migrations.reject! { |v| v > @target } unless @target == 0 @target = migrations.last.to_i if @target <= @currentVersion puts("Already at version #{@currentVersion}.") exit 0 end completed = @currentVersion migrations.each { |v| success = system("#{@dbms} #{@database} < #{v}.sql") if success $log.info("Evolved the database to version #{v}") completed = v else $log.error("Failed to evolve the database to version #{v}.") break end } return(completed) end |
#get_spec ⇒ Object
The deployment descriptor for an application should contain a single Database element in order to make use of the evolve
command. SQLite3 also needs a database
attribute to specify the file to operate on. <Database>/usr/bin/mysql</Database> <Database database=“/var/myapp/myapp.db”>/usr/bin/sqlite3</Database>
25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/promotion/evolver.rb', line 25 def get_spec() appFolder = File.(@appname, Folders::Staging) Dir.chdir(appFolder) specfile = File.(Files::Spec, appFolder) unless File.exist?(specfile) puts("\nSpecification file #{specfile} does not exist.\n" ) exit 1 end doc = REXML::Document.new(File.new(specfile)) doc.root end |
#start ⇒ Object
Gets the current version from the version file and calls evolve or devolve as required
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/promotion/evolver.rb', line 38 def start() versionFilename = File.("@version.#{@appname}", Folders::Staging) if !File.exist?(versionFilename) puts("We expect a version file at #{versionFilename} containing a single line") puts("with the current version of the database (eg. 1001)") exit 1 end versionFile = File.new(versionFilename, 'r') @currentVersion = versionFile.gets.chomp().to_i() versionFile.close() completed = @currentVersion if @evolve completed = evolve() else completed = devolve() end versionFile = File.new(versionFilename, 'w') versionFile.puts(completed) versionFile.close() puts("Evolved the database to version #{completed} ") end |