migratrix 0.8.1 → 0.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/migratrix.rb
CHANGED
@@ -9,9 +9,12 @@ module Migratrix
|
|
9
9
|
require EXT + 'string_ext'
|
10
10
|
require EXT + 'object_ext'
|
11
11
|
require EXT + 'andand'
|
12
|
+
require APP + 'exceptions'
|
13
|
+
|
14
|
+
require APP + 'callbacks'
|
12
15
|
require APP + 'loggable'
|
16
|
+
require APP + 'migration_strategy'
|
13
17
|
require APP + 'valid_options'
|
14
|
-
require APP + 'exceptions'
|
15
18
|
require APP + 'registry'
|
16
19
|
require APP + 'migration'
|
17
20
|
require APP + 'migratrix'
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
|
3
|
+
module Migratrix
|
4
|
+
# = Migratrix Callbacks
|
5
|
+
#
|
6
|
+
# Callbacks are hooks into the life cycle of a Migratrix Migration
|
7
|
+
# or Component object that allow you to trigger logic before or
|
8
|
+
# after an alteration of the object state. This can be used to do
|
9
|
+
# extra preparation or cleanup at each step along the way. Consider
|
10
|
+
# the <tt>Migration#migrate</tt> call:
|
11
|
+
#
|
12
|
+
# * (1) <tt>before_migrate</tt>
|
13
|
+
# * (2) <tt>before_extract</tt>
|
14
|
+
# * (-) <tt>extract</tt>
|
15
|
+
# * (3) <tt>after_extract</tt>
|
16
|
+
# * (4) <tt>before_transform</tt>
|
17
|
+
# * (-) <tt>transform</tt>
|
18
|
+
# * (5) <tt>after_transform</tt>
|
19
|
+
# * (6) <tt>before_load</tt>
|
20
|
+
# * (-) <tt>load</tt>
|
21
|
+
# * (7) <tt>after_load</tt>
|
22
|
+
# * (8) <tt>after_migrate</tt>
|
23
|
+
#
|
24
|
+
module Callbacks
|
25
|
+
extend ActiveSupport::Concern
|
26
|
+
|
27
|
+
CALLBACKS = [ :after_extract, :after_load, :after_migrate,
|
28
|
+
:after_transform, :around_extract, :around_load,
|
29
|
+
:around_migrate, :around_transform, :before_extract,
|
30
|
+
:before_load, :before_migrate, :before_transform
|
31
|
+
]
|
32
|
+
|
33
|
+
included do
|
34
|
+
extend ActiveModel::Callbacks
|
35
|
+
# include ActiveModel::Validations::Callbacks
|
36
|
+
|
37
|
+
define_model_callbacks :migrate, :extract, :load, :transform
|
38
|
+
end
|
39
|
+
|
40
|
+
def migrate #:nodoc:
|
41
|
+
run_callbacks(:migrate) { super }
|
42
|
+
end
|
43
|
+
|
44
|
+
def extract #:nodoc:
|
45
|
+
run_callbacks(:extract) { super }
|
46
|
+
end
|
47
|
+
|
48
|
+
def transform(*) #:nodoc:
|
49
|
+
run_callbacks(:transform) { super }
|
50
|
+
end
|
51
|
+
|
52
|
+
def load(*) #:nodoc:
|
53
|
+
run_callbacks(:load) { super }
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
data/lib/migratrix/migration.rb
CHANGED
@@ -4,9 +4,11 @@ module Migratrix
|
|
4
4
|
# Superclass for all migrations. Migratrix COULD check to see that a
|
5
5
|
# loaded migration inherits from this class, but hey, duck typing.
|
6
6
|
class Migration
|
7
|
-
include
|
7
|
+
include Migratrix::Loggable
|
8
8
|
include ActiveModel::AttributeMethods
|
9
9
|
include Migratrix::ValidOptions
|
10
|
+
include Migratrix::MigrationStrategy
|
11
|
+
include Migratrix::Callbacks
|
10
12
|
|
11
13
|
attr_accessor :options
|
12
14
|
set_valid_options :console
|
@@ -101,54 +103,6 @@ module Migratrix
|
|
101
103
|
def loads
|
102
104
|
self.class.loads
|
103
105
|
end
|
104
|
-
|
105
|
-
def extract
|
106
|
-
extracted_items = {}
|
107
|
-
extractions.each do |name, extraction|
|
108
|
-
extracted_items[name] = extraction.extract(options)
|
109
|
-
end
|
110
|
-
extracted_items
|
111
|
-
end
|
112
|
-
|
113
|
-
# Transforms source data into outputs. @transformed_items is a
|
114
|
-
# hash of name => transformed_items.
|
115
|
-
#
|
116
|
-
def transform(extracted_items)
|
117
|
-
transformed_items = { }
|
118
|
-
transforms.each do |name, transform|
|
119
|
-
transformed_items[transform.name] = transform.transform extracted_items[transform.extraction]
|
120
|
-
end
|
121
|
-
transformed_items
|
122
|
-
end
|
123
|
-
|
124
|
-
# Saves the migrated data by "loading" it into our database or
|
125
|
-
# other data sink. Loaders have their own names, and by default
|
126
|
-
# they depend on a transformed_items key of the same name, but you
|
127
|
-
# may override this behavior by setting :source => :name or
|
128
|
-
# possibly :source => [:name1, :name2, etc].
|
129
|
-
def load(transformed_items)
|
130
|
-
loaded_items = { }
|
131
|
-
loads.each do |name, load|
|
132
|
-
loaded_items[load.name] = load.load transformed_items[load.transform]
|
133
|
-
end
|
134
|
-
loaded_items
|
135
|
-
end
|
136
|
-
|
137
|
-
# Perform the migration
|
138
|
-
# TODO: turn this into a strategy object. This pattern migrates
|
139
|
-
# everything in all one go, while the user may want to do a batch
|
140
|
-
# strategy. YAGNI: Rails 3 lets us defer the querying until we get
|
141
|
-
# to the transform step, and then it's batched for us under the
|
142
|
-
# hood. ...assuming, of course, we change the ActiveRecord
|
143
|
-
# extraction's execute_extract method to return source instead of
|
144
|
-
# all, but now the
|
145
|
-
def migrate
|
146
|
-
# This fn || @var API lets you write a method and either set the
|
147
|
-
# @var or return the value.
|
148
|
-
@extracted_items = extract || @extracted_items
|
149
|
-
@transformed_items = transform(@extracted_items) || @transformed_items
|
150
|
-
load @transformed_items
|
151
|
-
end
|
152
106
|
end
|
153
107
|
end
|
154
108
|
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Migratrix
|
2
|
+
# TODO: blatant asymmetry here: extraction.extract gets options, but
|
3
|
+
# transform and load do not--and they should.
|
4
|
+
#
|
5
|
+
# = MigrationStrategy
|
6
|
+
#
|
7
|
+
# This module defines the basic strategy for a generic migration:
|
8
|
+
# extract gets a collection of items, transform transforms each
|
9
|
+
# item, then load calls save on that final transformed object.
|
10
|
+
module MigrationStrategy
|
11
|
+
def extract
|
12
|
+
extracted_items = {}
|
13
|
+
extractions.each do |name, extraction|
|
14
|
+
extracted_items[name] = extraction.extract(options)
|
15
|
+
end
|
16
|
+
extracted_items
|
17
|
+
end
|
18
|
+
|
19
|
+
# Transforms source data into outputs. @transformed_items is a
|
20
|
+
# hash of name => transformed_items.
|
21
|
+
#
|
22
|
+
def transform(extracted_items)
|
23
|
+
transformed_items = { }
|
24
|
+
transforms.each do |name, transform|
|
25
|
+
transformed_items[transform.name] = transform.transform extracted_items[transform.extraction]
|
26
|
+
end
|
27
|
+
transformed_items
|
28
|
+
end
|
29
|
+
|
30
|
+
# Saves the migrated data by "loading" it into our database or
|
31
|
+
# other data sink. Loaders have their own names, and by default
|
32
|
+
# they depend on a transformed_items key of the same name, but you
|
33
|
+
# may override this behavior by setting :source => :name or
|
34
|
+
# possibly :source => [:name1, :name2, etc].
|
35
|
+
def load(transformed_items)
|
36
|
+
loaded_items = { }
|
37
|
+
loads.each do |name, load|
|
38
|
+
loaded_items[load.name] = load.load transformed_items[load.transform]
|
39
|
+
end
|
40
|
+
loaded_items
|
41
|
+
end
|
42
|
+
|
43
|
+
# Perform the migration
|
44
|
+
def migrate
|
45
|
+
# This fn || @var API lets you write a method and either set the
|
46
|
+
# @var or return the value.
|
47
|
+
@extracted_items = extract || @extracted_items
|
48
|
+
@transformed_items = transform(@extracted_items) || @transformed_items
|
49
|
+
load @transformed_items
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
@@ -0,0 +1,218 @@
|
|
1
|
+
class NoOpExtraction < Migratrix::Extractions::Extraction
|
2
|
+
def extract(options={})
|
3
|
+
[]
|
4
|
+
end
|
5
|
+
end
|
6
|
+
|
7
|
+
class NoOpTransform < Migratrix::Transforms::Transform
|
8
|
+
def transform(exts, options={})
|
9
|
+
[]
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class NoOpLoad < Migratrix::Loads::Load
|
14
|
+
def load(trans, options={})
|
15
|
+
[]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
Migratrix::Migratrix.register_extraction :no_op, NoOpExtraction
|
20
|
+
Migratrix::Migratrix.register_transform :no_op, NoOpTransform
|
21
|
+
Migratrix::Migratrix.register_load :no_op, NoOpLoad
|
22
|
+
|
23
|
+
|
24
|
+
class TestCallbackMigration < Migratrix::Migration
|
25
|
+
set_extraction :test, :no_op
|
26
|
+
set_transform :test, :no_op
|
27
|
+
set_load :test, :no_op
|
28
|
+
end
|
29
|
+
|
30
|
+
class MethodCallbackMigration < TestCallbackMigration
|
31
|
+
extend_extraction :test, {}
|
32
|
+
extend_transform :test, {}
|
33
|
+
extend_load :test, {}
|
34
|
+
|
35
|
+
attr_reader :before_migrate_called, :after_migrate_called, :around_migrate_called
|
36
|
+
attr_reader :before_extract_called, :after_extract_called, :around_extract_called
|
37
|
+
attr_reader :before_transform_called, :after_transform_called, :around_transform_called
|
38
|
+
attr_reader :before_load_called, :after_load_called, :around_load_called
|
39
|
+
|
40
|
+
before_migrate :before_migrate_method
|
41
|
+
after_migrate :after_migrate_method
|
42
|
+
around_migrate :around_migrate_method
|
43
|
+
|
44
|
+
def before_migrate_method
|
45
|
+
@before_migrate_called = true
|
46
|
+
end
|
47
|
+
|
48
|
+
def after_migrate_method
|
49
|
+
@after_migrate_called = true
|
50
|
+
end
|
51
|
+
|
52
|
+
def around_migrate_method
|
53
|
+
yield
|
54
|
+
@around_migrate_called = true
|
55
|
+
end
|
56
|
+
|
57
|
+
before_extract :before_extract_method
|
58
|
+
after_extract :after_extract_method
|
59
|
+
around_extract :around_extract_method
|
60
|
+
|
61
|
+
def before_extract_method
|
62
|
+
@before_extract_called = true
|
63
|
+
end
|
64
|
+
|
65
|
+
def after_extract_method
|
66
|
+
@after_extract_called = true
|
67
|
+
end
|
68
|
+
|
69
|
+
def around_extract_method
|
70
|
+
yield
|
71
|
+
@around_extract_called = true
|
72
|
+
end
|
73
|
+
|
74
|
+
before_transform :before_transform_method
|
75
|
+
after_transform :after_transform_method
|
76
|
+
around_transform :around_transform_method
|
77
|
+
|
78
|
+
def before_transform_method
|
79
|
+
@before_transform_called = true
|
80
|
+
end
|
81
|
+
|
82
|
+
def after_transform_method
|
83
|
+
@after_transform_called = true
|
84
|
+
end
|
85
|
+
|
86
|
+
def around_transform_method
|
87
|
+
yield
|
88
|
+
@around_transform_called = true
|
89
|
+
end
|
90
|
+
|
91
|
+
before_load :before_load_method
|
92
|
+
after_load :after_load_method
|
93
|
+
around_load :around_load_method
|
94
|
+
|
95
|
+
def before_load_method
|
96
|
+
@before_load_called = true
|
97
|
+
end
|
98
|
+
|
99
|
+
def after_load_method
|
100
|
+
@after_load_called = true
|
101
|
+
end
|
102
|
+
|
103
|
+
def around_load_method
|
104
|
+
yield
|
105
|
+
@around_load_called = true
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
class BlockCallbackMigration < TestCallbackMigration
|
110
|
+
attr_reader :before_migrate_called, :after_migrate_called
|
111
|
+
attr_reader :before_extract_called, :after_extract_called
|
112
|
+
attr_reader :before_transform_called, :after_transform_called
|
113
|
+
attr_reader :before_load_called, :after_load_called
|
114
|
+
|
115
|
+
before_migrate do
|
116
|
+
@before_migrate_called = true
|
117
|
+
end
|
118
|
+
|
119
|
+
after_migrate do
|
120
|
+
@after_migrate_called = true
|
121
|
+
end
|
122
|
+
|
123
|
+
before_extract do
|
124
|
+
@before_extract_called = true
|
125
|
+
end
|
126
|
+
|
127
|
+
after_extract do
|
128
|
+
@after_extract_called = true
|
129
|
+
end
|
130
|
+
|
131
|
+
before_transform do
|
132
|
+
@before_transform_called = true
|
133
|
+
end
|
134
|
+
|
135
|
+
after_transform do
|
136
|
+
@after_transform_called = true
|
137
|
+
end
|
138
|
+
|
139
|
+
before_load do
|
140
|
+
@before_load_called = true
|
141
|
+
end
|
142
|
+
|
143
|
+
after_load do
|
144
|
+
@after_load_called = true
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
describe "callbacks" do
|
149
|
+
describe "sanity check cat" do
|
150
|
+
it "is sanity checked" do
|
151
|
+
NoOpExtraction.should_not be_nil
|
152
|
+
NoOpTransform.should_not be_nil
|
153
|
+
NoOpLoad.should_not be_nil
|
154
|
+
TestCallbackMigration.should_not be_nil
|
155
|
+
MethodCallbackMigration.should_not be_nil
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
describe "with named callback methods" do
|
160
|
+
let(:migration) { MethodCallbackMigration.new }
|
161
|
+
before do
|
162
|
+
migration.migrate
|
163
|
+
end
|
164
|
+
|
165
|
+
it "calls migrate callbacks" do
|
166
|
+
migration.before_migrate_called.should be_true
|
167
|
+
migration.after_migrate_called.should be_true
|
168
|
+
migration.around_migrate_called.should be_true
|
169
|
+
end
|
170
|
+
|
171
|
+
it "calls extract callbacks" do
|
172
|
+
migration.before_extract_called.should be_true
|
173
|
+
migration.after_extract_called.should be_true
|
174
|
+
migration.around_extract_called.should be_true
|
175
|
+
end
|
176
|
+
|
177
|
+
it "calls transform callbacks" do
|
178
|
+
migration.before_transform_called.should be_true
|
179
|
+
migration.after_transform_called.should be_true
|
180
|
+
migration.around_transform_called.should be_true
|
181
|
+
end
|
182
|
+
|
183
|
+
it "calls load callbacks" do
|
184
|
+
migration.before_load_called.should be_true
|
185
|
+
migration.after_load_called.should be_true
|
186
|
+
migration.around_load_called.should be_true
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
describe "with block callbacks" do
|
191
|
+
let(:migration) { BlockCallbackMigration.new }
|
192
|
+
before do
|
193
|
+
migration.migrate
|
194
|
+
end
|
195
|
+
|
196
|
+
it "calls migrate callbacks" do
|
197
|
+
migration.before_migrate_called.should be_true
|
198
|
+
migration.after_migrate_called.should be_true
|
199
|
+
end
|
200
|
+
|
201
|
+
it "calls extract callbacks" do
|
202
|
+
migration.before_extract_called.should be_true
|
203
|
+
migration.after_extract_called.should be_true
|
204
|
+
end
|
205
|
+
|
206
|
+
it "calls transform callbacks" do
|
207
|
+
migration.before_transform_called.should be_true
|
208
|
+
migration.after_transform_called.should be_true
|
209
|
+
end
|
210
|
+
|
211
|
+
it "calls load callbacks" do
|
212
|
+
migration.before_load_called.should be_true
|
213
|
+
migration.after_load_called.should be_true
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: migratrix
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-10-
|
12
|
+
date: 2011-10-25 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: trollop
|
16
|
-
requirement: &
|
16
|
+
requirement: &2152828360 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,7 +21,7 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *2152828360
|
25
25
|
description: Migratrix, a Rails legacy database migration tool supporting multiple
|
26
26
|
strategies, including arbitrary n-ary migrations (1->n, n->1, n->m), arbitrary inputs
|
27
27
|
and outputs (ActiveRecord, bare SQL, CSV) and migration logging
|
@@ -37,6 +37,7 @@ files:
|
|
37
37
|
- bin/migratrix
|
38
38
|
- lib/migratrix.rb
|
39
39
|
- lib/migratrix/active_record_migration_helpers.rb
|
40
|
+
- lib/migratrix/callbacks.rb
|
40
41
|
- lib/migratrix/exceptions.rb
|
41
42
|
- lib/migratrix/extractions/active_record.rb
|
42
43
|
- lib/migratrix/extractions/extraction.rb
|
@@ -44,6 +45,7 @@ files:
|
|
44
45
|
- lib/migratrix/loads/yaml.rb
|
45
46
|
- lib/migratrix/loggable.rb
|
46
47
|
- lib/migratrix/migration.rb
|
48
|
+
- lib/migratrix/migration_strategy.rb
|
47
49
|
- lib/migratrix/migratrix.rb
|
48
50
|
- lib/migratrix/registry.rb
|
49
51
|
- lib/migratrix/transforms/map.rb
|
@@ -54,6 +56,7 @@ files:
|
|
54
56
|
- lib/patches/string_ext.rb
|
55
57
|
- spec/fixtures/migrations/marbles_migration.rb
|
56
58
|
- spec/lib/migratrix/_loggable_spec.rb
|
59
|
+
- spec/lib/migratrix/callbacks_spec.rb
|
57
60
|
- spec/lib/migratrix/extractions/active_record_spec.rb
|
58
61
|
- spec/lib/migratrix/extractions/extraction_spec.rb
|
59
62
|
- spec/lib/migratrix/loads/load_spec.rb
|