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



70
71
72
73
74
75
76
77
78
# File 'lib/pg_migrate/migrator.rb', line 70

def execute_migration(name, filepath)
  @log.debug "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)



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/pg_migrate/migrator.rb', line 22

def migrate(manifest_path)
  @manifest_path = manifest_path

  if !@connection_hash[:pgconn].nil?
    @conn = @connection_hash[:pgconn]
  elsif !@connection_hash[:connstring].nil?
    @conn = PG::Connection.open(@connection_hash[:connstring])
  else
    @conn = PG::Connection.open(@connection_hash)
  end

  # 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()
end

#process_manifestObject

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



45
46
47
48
# File 'lib/pg_migrate/migrator.rb', line 45

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



64
65
66
67
# File 'lib/pg_migrate/migrator.rb', line 64

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



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/pg_migrate/migrator.rb', line 81

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_migrationsObject

run all necessary migrations



51
52
53
54
55
56
57
58
59
60
61
# File 'lib/pg_migrate/migrator.rb', line 51

def run_migrations

  # 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