xmigra 1.2.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3e69aae7f431f58d88125bfc0a31adb4a0f3b76c
4
- data.tar.gz: 65f872a4d23fd7515bf6231c636c0f10725effc7
3
+ metadata.gz: 5e70e491aa62e8fdf597baa7794b6c342ebb074d
4
+ data.tar.gz: 6d95f99d62ca23e9fb0f801dc37e0eaca2656cd0
5
5
  SHA512:
6
- metadata.gz: 299d09f45384c3dc16473c59e6d2494583c8486d776a3edef6ab4123e2245374e4cbe13472b73c013f9c82081f44fdef0a242b6048f694d666f2b5102b6a988d
7
- data.tar.gz: 5016ef96078d289add80ec678ca6a5e989fcaac0a9dc4fd30ce186c0fc7e766ab22c00c752f5f62c0c11ccdf6621b808d920709792b2dae8d0df774e3e61c158
6
+ metadata.gz: ddf810521f87c7ecf49c5aef49d8f51ce913c9e7ae6b0bb3ba14395560d965c9ff538ebd80872b97c1870e986f09e7f523e58054caf1b2387b80a44be4558ad5
7
+ data.tar.gz: 54aea5341db82a73aa972f6ad6e27f11a9c24780d5f83bd146f6c4c25b9cc1376aa99081177ddb14310720b0cb68081c1a4fa2d1fd67b91fa1dc961bad43f670
@@ -12,6 +12,8 @@ module XMigra
12
12
  $/ix
13
13
  STATISTICS_FILE = 'statistics-objects.yaml'
14
14
 
15
+ ID_COLLATION = 'Latin1_General_CS_AS'
16
+
15
17
  class StatisticsObject
16
18
  def initialize(name, params)
17
19
  (@name = name.dup).freeze
@@ -153,7 +155,7 @@ IF NOT EXISTS (
153
155
  )
154
156
  BEGIN
155
157
  CREATE TABLE [xmigra].[applied] (
156
- [MigrationID] nvarchar(80) NOT NULL,
158
+ [MigrationID] nvarchar(80) COLLATE #{ID_COLLATION} NOT NULL,
157
159
  [ApplicationOrder] int IDENTITY(1,1) NOT NULL,
158
160
  [VersionBridgeMark] bit NOT NULL,
159
161
  [Description] nvarchar(max) NOT NULL,
@@ -171,6 +173,45 @@ BEGIN
171
173
  END;
172
174
  GO
173
175
 
176
+ IF NOT EXISTS (
177
+ SELECT * FROM sys.columns
178
+ WHERE object_id = OBJECT_ID(N'[xmigra].[applied]')
179
+ AND name = N'MigrationID'
180
+ AND collation_name = N'#{ID_COLLATION}'
181
+ )
182
+ BEGIN
183
+ ALTER TABLE xmigra.applied DROP CONSTRAINT PK_version;
184
+ ALTER TABLE xmigra.applied ALTER COLUMN [MigrationID] nvarchar(80) COLLATE Latin1_General_CS_AS NOT NULL;
185
+ ALTER TABLE xmigra.applied ADD CONSTRAINT PK_version PRIMARY KEY ([MigrationID] ASC) WITH (
186
+ PAD_INDEX = OFF,
187
+ STATISTICS_NORECOMPUTE = OFF,
188
+ IGNORE_DUP_KEY = OFF,
189
+ ALLOW_ROW_LOCKS = ON,
190
+ ALLOW_PAGE_LOCKS = ON
191
+ ) ON [PRIMARY];
192
+ END;
193
+
194
+ IF NOT EXISTS (
195
+ SELECT * FROM sys.objects
196
+ WHERE object_id = OBJECT_ID(N'[xmigra].[previous_states]')
197
+ AND type IN (N'U')
198
+ )
199
+ BEGIN
200
+ CREATE TABLE [xmigra].[previous_states] (
201
+ [Changed] datetime NOT NULL,
202
+ [MigrationApplicationOrder] int NOT NULL,
203
+ [FromMigrationID] nvarchar(80) COLLATE #{ID_COLLATION},
204
+ [ToRangeStartMigrationID] nvarchar(80) COLLATE #{ID_COLLATION} NOT NULL,
205
+ [ToRangeEndMigrationID] nvarchar(80) COLLATE #{ID_COLLATION} NOT NULL,
206
+
207
+ CONSTRAINT [PK_previous_states] PRIMARY KEY CLUSTERED (
208
+ [Changed] ASC,
209
+ [MigrationApplicationOrder] ASC
210
+ )
211
+ );
212
+ END;
213
+ GO
214
+
174
215
  IF NOT EXISTS (
175
216
  SELECT * FROM sys.objects
176
217
  WHERE object_id = OBJECT_ID(N'[xmigra].[DF_version_VersionBridgeMark]')
@@ -244,6 +285,30 @@ BEGIN
244
285
  [CompletesMigration] nvarchar(80) NULL
245
286
  ) ON [PRIMARY];
246
287
  END;
288
+
289
+ IF EXISTS (
290
+ SELECT * FROM sys.objects
291
+ WHERE object_id = OBJECT_ID(N'[xmigra].[last_applied_migrations]')
292
+ AND type IN (N'V')
293
+ )
294
+ BEGIN
295
+ DROP VIEW [xmigra].[last_applied_migrations];
296
+ END;
297
+ GO
298
+
299
+ CREATE VIEW [xmigra].[last_applied_migrations] AS
300
+ SELECT
301
+ ROW_NUMBER() OVER (ORDER BY a.[ApplicationOrder] DESC) AS [RevertOrder],
302
+ a.[Description]
303
+ FROM
304
+ [xmigra].[applied] a
305
+ WHERE
306
+ a.[ApplicationOrder] > COALESCE((
307
+ SELECT TOP (1) ps.[MigrationApplicationOrder]
308
+ FROM [xmigra].[previous_states] ps
309
+ JOIN [xmigra].[applied] a2 ON ps.[ToRangeStartMigrationID] = a2.[MigrationID]
310
+ ORDER BY ps.[Changed] DESC
311
+ ), 0);
247
312
  END_OF_SQL
248
313
  end
249
314
 
@@ -260,7 +325,7 @@ END;
260
325
  GO
261
326
 
262
327
  CREATE TABLE [xmigra].[migrations] (
263
- [MigrationID] nvarchar(80) NOT NULL,
328
+ [MigrationID] nvarchar(80) COLLATE #{ID_COLLATION} NOT NULL,
264
329
  [ApplicationOrder] int NOT NULL,
265
330
  [Description] ntext NOT NULL,
266
331
  [Install] bit NOT NULL DEFAULT(0)
@@ -472,6 +537,38 @@ ELSE BEGIN
472
537
  )
473
538
  AND [ApplicationOrder] > @BridgePoint;
474
539
  END;
540
+
541
+ INSERT INTO [xmigra].[previous_states] (
542
+ [Changed],
543
+ [MigrationApplicationOrder],
544
+ [FromMigrationID],
545
+ [ToRangeStartMigrationID],
546
+ [ToRangeEndMigrationID]
547
+ )
548
+ SELECT TOP (1)
549
+ CURRENT_TIMESTAMP,
550
+ -- Application order of last installed migration --
551
+ COALESCE(
552
+ (
553
+ SELECT TOP(1) [ApplicationOrder] FROM [xmigra].[applied]
554
+ ORDER BY [ApplicationOrder] DESC
555
+ ),
556
+ 0
557
+ ),
558
+ ( -- Last installed migration --
559
+ SELECT TOP (1) [MigrationID]
560
+ FROM [xmigra].[applied]
561
+ ORDER BY [ApplicationOrder] DESC
562
+ ),
563
+ m.[MigrationID],
564
+ ( -- Last migration to install --
565
+ SELECT TOP(1) [MigrationID] FROM [xmigra].[migrations]
566
+ WHERE [Install] <> 0
567
+ ORDER BY [ApplicationOrder] DESC
568
+ )
569
+ FROM [xmigra].[migrations] m
570
+ WHERE m.[Install] <> 0
571
+ ORDER BY m.[ApplicationOrder] ASC;
475
572
  END_OF_SQL
476
573
  end
477
574
 
@@ -885,6 +982,10 @@ END;
885
982
  end.join("\n"))
886
983
  end
887
984
 
985
+ def reversion_tracking_sql
986
+ "DELETE FROM [xmigra].[applied] WHERE [MigrationID] = '#{id}';\n"
987
+ end
988
+
888
989
  def each_batch(sql)
889
990
  current_batch_lines = []
890
991
  sql.each_line do |line|
@@ -111,6 +111,24 @@ module XMigra
111
111
  );
112
112
  END IF;
113
113
 
114
+ IF NOT EXISTS(
115
+ SELECT * FROM information_schema.tables
116
+ WHERE table_schema = 'xmigra' AND table_name = 'previous_states'
117
+ ) THEN
118
+ CREATE TABLE xmigra.previous_states (
119
+ "Changed" timestamp NOT NULL,
120
+ "MigrationApplicationOrder" int NOT NULL,
121
+ "FromMigrationID" varchar(80),
122
+ "ToRangeStartMigrationID" varchar(80) NOT NULL,
123
+ "ToRangeEndMigrationID" varchar(80) NOT NULL,
124
+
125
+ CONSTRAINT PK_previous_states PRIMARY KEY (
126
+ "Changed",
127
+ "MigrationApplicationOrder"
128
+ )
129
+ );
130
+ END IF;
131
+
114
132
  IF NOT EXISTS(
115
133
  SELECT * FROM information_schema.tables
116
134
  WHERE table_schema = 'xmigra' AND table_name = 'access_objects'
@@ -145,6 +163,26 @@ module XMigra
145
163
  );
146
164
  END IF;
147
165
 
166
+ IF NOT EXISTS(
167
+ SELECT * FROM information_schema.views
168
+ WHERE table_schema = 'xmigra' and table_name = 'last_applied_migrations'
169
+ ) THEN
170
+ CREATE VIEW xmigra.last_applied_migrations AS
171
+ SELECT
172
+ row_number() OVER (ORDER BY a."ApplicationOrder" DESC) AS "RevertOrder",
173
+ a."Description"
174
+ FROM
175
+ xmigra.applied a
176
+ WHERE
177
+ a."ApplicationOrder" > COALESCE((
178
+ SELECT ps."MigrationApplicationOrder"
179
+ FROM xmigra.previous_states ps
180
+ JOIN xmigra.applied a2 ON ps."ToRangeStartMigrationID" = a2."MigrationID"
181
+ ORDER BY ps."Changed" DESC
182
+ LIMIT 1
183
+ ), 0);
184
+ END IF;
185
+
148
186
  RAISE NOTICE ' done';
149
187
  }
150
188
  end
@@ -292,6 +330,40 @@ module XMigra
292
330
  );
293
331
  END IF;
294
332
 
333
+ INSERT INTO xmigra.previous_states (
334
+ "Changed",
335
+ "MigrationApplicationOrder",
336
+ "FromMigrationID",
337
+ "ToRangeStartMigrationID",
338
+ "ToRangeEndMigrationID"
339
+ )
340
+ SELECT
341
+ CURRENT_TIMESTAMP,
342
+ -- Application order of last installed migration --
343
+ COALESCE(
344
+ (
345
+ SELECT "ApplicationOrder" FROM xmigra.applied
346
+ ORDER BY "ApplicationOrder" DESC
347
+ ),
348
+ 0
349
+ ),
350
+ ( -- Last installed migration --
351
+ SELECT "MigrationID" FROM xmigra.applied
352
+ ORDER BY "ApplicationOrder" DESC
353
+ LIMIT 1
354
+ ),
355
+ m."MigrationID",
356
+ ( -- Last migration to install --
357
+ SELECT "MigrationID" FROM temp$xmigra_migrations
358
+ WHERE "Install"
359
+ ORDER BY "ApplicationOrder" DESC
360
+ LIMIT 1
361
+ )
362
+ FROM temp$xmigra_migrations m
363
+ WHERE "Install"
364
+ ORDER BY "ApplicationOrder" ASC
365
+ LIMIT 1;
366
+
295
367
  RAISE NOTICE ' done';
296
368
  })
297
369
  end
@@ -490,6 +562,10 @@ module XMigra
490
562
  }
491
563
  end
492
564
 
565
+ def reversion_tracking_sql
566
+ %Q{DELETE FROM xmigra.applied WHERE "MigrationID" = '#{id}';\n}
567
+ end
568
+
493
569
  def check_existence_sql(for_existence, error_message)
494
570
  error_message_literal = PgSQLSpecifics.string_literal sprintf(error_message, quoted_name)
495
571
 
@@ -591,7 +667,7 @@ module XMigra
591
667
  DELETE FROM xmigra.applied WHERE "MigrationID" = CompletedMigration.applied;
592
668
 
593
669
  INSERT INTO xmigra.applied ("MigrationID", "VersionBridgeMark", "Description")
594
- VALUE (CompletedMigration.applied, TRUE, 'Branch upgrade from branch ' || CompletedMigration.old_branch || '.');
670
+ VALUES (CompletedMigration.applied, TRUE, 'Branch upgrade from branch ' || CompletedMigration.old_branch || '.');
595
671
 
596
672
  RAISE NOTICE ' done';
597
673
  END IF;
@@ -1,3 +1,5 @@
1
+ require 'pathname'
2
+ require 'xmigra/revert_file'
1
3
 
2
4
  module XMigra
3
5
  class Migration
@@ -18,6 +20,15 @@ module XMigra
18
20
  attr_reader :id, :follows, :sql, :description, :changes
19
21
  attr_accessor :file_path
20
22
 
23
+ def schema_dir
24
+ Pathname(file_path).dirname.join('..')
25
+ end
26
+
27
+ def reversion
28
+ result = RevertFile.new(self)
29
+ return result if result.exist?
30
+ end
31
+
21
32
  class << self
22
33
  def id_from_filename(fname)
23
34
  XMigra.secure_digest(fname.upcase) # Base64 encoded digest
@@ -184,7 +184,7 @@ END_OF_HELP
184
184
 
185
185
  def output_to(fpath_or_nil)
186
186
  if fpath_or_nil.nil?
187
- yield(STDOUT)
187
+ yield($stdout)
188
188
  else
189
189
  File.open(fpath_or_nil, "w") do |stream|
190
190
  yield(stream)
@@ -457,6 +457,7 @@ system shall be targeted for the generation of scripts. Currently the
457
457
  supported values are:
458
458
 
459
459
  - Microsoft SQL Server
460
+ - PostgreSQL
460
461
 
461
462
  Each system can also have sub-settings that modify the generated scripts.
462
463
 
@@ -671,6 +672,36 @@ END_OF_HELP
671
672
  end
672
673
  end
673
674
 
675
+ subcommand 'reversions', "Generate a script file containing reversions" do |argv|
676
+ args, options = command_line(argv, {:outfile=>true},
677
+ :help=> <<END_OF_HELP)
678
+ This command generates a script file containing parts that can be run to
679
+ revert individual migrations in reverse of the order they are applied. The
680
+ SQL for reverting the migration is taken from a file with the same basename
681
+ as the migration it reverts, but in the 'rollback' subfolder and with a
682
+ '.sql' extension. The output file will not run as a viable script; a
683
+ contiguous section starting at the first SQL command and terminating at a
684
+ migration boundary should be run. Subsequent sections, consecutive with those
685
+ previously run, may also be run to further revert the database if necessary.
686
+
687
+ It may be helpful to execute the query:
688
+
689
+ SELECT * FROM xmigra.last_applied_migrations ORDER BY "RevertOrder";
690
+
691
+ This query lists the migrations applied by the last upgrade script that was
692
+ run.
693
+ END_OF_HELP
694
+
695
+ argument_error_unless(args.length == 0,
696
+ "'%prog %cmd' does not take any arguments.")
697
+
698
+ sql_gen = SchemaUpdater.new(options.source_dir).extend(WarnToStderr)
699
+
700
+ output_to(options.outfile) do |out_stream|
701
+ out_stream.print(sql_gen.reversion_script)
702
+ end
703
+ end
704
+
674
705
  subcommand 'render', "Generate SQL script for an access object" do |argv|
675
706
  args, options = command_line(argv, {:outfile=>true},
676
707
  :argument_desc=>"ACCESS_OBJECT_FILE",
@@ -0,0 +1,40 @@
1
+
2
+ module XMigra
3
+ module ReversionScriptBuilding
4
+ # This module is intended to be included into XMigra::SchemaUpdater
5
+
6
+ def reversions
7
+ if @reversions.nil?
8
+ @reversions = []
9
+ migrations.reverse_each do |m|
10
+ reversion = m.reversion
11
+ break unless reversion
12
+ @reversions << reversion
13
+ end
14
+ end
15
+
16
+ return @reversions if @reversions
17
+ end
18
+
19
+ def reversion_script
20
+ return nil if reversions.empty?
21
+
22
+ usage_note = [
23
+ "Run the reversion scripts below (separated by -- ======= -- dividers) in",
24
+ "the order given to revert changes as far as desired. Migrations should",
25
+ "always be reverted in the order given in this file. If any migration is",
26
+ "not reverted and one further down this file is, XMigra will no longer be",
27
+ "able to update the database schema.\n",
28
+ "The query:",
29
+ "",
30
+ " SELECT * FROM xmigra.last_applied_migrations ORDER BY \"RevertOrder\";",
31
+ "",
32
+ "lists the migrations applied by the last upgrade script run against this",
33
+ "database.\n",
34
+ ].collect {|l| '-- ' + l + "\n"}.join('')
35
+
36
+ return usage_note + "========================================\n" + \
37
+ reversions.join("-- ================================== --\n")
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,42 @@
1
+ require 'pathname'
2
+
3
+ module XMigra
4
+ class RevertFile
5
+ REVERSION_SUBDIR = 'rollback'
6
+
7
+ def initialize(migration)
8
+ @migration = migration
9
+ mig_path = Pathname(migration.file_path)
10
+ @description = "REVERT #{migration.description} (#{mig_path.basename})"
11
+ @path = migration.schema_dir.join(
12
+ REVERSION_SUBDIR,
13
+ mig_path.basename.to_s.sub(/\..*?$/, '.sql')
14
+ )
15
+ end
16
+
17
+ attr_reader :path, :description
18
+
19
+ def to_s
20
+ if @path.exist?
21
+ @sql ||= "-- %s:\n\n%s\n%s" % [
22
+ @description,
23
+ @path.read,
24
+ @migration.reversion_tracking_sql
25
+ ]
26
+ else
27
+ "-- #@description: No reversion given\n"
28
+ end
29
+ end
30
+
31
+ def inspect
32
+ "#<#{self.class.name} %s%s>" % [
33
+ @path,
34
+ (" (missing)" unless @path.exist?),
35
+ ]
36
+ end
37
+
38
+ def exist?
39
+ @path.exist?
40
+ end
41
+ end
42
+ end
@@ -1,8 +1,11 @@
1
1
 
2
2
  require 'xmigra/schema_manipulator'
3
+ require 'xmigra/reversion_script_building'
3
4
 
4
5
  module XMigra
5
6
  class SchemaUpdater < SchemaManipulator
7
+ include ReversionScriptBuilding
8
+
6
9
  DEV_SCRIPT_WARNING = <<-"END_OF_TEXT"
7
10
  *********************************************************
8
11
  *** WARNING ***
@@ -8,7 +8,7 @@ module XMigra
8
8
 
9
9
  class << self
10
10
  def manages(path)
11
- run_git(:status, :check_exit=>true)
11
+ run_git(:status, :check_exit=>true, :quiet=>true)
12
12
  end
13
13
 
14
14
  def run_git(subcmd, *args)
@@ -1,3 +1,3 @@
1
1
  module XMigra
2
- VERSION = "1.2.0"
2
+ VERSION = "1.3.0"
3
3
  end
@@ -0,0 +1,97 @@
1
+
2
+ def in_xmigra_schema
3
+ 1.temp_dirs do |schema|
4
+ Dir.chdir(schema) do
5
+ initialize_xmigra_schema
6
+ yield
7
+ end
8
+ end
9
+ end
10
+
11
+ def add_migration(migration_name, reversion_sql=nil)
12
+ tool = XMigra::NewMigrationAdder.new('.')
13
+ mig_path = tool.add_migration migration_name
14
+ mig_chain = XMigra::MigrationChain.new('structure')
15
+ migration = mig_chain[-1]
16
+ unless reversion_sql.nil?
17
+ class <<migration
18
+ def reversion_tracking_sql
19
+ '-- TRACK REVERSION OF MIGRATION --'
20
+ end
21
+ end
22
+ rev_file = XMigra::RevertFile.new(migration)
23
+ rev_file.path.dirname.mkpath
24
+ rev_file.path.open('w') do |rev_stream|
25
+ rev_stream.puts reversion_sql
26
+ end
27
+ end
28
+ return migration
29
+ end
30
+
31
+ def add_migration_reversion_pair(migration_name, reversion_sql)
32
+ return [add_migration(migration_name, reversion_sql), reversion_sql]
33
+ end
34
+
35
+ run_test "Generate upgrade with no reversions" do
36
+ in_xmigra_schema do
37
+ XMigra::NewMigrationAdder.new('.').tap do |tool|
38
+ tool.add_migration "Create foo table"
39
+ end
40
+ XMigra::Program.run(['upgrade', '--outfile=/dev/null'])
41
+ end
42
+ end
43
+
44
+ run_test "Generate reversions script with no reversions" do
45
+ in_xmigra_schema do
46
+ XMigra::NewMigrationAdder.new('.').tap do |tool|
47
+ tool.add_migration "Create foo table"
48
+ end
49
+ XMigra::Program.run(['reversions', '--outfile=/dev/null'])
50
+ end
51
+ end
52
+
53
+ run_test "Migration reversion contains SQL in reversion file" do
54
+ in_xmigra_schema do
55
+ reversion_sql = "DROP TABLE foo;"
56
+ migration = add_migration("Create foo table", reversion_sql)
57
+ assert("Reversion commands did not contain expected SQL") {
58
+ migration.reversion.to_s.include? reversion_sql
59
+ }
60
+ end
61
+ end
62
+
63
+ run_test "Generated revisions script for one migration" do
64
+ in_xmigra_schema do
65
+ reversion_sql = "DROP TABLE foo;"
66
+ migration = add_migration("Create foo table", reversion_sql)
67
+ assert("Reversions script did not contain reversion SQL") {
68
+ XMigra::Program.run(['reversions'])
69
+ test_output.include? reversion_sql
70
+ }
71
+ end
72
+ end
73
+
74
+ run_test "Generated revisions script for one migration removes application record" do
75
+ in_xmigra_schema do
76
+ reversion_sql = "DROP TABLE foo;"
77
+ migration = add_migration("Create foo table", reversion_sql)
78
+ assert("Reversions script does not remove migration application record") {
79
+ XMigra::Program.run(['reversions'])
80
+ script = test_output
81
+ script =~ /DELETE\s+FROM\s+.?xmigra.?\..?applied.?\s+WHERE\s+.?MigrationID.?\s*=\s*'#{migration.id}'\s*;/
82
+ }
83
+ end
84
+ end
85
+
86
+ run_test "Generate reversions script for two migrations" do
87
+ in_xmigra_schema do
88
+ migrations = []
89
+ migrations << add_migration_reversion_pair("Create foo table", "DROP TABLE foo;")
90
+ migrations << add_migration_reversion_pair("Add bar column to foo table", "ALTER TABLE foo DROP bar;")
91
+ assert("ALTER TABLE appeared after DROP TABLE") {
92
+ XMigra::Program.run(['reversions'])
93
+ script = test_output
94
+ (script =~ /ALTER\s+TABLE/) < (script =~ /DROP\s+TABLE/)
95
+ }
96
+ end
97
+ end
data/test/runner.rb CHANGED
@@ -7,6 +7,7 @@ require 'tmpdir'
7
7
 
8
8
  TESTS = %w[
9
9
  git_vcs
10
+ reversions
10
11
  ]
11
12
 
12
13
  $:.unshift Pathname(__FILE__).expand_path.dirname.dirname + 'lib'
@@ -48,7 +49,13 @@ def run_test(name, &block)
48
49
  end
49
50
  else
50
51
  begin
51
- block.call
52
+ prev_stdout = $stdout
53
+ $stdout = StringIO.new
54
+ begin
55
+ block.call
56
+ ensure
57
+ $stdout = prev_stdout
58
+ end
52
59
  exit! 0
53
60
  rescue AssertionFailure
54
61
  exit! 2
@@ -95,6 +102,11 @@ def initialize_xmigra_schema(path='.', options={})
95
102
  end
96
103
  end
97
104
 
105
+ def test_output
106
+ return nil unless $stdout.kind_of? StringIO
107
+ return $stdout.string
108
+ end
109
+
98
110
  def assert(message=nil, &block)
99
111
  get_message = proc {
100
112
  if !message and File.exist?(block.source_location[0])
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xmigra
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Next IT Corporation
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-12-08 00:00:00.000000000 Z
12
+ date: 2015-02-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -73,6 +73,8 @@ files:
73
73
  - lib/xmigra/new_migration_adder.rb
74
74
  - lib/xmigra/permission_script_writer.rb
75
75
  - lib/xmigra/program.rb
76
+ - lib/xmigra/reversion_script_building.rb
77
+ - lib/xmigra/revert_file.rb
76
78
  - lib/xmigra/schema_manipulator.rb
77
79
  - lib/xmigra/schema_updater.rb
78
80
  - lib/xmigra/stored_procedure.rb
@@ -82,6 +84,7 @@ files:
82
84
  - lib/xmigra/version.rb
83
85
  - lib/xmigra/view.rb
84
86
  - test/git_vcs.rb
87
+ - test/reversions.rb
85
88
  - test/runner.rb
86
89
  - xmigra.gemspec
87
90
  homepage: https://github.com/rtweeks/xmigra