Class: PgMigrate::Migrator

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

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(manifest_reader, sql_reader, options = {}) ⇒ Migrator

options = gem ‘pg’ connection_hash options, or connstring => dbname=test port=5432, or pgconn => PG::Connection object



8
9
10
11
12
13
14
15
# File 'lib/pg_migrate/migrator.rb', line 8

def initialize(manifest_reader, sql_reader, options = {})
  @log = Logging.logger[self]
  @connection_hash = options
  @manifest = nil
  @builder_version = nil
  @manifest_reader = manifest_reader
  @sql_reader = sql_reader
end

Instance Attribute Details

#connObject

Returns the value of attribute conn.



5
6
7
# File 'lib/pg_migrate/migrator.rb', line 5

def conn
  @conn
end

#connection_hashObject

Returns the value of attribute connection_hash.



5
6
7
# File 'lib/pg_migrate/migrator.rb', line 5

def connection_hash
  @connection_hash
end

#manifestObject

Returns the value of attribute manifest.



5
6
7
# File 'lib/pg_migrate/migrator.rb', line 5

def manifest
  @manifest
end

#manifest_pathObject

Returns the value of attribute manifest_path.



5
6
7
# File 'lib/pg_migrate/migrator.rb', line 5

def manifest_path
  @manifest_path
end

#manifest_readerObject

Returns the value of attribute manifest_reader.



5
6
7
# File 'lib/pg_migrate/migrator.rb', line 5

def manifest_reader
  @manifest_reader
end

#sql_readerObject

Returns the value of attribute sql_reader.



5
6
7
# File 'lib/pg_migrate/migrator.rb', line 5

def sql_reader
  @sql_reader
end

Instance Method Details

#execute_migration(name, filepath) ⇒ Object

execute a single migration by loading it’s statements from file, and then executing each



63
64
65
66
67
68
69
70
71
# File 'lib/pg_migrate/migrator.rb', line 63

def execute_migration(name, filepath)
  @log.info "executing migration #{filepath}"

  statements = @sql_reader.load_migration(filepath)
  if statements.length == 0
    raise 'no statements found in migration #{filepath}'
  end
  run_migration(name, statements)
end

#migrate(manifest_path) ⇒ Object

‘migrate’ attempt to migrate your database based on the contents of your built manifest The manifest_path argument should point to your manifest manifest_path = the directory containing your ‘manifest’ file, ‘up’ directory, ‘down’ directory, ‘test’ directory this method will throw an exception if anything goes wrong (such as bad SQL in the migrations themselves)



21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/pg_migrate/migrator.rb', line 21

def migrate(manifest_path)
  @manifest_path = manifest_path

  @conn = Util::get_conn(@connection_hash)

  # this is used to record the version of the 'migrator' in the pg_migrate table
  @conn.exec("SET application_name = 'pg_migrate_ruby-#{PgMigrate::VERSION}'")

  # load the manifest, and version of the builder that made it
  process_manifest()

  # execute the migrations
  run_migrations(@manifest)
end

#process_manifestObject

load the manifest’s migration declarations, and validate that each migration points to a real file



38
39
40
41
# File 'lib/pg_migrate/migrator.rb', line 38

def process_manifest
  @manifest, @builder_version = @manifest_reader.load_output_manifest(@manifest_path)
  @manifest_reader.validate_migration_paths(@manifest_path, @manifest)
end

#run_bootstrapObject

executes the bootstrap method



57
58
59
60
# File 'lib/pg_migrate/migrator.rb', line 57

def run_bootstrap
  bootstrap = File.join(@manifest_path, UP_DIRNAME, BOOTSTRAP_FILENAME)
  execute_migration('bootstrap.sql', bootstrap)
end

#run_migration(name, statements) ⇒ Object

execute all the statements of a single migration



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/pg_migrate/migrator.rb', line 74

def run_migration(name, statements)

  begin
    statements.each do |statement|
      conn.exec(statement).clear
    end
  rescue Exception => e
    # we make a special allowance for one exception; it just means this migration
    # has already occurred, and we should just treat it like a continue
    if e.message.index('pg_migrate: code=migration_exists').nil?
      conn.exec("ROLLBACK")
      raise e
    else
      conn.exec("ROLLBACK")
      @log.info "migration #{name} already run"
    end
  end
end

#run_migrations(manifest) ⇒ Object

run all necessary migrations



44
45
46
47
48
49
50
51
52
53
54
# File 'lib/pg_migrate/migrator.rb', line 44

def run_migrations(manifest)

  # run bootstrap before user migrations to prepare database
  run_bootstrap

  # loop through the manifest, executing migrations in turn
  manifest.each_with_index do |migration, index|
    execute_migration(migration.name, migration.filepath)
  end

end