pg_migrate 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- pg_migrate (0.1.0)
4
+ pg_migrate (0.1.1)
5
5
  logging (= 1.7.2)
6
6
  pg (= 0.14.0)
7
7
  thor (= 0.15.4)
@@ -8,7 +8,7 @@ module PgMigrate
8
8
  # takes a unprocessed manifest directory, and adds before/after headers to each file
9
9
  class Builder
10
10
 
11
- attr_accessor :manifest_reader, :sql_reader
11
+ attr_accessor :manifest_reader, :sql_reader, :loaded_manifest
12
12
 
13
13
  def initialize(manifest_reader, sql_reader)
14
14
  @log = Logging.logger[self]
@@ -21,7 +21,8 @@ module PgMigrate
21
21
  # input_dir is root path, contains file 'manifest' and 'migrations'
22
22
  # output_dir will have a manifest and migrations folder, but processed
23
23
  # force will create the output dir if needed, and *delete an existing directory* if it's in the way
24
- def build(input_dir, output_dir, options={:force=>true})
24
+ # test will run tests
25
+ def build(input_dir, output_dir, options={:force=>true, :test=>false})
25
26
  input_dir = File.expand_path(input_dir)
26
27
  output_dir = File.expand_path(output_dir)
27
28
 
@@ -75,13 +76,18 @@ module PgMigrate
75
76
  end
76
77
 
77
78
  # in order array of manifest declarations
78
- loaded_manifest = @manifest_reader.load_input_manifest(input_dir)
79
+ @loaded_manifest = @manifest_reader.load_input_manifest(input_dir)
79
80
  # hashed on migration name hash of manifest
80
81
 
81
82
  loaded_manifest_hash = @manifest_reader.hash_loaded_manifest(loaded_manifest)
82
83
  @manifest_reader.validate_migration_paths(input_dir, loaded_manifest)
83
84
 
84
85
  build_up(input_dir, output_dir, loaded_manifest_hash, loaded_manifest)
86
+
87
+ # ok we are done. time to test!
88
+ if options[:test]
89
+ test(output_dir, options)
90
+ end
85
91
  end
86
92
 
87
93
  def build_up(input_dir, output_dir, loaded_manifest_hash, loaded_manifest)
@@ -118,10 +124,13 @@ module PgMigrate
118
124
 
119
125
  # creates the 'pg_migrations table'
120
126
  def create_bootstrap_script(migration_out_path)
127
+ @log.debug "creating bootstrap script #{migration_out_path}"
121
128
  run_template("bootstrap.erb", binding, File.join(migration_out_path, BOOTSTRAP_FILENAME))
122
129
  end
123
130
 
124
131
  def create_wrapped_up_migration(migration_in_filepath, migration_out_filepath, migration_def, loaded_manifest)
132
+ @log.debug "securing migration #{migration_def.name}"
133
+
125
134
  builder_version="pg_migrate_ruby-#{PgMigrate::VERSION}"
126
135
  manifest_version=loaded_manifest[-1].ordinal
127
136
  migration_content = nil
@@ -164,10 +173,40 @@ module PgMigrate
164
173
 
165
174
  create_wrapped_up_migration(migration_in_path, migration_out_path, migration_def, loaded_manifest)
166
175
  else
176
+ @log.debug "copying non-sql file #{migration_in_path}"
167
177
  # if not a .sql file, just copy it over
168
178
  FileUtils.cp(migration_in_path, migration_out_path)
169
179
  end
170
180
  end
171
181
  end
182
+
183
+ def recreate_test_database(conn, test_db_name)
184
+ @log.debug "recreate test database #{test_db_name}"
185
+
186
+ conn.exec("drop database if exists #{test_db_name}")
187
+ conn.exec("create database #{test_db_name}")
188
+ end
189
+
190
+ def test(output_dir, test_options)
191
+
192
+ @log.info "testing..."
193
+
194
+ oobconn = Util::get_oob_conn(test_options)
195
+ target_dbname = Util::get_db_name(test_options)
196
+
197
+ run_manifests = []
198
+
199
+
200
+ recreate_test_database(oobconn, target_dbname)
201
+
202
+ conn = Util::get_conn(test_options)
203
+
204
+ migrator = Migrator.new(manifest_reader, sql_reader, :pgconn => conn)
205
+ migrator.migrate(output_dir)
206
+ conn.close
207
+
208
+ @log.info "test success"
209
+
210
+ end
172
211
  end
173
212
  end
@@ -78,6 +78,9 @@ module PgMigrate
78
78
  method_option :out, :aliases => "-o", :banner => "output directory", :desc => "where the processed migrations will be placed"
79
79
  method_option :force, :aliases => "-f", :type => :boolean, :banner => "overwrite out", :desc => "if specified, the out directory will be created before processing occurs, replacing any existing directory"
80
80
  method_option :verbose, :aliases => "-v", :type => :boolean, :banner => "verbose", :desc=> "set to raise verbosity"
81
+ method_option :test, :aliases => "-t", :default => false, :type => :boolean, :banner => "run tests", :desc => "run tests by creating a test database and executing migrations"
82
+ method_option :oob_connopts, :aliases => "-b",:default=> nil, :type => :hash, :banner => "out-of-band connection options", :desc => "this is a 'landing pad' database from which pg_migrate can execute 'create/drop' against the database specified by the connopts argument. database connection options used by gem 'pg': dbname|host|hostaddr|port|user|password|connection_timeout|options|sslmode|krbsrvname|gsslib|service"
83
+ method_option :connopts, :aliases => "-c", :default => nil, :type => :hash, :banner => "connection options", :desc => "database connection options used by gem 'pg': dbname|host|hostaddr|port|user|password|connection_timeout|options|sslmode|krbsrvname|gsslib|service"
81
84
 
82
85
  def build
83
86
  source = options[:source]
@@ -86,7 +89,7 @@ module PgMigrate
86
89
  source = @@packaged_source
87
90
  end
88
91
 
89
- method_defaults = {"force" => false, "verbose" => false}
92
+ method_defaults = {"force" => false, "verbose" => false, "test" => false}
90
93
  local_options = set_defaults_from_file(method_defaults, "build", source)
91
94
  local_options = local_options.merge(options)
92
95
 
@@ -97,10 +100,41 @@ module PgMigrate
97
100
  exit 1
98
101
  end
99
102
 
103
+ if local_options["test"].to_s == "true"
104
+ if !local_options["oob_connopts"]
105
+ puts "error: --oob_connopts not specified when test = true"
106
+ exit 1
107
+ else
108
+ # type safety; if string is found, convert to hash
109
+ local_options["oob_connopts"] = parse_to_hash(local_options["oob_connopts"])
110
+ end
111
+
112
+
113
+ if !local_options["connopts"]
114
+ puts "error: --connopts not specified when test = true"
115
+ exit 1
116
+ else
117
+ # type safety; if string is found, convert to hash
118
+ local_options["connopts"] = parse_to_hash(local_options["connopts"])
119
+ end
120
+
121
+ end
122
+
100
123
  manifest_reader = ManifestReader.new
101
124
  sql_reader = SqlReader.new
102
125
  builder = Builder.new(manifest_reader, sql_reader)
103
- builder.build(source, local_options["out"], :force => local_options["force"])
126
+
127
+ begin
128
+ builder.build(source, local_options["out"],
129
+ :force => local_options["force"],
130
+ :test => local_options["test"],
131
+ :oob_connopts => local_options["oob_connopts"],
132
+ :connopts => local_options["connopts"])
133
+ rescue PG::Error => pge
134
+ puts "test failure"
135
+ puts pge
136
+ end
137
+
104
138
  end
105
139
 
106
140
 
@@ -132,7 +166,7 @@ module PgMigrate
132
166
  exit 1
133
167
  end
134
168
  if !local_options["version"]
135
- puts "error: --version not specified"
169
+ puts "error: --version not specified"
136
170
  exit 1
137
171
  end
138
172
 
@@ -186,6 +220,18 @@ module PgMigrate
186
220
  return map
187
221
 
188
222
  end
223
+
224
+ def parse_to_hash(value)
225
+ hash = {}
226
+
227
+ bits = value.split()
228
+ bits.each do |bit|
229
+ key, value = bit.split(':',2)
230
+ hash[key] = value
231
+ end
232
+
233
+ return hash
234
+ end
189
235
  end
190
236
 
191
237
 
@@ -18,17 +18,10 @@ module PgMigrate
18
18
  # The manifest_path argument should point to your manifest
19
19
  # manifest_path = the directory containing your 'manifest' file, 'up' directory, 'down' directory, 'test' directory
20
20
  # this method will throw an exception if anything goes wrong (such as bad SQL in the migrations themselves)
21
-
22
21
  def migrate(manifest_path)
23
22
  @manifest_path = manifest_path
24
23
 
25
- if !@connection_hash[:pgconn].nil?
26
- @conn = @connection_hash[:pgconn]
27
- elsif !@connection_hash[:connstring].nil?
28
- @conn = PG::Connection.open(@connection_hash[:connstring])
29
- else
30
- @conn = PG::Connection.open(@connection_hash)
31
- end
24
+ @conn = Util::get_conn(@connection_hash)
32
25
 
33
26
  # this is used to record the version of the 'migrator' in the pg_migrate table
34
27
  @conn.exec("SET application_name = 'pg_migrate_ruby-#{PgMigrate::VERSION}'")
@@ -37,7 +30,7 @@ module PgMigrate
37
30
  process_manifest()
38
31
 
39
32
  # execute the migrations
40
- run_migrations()
33
+ run_migrations(@manifest)
41
34
  end
42
35
 
43
36
 
@@ -48,7 +41,7 @@ module PgMigrate
48
41
  end
49
42
 
50
43
  # run all necessary migrations
51
- def run_migrations
44
+ def run_migrations(manifest)
52
45
 
53
46
  # run bootstrap before user migrations to prepare database
54
47
  run_bootstrap
@@ -68,7 +61,7 @@ module PgMigrate
68
61
 
69
62
  # execute a single migration by loading it's statements from file, and then executing each
70
63
  def execute_migration(name, filepath)
71
- @log.debug "executing migration #{filepath}"
64
+ @log.info "executing migration #{filepath}"
72
65
 
73
66
  statements = @sql_reader.load_migration(filepath)
74
67
  if statements.length == 0
@@ -1,3 +1,3 @@
1
1
  module PgMigrate
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
data/lib/pg_migrate.rb CHANGED
@@ -11,6 +11,7 @@ require "pg_migrate/config_parser"
11
11
  require "pg_migrate/builder"
12
12
  require "pg_migrate/package"
13
13
  require "pg_migrate/command_line"
14
+ require "pg_migrate/util"
14
15
 
15
16
  # name of the manifest file
16
17
  MANIFEST_FILENAME = 'manifest'
@@ -27,6 +27,7 @@ describe CommandLine do
27
27
  props = Properties.new
28
28
  props['build.out'] = output_dir
29
29
  props['build.force'] = "true"
30
+ props['build.test'] = "false"
30
31
  #props['up.connopts'] = "dbname:pg_migrate_test host:localhost port:5432 user:postgres password:postgres"
31
32
 
32
33
  # and put that properties file in the input dir
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pg_migrate
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-07-29 00:00:00.000000000 Z
12
+ date: 2012-08-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: logging