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.
@@ -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
+
@@ -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 ::Migratrix::Loggable
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
+
@@ -108,6 +108,5 @@ describe Migratrix::Migratrix do
108
108
  end
109
109
  end
110
110
  end
111
-
112
111
  end
113
112
 
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.1
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-24 00:00:00.000000000Z
12
+ date: 2011-10-25 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: trollop
16
- requirement: &2164512960 !ruby/object:Gem::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: *2164512960
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