pg_migrate 0.1.11 → 0.1.12

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +34 -34
  3. data/.gitmodules +3 -3
  4. data/Gemfile +9 -9
  5. data/Gemfile.lock +39 -39
  6. data/LICENSE +21 -21
  7. data/README.md +33 -33
  8. data/Rakefile +2 -2
  9. data/bin/pg_migrate +6 -6
  10. data/lib/pg_migrate/builder.rb +214 -214
  11. data/lib/pg_migrate/command_line.rb +242 -242
  12. data/lib/pg_migrate/config_parser.rb +48 -48
  13. data/lib/pg_migrate/manifest_reader.rb +102 -102
  14. data/lib/pg_migrate/migration.rb +11 -11
  15. data/lib/pg_migrate/migrator.rb +94 -94
  16. data/lib/pg_migrate/package.rb +152 -152
  17. data/lib/pg_migrate/package_templates/Gemfile.erb +3 -3
  18. data/lib/pg_migrate/package_templates/bin/migrate.rb +9 -9
  19. data/lib/pg_migrate/package_templates/gemspec.erb +21 -21
  20. data/lib/pg_migrate/package_templates/lib/gem/version.rb +3 -3
  21. data/lib/pg_migrate/package_templates/lib/gem.rb +12 -12
  22. data/lib/pg_migrate/props.rb +19 -19
  23. data/lib/pg_migrate/sql_reader.rb +51 -51
  24. data/lib/pg_migrate/templates/bootstrap.erb +175 -175
  25. data/lib/pg_migrate/templates/up.erb +30 -30
  26. data/lib/pg_migrate/util.rb +73 -73
  27. data/lib/pg_migrate/version.rb +3 -3
  28. data/lib/pg_migrate.rb +40 -40
  29. data/pg_migrate.gemspec +29 -29
  30. data/spec/database.yml +8 -8
  31. data/spec/pg_migrate/builder_spec.rb +113 -113
  32. data/spec/pg_migrate/command_line_spec.rb +53 -53
  33. data/spec/pg_migrate/config_parser_spec.rb +18 -18
  34. data/spec/pg_migrate/db_utility.rb +73 -73
  35. data/spec/pg_migrate/input_manifests/single_manifest/manifest +3 -3
  36. data/spec/pg_migrate/input_manifests/single_manifest/up/single1.sql +29 -29
  37. data/spec/pg_migrate/manifest_reader_spec.rb +19 -19
  38. data/spec/pg_migrate/migrator_spec.rb +68 -68
  39. data/spec/pg_migrate/package_spec.rb +38 -38
  40. data/spec/pg_migrate/sql_reader_spec.rb +21 -21
  41. data/spec/spec_helper.rb +15 -15
  42. metadata +5 -5
@@ -1,103 +1,103 @@
1
- require 'pathname'
2
-
3
- module PgMigrate
4
- class ManifestReader
5
-
6
- def initialize
7
- @log = Logging.logger[self]
8
- end
9
-
10
- # returns array of migration paths
11
- def load_input_manifest(manifest_path)
12
- manifest, version = load_manifest(manifest_path, false)
13
- return manifest
14
- end
15
-
16
- # returns [array of migration paths, version]
17
- def load_output_manifest(manifest_path)
18
- return load_manifest(manifest_path, true)
19
- end
20
-
21
-
22
- # verify that the migration files exist
23
- def validate_migration_paths(manifest_path, manifest)
24
- # each item in the manifest should be a valid file
25
- manifest.each do |item|
26
- item_path = build_migration_path(manifest_path, item.name)
27
- if !Pathname.new(item_path).exist?
28
- raise "manifest reference #{item.name} does not exist at path #{item_path}"
29
- end
30
- end
31
- end
32
-
33
- # construct a migration file path location based on the manifest basedir and the name of the migration
34
- def build_migration_path(manifest_path, migration_name)
35
- File.join(manifest_path, UP_DIRNAME, "#{migration_name}")
36
- end
37
-
38
- def hash_loaded_manifest(loaded_manifest)
39
- hash = {}
40
- loaded_manifest.each do |manifest|
41
- hash[manifest.name] = manifest
42
- end
43
- return hash
44
- end
45
-
46
- # read in the manifest, saving each migration declaration in order as they are found
47
- private
48
- def load_manifest(manifest_path, is_output)
49
-
50
- manifest = []
51
- version = nil
52
-
53
- manifest_filepath = File.join(manifest_path, MANIFEST_FILENAME)
54
-
55
- @log.debug "loading manifest from #{manifest_filepath}"
56
-
57
- # there should be a file called 'manifest' at this location
58
- if !FileTest::exist?(manifest_filepath)
59
- raise "ManifestReader: code=unloadable_manifest: manifest not found at #{manifest_filepath}"
60
- end
61
-
62
- manifest_lines = IO.readlines(manifest_filepath)
63
-
64
- ordinal = 0
65
- manifest_lines.each_with_index do |line, index|
66
- migration_name = line.strip
67
-
68
- @log.debug "processing line:#{index} #{line}"
69
-
70
- # output files must have a version header as 1st line o file
71
- if is_output
72
- if index == 0
73
- # the first line must be the version comment. if not, error out.
74
- if migration_name.index(BUILDER_VERSION_HEADER) == 0 && migration_name.length > BUILDER_VERSION_HEADER.length
75
- version = migration_name[BUILDER_VERSION_HEADER.length..-1]
76
- @log.debug "manifest has builder_version #{version}"
77
- else
78
- raise "manifest invalid: missing/malformed version. expecting '# pg_migrate-VERSION' to begin first line '#{line}' of manifest file: '#{manifest_filepath}'"
79
- end
80
- end
81
- end
82
-
83
- # ignore comments
84
- if migration_name.empty? or migration_name.start_with?('#')
85
- # ignored!
86
- else
87
- @log.debug "adding migration #{migration_name} with ordinal #{ordinal}"
88
- manifest.push(Migration.new(migration_name, ordinal, build_migration_path(manifest_path, migration_name)))
89
- ordinal += 1
90
- end
91
-
92
- # the logic above wouldn't get upset with an empty manifest
93
- if is_output
94
- if version.nil?
95
- raise "manifest invalid: empty"
96
- end
97
- end
98
- end
99
- return manifest, version
100
- end
101
-
102
- end
1
+ require 'pathname'
2
+
3
+ module PgMigrate
4
+ class ManifestReader
5
+
6
+ def initialize
7
+ @log = Logging.logger[self]
8
+ end
9
+
10
+ # returns array of migration paths
11
+ def load_input_manifest(manifest_path)
12
+ manifest, version = load_manifest(manifest_path, false)
13
+ return manifest
14
+ end
15
+
16
+ # returns [array of migration paths, version]
17
+ def load_output_manifest(manifest_path)
18
+ return load_manifest(manifest_path, true)
19
+ end
20
+
21
+
22
+ # verify that the migration files exist
23
+ def validate_migration_paths(manifest_path, manifest)
24
+ # each item in the manifest should be a valid file
25
+ manifest.each do |item|
26
+ item_path = build_migration_path(manifest_path, item.name)
27
+ if !Pathname.new(item_path).exist?
28
+ raise "manifest reference #{item.name} does not exist at path #{item_path}"
29
+ end
30
+ end
31
+ end
32
+
33
+ # construct a migration file path location based on the manifest basedir and the name of the migration
34
+ def build_migration_path(manifest_path, migration_name)
35
+ File.join(manifest_path, UP_DIRNAME, "#{migration_name}")
36
+ end
37
+
38
+ def hash_loaded_manifest(loaded_manifest)
39
+ hash = {}
40
+ loaded_manifest.each do |manifest|
41
+ hash[manifest.name] = manifest
42
+ end
43
+ return hash
44
+ end
45
+
46
+ # read in the manifest, saving each migration declaration in order as they are found
47
+ private
48
+ def load_manifest(manifest_path, is_output)
49
+
50
+ manifest = []
51
+ version = nil
52
+
53
+ manifest_filepath = File.join(manifest_path, MANIFEST_FILENAME)
54
+
55
+ @log.debug "loading manifest from #{manifest_filepath}"
56
+
57
+ # there should be a file called 'manifest' at this location
58
+ if !FileTest::exist?(manifest_filepath)
59
+ raise "ManifestReader: code=unloadable_manifest: manifest not found at #{manifest_filepath}"
60
+ end
61
+
62
+ manifest_lines = IO.readlines(manifest_filepath)
63
+
64
+ ordinal = 0
65
+ manifest_lines.each_with_index do |line, index|
66
+ migration_name = line.strip
67
+
68
+ @log.debug "processing line:#{index} #{line}"
69
+
70
+ # output files must have a version header as 1st line o file
71
+ if is_output
72
+ if index == 0
73
+ # the first line must be the version comment. if not, error out.
74
+ if migration_name.index(BUILDER_VERSION_HEADER) == 0 && migration_name.length > BUILDER_VERSION_HEADER.length
75
+ version = migration_name[BUILDER_VERSION_HEADER.length..-1]
76
+ @log.debug "manifest has builder_version #{version}"
77
+ else
78
+ raise "manifest invalid: missing/malformed version. expecting '# pg_migrate-VERSION' to begin first line '#{line}' of manifest file: '#{manifest_filepath}'"
79
+ end
80
+ end
81
+ end
82
+
83
+ # ignore comments
84
+ if migration_name.empty? or migration_name.start_with?('#')
85
+ # ignored!
86
+ else
87
+ @log.debug "adding migration #{migration_name} with ordinal #{ordinal}"
88
+ manifest.push(Migration.new(migration_name, ordinal, build_migration_path(manifest_path, migration_name)))
89
+ ordinal += 1
90
+ end
91
+
92
+ # the logic above wouldn't get upset with an empty manifest
93
+ if is_output
94
+ if version.nil?
95
+ raise "manifest invalid: empty"
96
+ end
97
+ end
98
+ end
99
+ return manifest, version
100
+ end
101
+
102
+ end
103
103
  end
@@ -1,12 +1,12 @@
1
- module PgMigrate
2
- class Migration
3
- attr_accessor :name, :ordinal, :created, :production, :filepath
4
-
5
- def initialize(name, ordinal, filepath)
6
- @name = name
7
- @ordinal = ordinal
8
- @filepath = filepath
9
- end
10
-
11
- end
1
+ module PgMigrate
2
+ class Migration
3
+ attr_accessor :name, :ordinal, :created, :production, :filepath
4
+
5
+ def initialize(name, ordinal, filepath)
6
+ @name = name
7
+ @ordinal = ordinal
8
+ @filepath = filepath
9
+ end
10
+
11
+ end
12
12
  end
@@ -1,94 +1,94 @@
1
- module PgMigrate
2
-
3
- class Migrator
4
-
5
- attr_accessor :conn, :connection_hash, :manifest_path, :manifest, :manifest_reader, :sql_reader
6
-
7
- # options = gem 'pg' connection_hash options, or connstring => dbname=test port=5432, or pgconn => PG::Connection object
8
- def initialize(manifest_reader, sql_reader, options = {})
9
- @log = Logging.logger[self]
10
- @connection_hash = options
11
- @manifest = nil
12
- @builder_version = nil
13
- @manifest_reader = manifest_reader
14
- @sql_reader = sql_reader
15
- end
16
-
17
- # 'migrate' attempt to migrate your database based on the contents of your built manifest
18
- # The manifest_path argument should point to your manifest
19
- # manifest_path = the directory containing your 'manifest' file, 'up' directory, 'down' directory, 'test' directory
20
- # this method will throw an exception if anything goes wrong (such as bad SQL in the migrations themselves)
21
- def migrate(manifest_path)
22
- @manifest_path = manifest_path
23
-
24
- @conn = Util::get_conn(@connection_hash)
25
-
26
- # this is used to record the version of the 'migrator' in the pg_migrate table
27
- @conn.exec("SET application_name = 'pg_migrate_ruby-#{PgMigrate::VERSION}'")
28
-
29
- # load the manifest, and version of the builder that made it
30
- process_manifest()
31
-
32
- # execute the migrations
33
- run_migrations(@manifest)
34
- end
35
-
36
-
37
- # load the manifest's migration declarations, and validate that each migration points to a real file
38
- def process_manifest
39
- @manifest, @builder_version = @manifest_reader.load_output_manifest(@manifest_path)
40
- @manifest_reader.validate_migration_paths(@manifest_path, @manifest)
41
- end
42
-
43
- # run all necessary migrations
44
- def run_migrations(manifest)
45
-
46
- # run bootstrap before user migrations to prepare database
47
- run_bootstrap
48
-
49
- # loop through the manifest, executing migrations in turn
50
- manifest.each_with_index do |migration, index|
51
- execute_migration(migration.name, migration.filepath)
52
- end
53
-
54
- end
55
-
56
- # executes the bootstrap method
57
- def run_bootstrap
58
- bootstrap = File.join(@manifest_path, UP_DIRNAME, BOOTSTRAP_FILENAME)
59
- execute_migration('bootstrap.sql', bootstrap)
60
- end
61
-
62
- # execute a single migration by loading it's statements from file, and then executing each
63
- def execute_migration(name, filepath)
64
- @log.info "executing migration #{filepath}"
65
-
66
- statements = @sql_reader.load_migration(filepath)
67
- if statements.length == 0
68
- raise 'no statements found in migration #{filepath}'
69
- end
70
- run_migration(name, statements)
71
- end
72
-
73
- # execute all the statements of a single migration
74
- def run_migration(name, statements)
75
-
76
- begin
77
- statements.each do |statement|
78
- conn.exec(statement).clear
79
- end
80
- rescue Exception => e
81
- # we make a special allowance for one exception; it just means this migration
82
- # has already occurred, and we should just treat it like a continue
83
- if e.message.index('pg_migrate: code=migration_exists').nil?
84
- conn.exec("ROLLBACK")
85
- raise e
86
- else
87
- conn.exec("ROLLBACK")
88
- @log.info "migration #{name} already run"
89
- end
90
- end
91
- end
92
- end
93
- end
94
-
1
+ module PgMigrate
2
+
3
+ class Migrator
4
+
5
+ attr_accessor :conn, :connection_hash, :manifest_path, :manifest, :manifest_reader, :sql_reader
6
+
7
+ # options = gem 'pg' connection_hash options, or connstring => dbname=test port=5432, or pgconn => PG::Connection object
8
+ def initialize(manifest_reader, sql_reader, options = {})
9
+ @log = Logging.logger[self]
10
+ @connection_hash = options
11
+ @manifest = nil
12
+ @builder_version = nil
13
+ @manifest_reader = manifest_reader
14
+ @sql_reader = sql_reader
15
+ end
16
+
17
+ # 'migrate' attempt to migrate your database based on the contents of your built manifest
18
+ # The manifest_path argument should point to your manifest
19
+ # manifest_path = the directory containing your 'manifest' file, 'up' directory, 'down' directory, 'test' directory
20
+ # this method will throw an exception if anything goes wrong (such as bad SQL in the migrations themselves)
21
+ def migrate(manifest_path)
22
+ @manifest_path = manifest_path
23
+
24
+ @conn = Util::get_conn(@connection_hash)
25
+
26
+ # this is used to record the version of the 'migrator' in the pg_migrate table
27
+ @conn.exec("SET application_name = 'pg_migrate_ruby-#{PgMigrate::VERSION}'")
28
+
29
+ # load the manifest, and version of the builder that made it
30
+ process_manifest()
31
+
32
+ # execute the migrations
33
+ run_migrations(@manifest)
34
+ end
35
+
36
+
37
+ # load the manifest's migration declarations, and validate that each migration points to a real file
38
+ def process_manifest
39
+ @manifest, @builder_version = @manifest_reader.load_output_manifest(@manifest_path)
40
+ @manifest_reader.validate_migration_paths(@manifest_path, @manifest)
41
+ end
42
+
43
+ # run all necessary migrations
44
+ def run_migrations(manifest)
45
+
46
+ # run bootstrap before user migrations to prepare database
47
+ run_bootstrap
48
+
49
+ # loop through the manifest, executing migrations in turn
50
+ manifest.each_with_index do |migration, index|
51
+ execute_migration(migration.name, migration.filepath)
52
+ end
53
+
54
+ end
55
+
56
+ # executes the bootstrap method
57
+ def run_bootstrap
58
+ bootstrap = File.join(@manifest_path, UP_DIRNAME, BOOTSTRAP_FILENAME)
59
+ execute_migration('bootstrap.sql', bootstrap)
60
+ end
61
+
62
+ # execute a single migration by loading it's statements from file, and then executing each
63
+ def execute_migration(name, filepath)
64
+ @log.info "executing migration #{filepath}"
65
+
66
+ statements = @sql_reader.load_migration(filepath)
67
+ if statements.length == 0
68
+ raise 'no statements found in migration #{filepath}'
69
+ end
70
+ run_migration(name, statements)
71
+ end
72
+
73
+ # execute all the statements of a single migration
74
+ def run_migration(name, statements)
75
+
76
+ begin
77
+ statements.each do |statement|
78
+ conn.exec(statement).clear
79
+ end
80
+ rescue Exception => e
81
+ # we make a special allowance for one exception; it just means this migration
82
+ # has already occurred, and we should just treat it like a continue
83
+ if e.message.index('pg_migrate: code=migration_exists').nil?
84
+ conn.exec("ROLLBACK")
85
+ raise e
86
+ else
87
+ conn.exec("ROLLBACK")
88
+ @log.info "migration #{name} already run"
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
94
+