data_migrator 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +20 -0
- data/README.rdoc +42 -0
- data/db/migrate/20100819181805_create_data_migrations_table.rb +15 -0
- data/lib/data_migrator.rb +303 -0
- data/lib/generators/data_migration/USAGE +9 -0
- data/lib/generators/data_migration/data_migration_generator.rb +7 -0
- data/lib/generators/data_migration/templates/migration_template.rb +11 -0
- data/lib/tasks/data_migrator.rake +54 -0
- data/lib/version.rb +3 -0
- data/test/data_migrator_test.rb +8 -0
- data/test/test_helper.rb +3 -0
- metadata +93 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 [name of plugin creator]
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
Data Migrations
|
2
|
+
===============
|
3
|
+
|
4
|
+
Every Rails developer is familiar with Rails’ invaluable schema migration tool but, as I’m sure many have experienced, it does not address the need for data migrations. Mixing data migrations into schema migrations is simply unacceptable. There is of course the seed data tool, but this is intended for the loading of initial data, much like fixtures. We needed a way to deal with ongoing data migrations to support schema changes over time. This called for a tool similar to schema migrations to be used exclusively for data migrations. The behavior is almost identical to schema migrations. They are controlled via a versioning mechanism like schema migrations. They can be run up and down and they load your Rails environment so all your models are fair game. Anything you can do with your models you can do in the migrations i.e. create, update destroy/delete.
|
5
|
+
It's easy to get started just install the plugin and your ready to go. There is a generator just like with schema migrations:
|
6
|
+
|
7
|
+
script/generate data_migration create_sample_users
|
8
|
+
|
9
|
+
It will generate the versioning for you and place the file in db/data_migrations (don't worry if the folder isn't there it will create it for you). Simply add your code to the generated file
|
10
|
+
|
11
|
+
class CreateSampleUsers
|
12
|
+
def self.up
|
13
|
+
User.create(:login => 'awesome_dude' , :email => 'awesome@dude.com')
|
14
|
+
end
|
15
|
+
def self.down
|
16
|
+
User.destroy_all(:conditions => ['login = ?','awesome_dude'])
|
17
|
+
end
|
18
|
+
end
|
19
|
+
You can even use the Migration class if you wish:
|
20
|
+
class CreateSampleUsers < ActiveRecord::Migration
|
21
|
+
def self.up
|
22
|
+
execute "UPDATE users SET name=’Fred' WHERE id=2"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
As you can see it has an up and a down just like schema migrations. To run the data migrations simply run the rake task
|
27
|
+
rake db:migrate_data
|
28
|
+
|
29
|
+
All the schema migration features work here too
|
30
|
+
Migrate up to and including specified version, running all migrations that have not been run:
|
31
|
+
rake db:migrate VERSION=10101010101
|
32
|
+
Migrate only the specified migration if it has not been run:
|
33
|
+
rake db:migrate_data:up VERSION=1010101010101
|
34
|
+
Migrate down only the specified version if it has not been run:
|
35
|
+
rake db:migrate_data:down VERSION=10101010101
|
36
|
+
|
37
|
+
One added benefit that data migrations have over regular schema migrations is that if you like to develop in engines as I do, it will pick up and run any of the data migrations living in your engines as well. Just create a folder in your engine db/data_migrations and you’re all set. When you run the rake task it will copy any files located in db/data_migrations of your engines up to RAILS_ROOT/db/data_migrations and run them. When it is done it will remove them from RAILS_ROOT /db/data_migrations leaving them down in your engines. Yet another cool feature (I know this is starting to sound like an infomercial), if you don't want to run some of your migrations, say you have some test data that you want only ran from your environment you can place them in folder called db/data_migrations/ignore and as the folder suggests the rake task will ignore anything and everything in that folder. So when you commit your changes, your colleagues won't groan when your migrations won't run in their environment. It will also recursively go through folders looking for migrations so you can organize them if you like
|
38
|
+
|
39
|
+
db/data_migrations/users/010101010101_example_users.rb
|
40
|
+
db/data_migrations/roles/010101010101_example_roles.rb
|
41
|
+
|
42
|
+
That about wraps it up. Have at it my fellow developers and as always happy coding.
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class CreateDataMigrationsTable < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
unless table_exists?(:data_migrations)
|
4
|
+
create_table :data_migrations, {:id => false} do |t|
|
5
|
+
t.column :version, :string
|
6
|
+
end
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.down
|
11
|
+
if table_exists?(:data_migrations)
|
12
|
+
drop_table :data_migrations
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,303 @@
|
|
1
|
+
require "benchmark"
|
2
|
+
|
3
|
+
class DataMigrator
|
4
|
+
DEFAULT_MIGRATIONS_PATH = "#{Rails.root}/db/data_migrations"
|
5
|
+
REMOVE_FILES_REGEX = /^\./
|
6
|
+
|
7
|
+
def self.migrate(passed_location=nil, passed_version=nil)
|
8
|
+
self.setup
|
9
|
+
|
10
|
+
location = passed_location.nil? ? DEFAULT_MIGRATIONS_PATH : passed_location
|
11
|
+
@@current_version = get_current_version
|
12
|
+
|
13
|
+
if passed_version.nil? || @@current_version.nil?
|
14
|
+
self.run_all_non_migrated(passed_version)
|
15
|
+
elsif passed_version < @@current_version
|
16
|
+
self.handle_lower_passed_version(passed_version)
|
17
|
+
elsif passed_version > @@current_version
|
18
|
+
self.handle_higher_passed_version(passed_version)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.pending_migrations
|
23
|
+
versions = []
|
24
|
+
files = self.get_all_files
|
25
|
+
files.each do |file|
|
26
|
+
filename, version, klass_name = self.seperate_file_parts(file)
|
27
|
+
unless version_has_been_migrated?(version)
|
28
|
+
versions << filename
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
versions
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.get_current_version
|
36
|
+
result = ActiveRecord::Base.connection.select_all("select max(version) as current_version from data_migrations")
|
37
|
+
|
38
|
+
current_version = result[0]['current_version'] unless result == -1
|
39
|
+
|
40
|
+
current_version = current_version.to_i unless current_version.nil?
|
41
|
+
|
42
|
+
current_version
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.next_migration_number
|
46
|
+
Time.now.utc.strftime("%Y%m%d%H%M%S")
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.run_up(passed_version)
|
50
|
+
self.setup
|
51
|
+
|
52
|
+
raise "VERSION is required" unless passed_version
|
53
|
+
|
54
|
+
files = self.get_all_files
|
55
|
+
found = false
|
56
|
+
|
57
|
+
files.each do |file|
|
58
|
+
filename, version, klass_name = self.seperate_file_parts(file)
|
59
|
+
if passed_version == version
|
60
|
+
found = true
|
61
|
+
unless self.version_has_been_migrated?(version)
|
62
|
+
self.handle_action(file, klass_name, version, :up)
|
63
|
+
else
|
64
|
+
puts "** Version #{passed_version} has already been migrated"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
unless found
|
70
|
+
puts "** Version #{passed_version} not found"
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.run_down(passed_version)
|
76
|
+
self.setup
|
77
|
+
|
78
|
+
raise "VERSION is required" unless passed_version
|
79
|
+
|
80
|
+
files = self.get_all_files
|
81
|
+
found = false
|
82
|
+
|
83
|
+
files.each do |file|
|
84
|
+
filename, version, klass_name = self.seperate_file_parts(file)
|
85
|
+
if passed_version == version
|
86
|
+
found = true
|
87
|
+
if self.version_has_been_migrated?(version)
|
88
|
+
self.handle_action(file, klass_name, version, :down)
|
89
|
+
else
|
90
|
+
puts "** Version #{passed_version} has not been migrated"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
unless found
|
96
|
+
puts "** Version #{passed_version} not found"
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
|
+
def self.prepare_migrations
|
102
|
+
target = "#{Rails.root}/db/data_migrations/"
|
103
|
+
|
104
|
+
# first copy all app data_migrations away
|
105
|
+
files = Dir["#{target}*.rb"]
|
106
|
+
|
107
|
+
unless files.empty?
|
108
|
+
FileUtils.mkdir_p "#{target}/ignore/app/"
|
109
|
+
FileUtils.cp files, "#{target}/ignore/app/"
|
110
|
+
puts "copied #{files.size} data_migrations to db/data_migrations/ignore/app"
|
111
|
+
end
|
112
|
+
|
113
|
+
dirs = Rails::Application::Railties.engines.map{|p| p.config.root.to_s}
|
114
|
+
files = Dir["{#{dirs.join(',')}}/db/data_migrations/*.rb"]
|
115
|
+
|
116
|
+
unless files.empty?
|
117
|
+
FileUtils.mkdir_p target
|
118
|
+
FileUtils.cp files, target
|
119
|
+
puts "copied #{files.size} migrations to db/data_migrations"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def self.cleanup_migrations
|
124
|
+
target = "#{Rails.root}/db/data_migrations/"
|
125
|
+
|
126
|
+
files = Dir["#{target}*.rb"]
|
127
|
+
unless files.empty?
|
128
|
+
FileUtils.rm files
|
129
|
+
puts "removed #{files.size} data_migrations from db/data_migrations"
|
130
|
+
end
|
131
|
+
files = Dir["#{target}/ignore/app/*.rb"]
|
132
|
+
unless files.empty?
|
133
|
+
FileUtils.cp files, target
|
134
|
+
puts "copied #{files.size} data_migrations back to db/data_migrations"
|
135
|
+
end
|
136
|
+
FileUtils.rm_rf "#{target}/ignore/app"
|
137
|
+
end
|
138
|
+
|
139
|
+
private
|
140
|
+
|
141
|
+
def self.setup
|
142
|
+
unless self.data_migrations_table_exists?
|
143
|
+
self.create_data_migrations_table
|
144
|
+
end
|
145
|
+
|
146
|
+
unless File.directory? DEFAULT_MIGRATIONS_PATH
|
147
|
+
FileUtils.mkdir_p(DEFAULT_MIGRATIONS_PATH)
|
148
|
+
#create ignore folder
|
149
|
+
FileUtils.mkdir_p(DEFAULT_MIGRATIONS_PATH + '/ignore/')
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def self.handle_higher_passed_version(passed_version)
|
154
|
+
files = self.get_all_files
|
155
|
+
|
156
|
+
files.each do |file|
|
157
|
+
filename, version, klass_name = self.seperate_file_parts(file)
|
158
|
+
if version <= passed_version
|
159
|
+
unless self.version_has_been_migrated?(version)
|
160
|
+
self.handle_action(file, klass_name, version, :up)
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
end
|
166
|
+
|
167
|
+
def self.run_all_non_migrated(passed_version)
|
168
|
+
files = self.get_all_files
|
169
|
+
|
170
|
+
files.each do |file|
|
171
|
+
filename, version, klass_name = self.seperate_file_parts(file)
|
172
|
+
if passed_version.nil? or version <= passed_version
|
173
|
+
if !self.version_has_been_migrated?(version)
|
174
|
+
self.handle_action(file, klass_name, version, :up)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
def self.handle_lower_passed_version(passed_version)
|
181
|
+
files = self.get_all_files
|
182
|
+
|
183
|
+
files.each do |file|
|
184
|
+
filename, version, klass_name = self.seperate_file_parts(file)
|
185
|
+
if version > passed_version
|
186
|
+
if self.version_has_been_migrated?(version)
|
187
|
+
self.handle_action(file, klass_name, version, :down)
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
end
|
193
|
+
|
194
|
+
def self.handle_action(file, klass_name, version, action)
|
195
|
+
require file
|
196
|
+
klass = klass_name.camelize.constantize
|
197
|
+
puts "=================Migrating #{klass.to_s} #{action.to_s.upcase}============"
|
198
|
+
begin
|
199
|
+
time = Benchmark.measure do
|
200
|
+
ActiveRecord::Base.transaction do
|
201
|
+
klass.send(action.to_s)
|
202
|
+
end
|
203
|
+
end
|
204
|
+
rescue Exception=>ex
|
205
|
+
self.cleanup_migrations
|
206
|
+
raise ex
|
207
|
+
end
|
208
|
+
time_str = "(%.4fs)" % time.real
|
209
|
+
puts "================Finished #{klass.to_s} in #{time_str}=="
|
210
|
+
self.insert_migration_version(version)
|
211
|
+
end
|
212
|
+
|
213
|
+
def self.insert_migration_version(version)
|
214
|
+
ActiveRecord::Base.connection.execute("insert into data_migrations (version) values ('#{version}')")
|
215
|
+
end
|
216
|
+
|
217
|
+
def self.remove_migration_version(version)
|
218
|
+
ActiveRecord::Base.connection.execute("delete from data_migrations where version = '#{version}'")
|
219
|
+
end
|
220
|
+
|
221
|
+
def self.version_has_been_migrated?(version)
|
222
|
+
result = true
|
223
|
+
|
224
|
+
db_result = ActiveRecord::Base.connection.select_all("select count(*) as num_rows from data_migrations where version = '#{version}'")
|
225
|
+
|
226
|
+
num_rows = db_result[0]['num_rows'] unless db_result == -1
|
227
|
+
|
228
|
+
if num_rows.nil? || num_rows.to_i == 0
|
229
|
+
result = false
|
230
|
+
end
|
231
|
+
|
232
|
+
result
|
233
|
+
end
|
234
|
+
|
235
|
+
def self.data_migrations_table_exists?
|
236
|
+
table_names = ActiveRecord::Base.connection.tables
|
237
|
+
table_names.include?('data_migrations')
|
238
|
+
end
|
239
|
+
|
240
|
+
def self.create_data_migrations_table
|
241
|
+
puts "** data_migrations table missing creating now...."
|
242
|
+
puts ActiveRecord::Migrator.run(:up, File.join(File.dirname(__FILE__),'../db/migrate/'), 20100819181805)
|
243
|
+
puts "** done"
|
244
|
+
end
|
245
|
+
|
246
|
+
def self.seperate_file_parts(file)
|
247
|
+
paths = file.split('/')
|
248
|
+
filename = paths[paths.length - 1]
|
249
|
+
version = filename.split('_')[0]
|
250
|
+
klass_name = filename.gsub(/#{version}/, "").gsub(/.rb/, "")[1..filename.length]
|
251
|
+
|
252
|
+
return filename, version.to_i, klass_name
|
253
|
+
end
|
254
|
+
|
255
|
+
def self.get_all_files
|
256
|
+
files = []
|
257
|
+
|
258
|
+
if File.directory? DEFAULT_MIGRATIONS_PATH
|
259
|
+
|
260
|
+
files_or_directories = Dir.entries(DEFAULT_MIGRATIONS_PATH).map{|directory| directory}
|
261
|
+
|
262
|
+
files_or_directories.delete_if{|name| name =~ REMOVE_FILES_REGEX} #remove any file leading with . or ..
|
263
|
+
files_or_directories.delete_if{|name| name == 'ignore'} #ignore the ignore folder
|
264
|
+
|
265
|
+
|
266
|
+
files_or_directories.each do |file_or_directory|
|
267
|
+
file_or_directory = DEFAULT_MIGRATIONS_PATH + "/" + file_or_directory
|
268
|
+
files = self.get_files_in_directory(file_or_directory, files)
|
269
|
+
end
|
270
|
+
|
271
|
+
files.sort! {|x,y| self.get_file_name(x) <=> self.get_file_name(y)}
|
272
|
+
end
|
273
|
+
|
274
|
+
files
|
275
|
+
end
|
276
|
+
|
277
|
+
def self.get_files_in_directory(file_or_directory, files)
|
278
|
+
unless file_or_directory =~ /\w\.rb/
|
279
|
+
files_or_directories = Dir.entries(file_or_directory).map{|directory| directory}
|
280
|
+
|
281
|
+
files_or_directories.delete_if{|name| name =~ REMOVE_FILES_REGEX} #remove any file leading with . or ..
|
282
|
+
files_or_directories.delete_if{|name| name == 'ignore'} #ignore the ignore folder
|
283
|
+
|
284
|
+
files_or_directories.each do |_file_or_directory|
|
285
|
+
_file_or_directory = file_or_directory + "/" + _file_or_directory
|
286
|
+
files = self.get_files_in_directory(_file_or_directory, files)
|
287
|
+
end
|
288
|
+
else
|
289
|
+
files << file_or_directory
|
290
|
+
end
|
291
|
+
|
292
|
+
files
|
293
|
+
end
|
294
|
+
|
295
|
+
def self.get_file_name(dir)
|
296
|
+
file_name = dir
|
297
|
+
|
298
|
+
paths = dir.split('/')
|
299
|
+
file_name = paths[paths.length - 1]
|
300
|
+
|
301
|
+
file_name
|
302
|
+
end
|
303
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
namespace :db do
|
2
|
+
desc 'migrates data into database'
|
3
|
+
task :migrate_data => :environment do
|
4
|
+
|
5
|
+
passed_version = ENV["VERSION"] ? ENV["VERSION"].to_i : nil
|
6
|
+
DataMigrator.prepare_migrations
|
7
|
+
DataMigrator.migrate(nil, passed_version)
|
8
|
+
DataMigrator.cleanup_migrations
|
9
|
+
|
10
|
+
end#end task
|
11
|
+
|
12
|
+
namespace :migrate_data do
|
13
|
+
task :list_pending => :environment do
|
14
|
+
DataMigrator.prepare_migrations
|
15
|
+
pending_migrations = DataMigrator.pending_migrations
|
16
|
+
puts "================Pending Data Migrations=========="
|
17
|
+
puts pending_migrations
|
18
|
+
puts "================================================="
|
19
|
+
DataMigrator.cleanup_migrations
|
20
|
+
end
|
21
|
+
|
22
|
+
task :version => :environment do
|
23
|
+
version = DataMigrator.get_current_version
|
24
|
+
|
25
|
+
unless version.nil?
|
26
|
+
puts "** Current version #{version}"
|
27
|
+
else
|
28
|
+
puts "** No migrations ran"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
task :up => :environment do
|
33
|
+
passed_version = ENV["VERSION"] ? ENV["VERSION"].to_i : nil
|
34
|
+
raise "VERSION is required" unless passed_version
|
35
|
+
|
36
|
+
DataMigrator.prepare_migrations
|
37
|
+
DataMigrator.run_up(passed_version)
|
38
|
+
DataMigrator.cleanup_migrations
|
39
|
+
|
40
|
+
end#end task
|
41
|
+
|
42
|
+
task :down => :environment do
|
43
|
+
passed_version = ENV["VERSION"] ? ENV["VERSION"].to_i : nil
|
44
|
+
raise "VERSION is required" unless passed_version
|
45
|
+
|
46
|
+
DataMigrator.prepare_migrations
|
47
|
+
DataMigrator.run_down(passed_version)
|
48
|
+
DataMigrator.cleanup_migrations
|
49
|
+
|
50
|
+
end#end task
|
51
|
+
end#end namespace
|
52
|
+
end
|
53
|
+
|
54
|
+
|
data/lib/version.rb
ADDED
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: data_migrator
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Russell Holmes, Adam Hull
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-08-19 00:00:00 -04:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: activerecord
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 9
|
30
|
+
segments:
|
31
|
+
- 2
|
32
|
+
- 3
|
33
|
+
- 5
|
34
|
+
version: 2.3.5
|
35
|
+
type: :runtime
|
36
|
+
version_requirements: *id001
|
37
|
+
description: Allows you to create data migrations that can be run up and down to insert data into the database.
|
38
|
+
email: russellfholmes@gmail.com
|
39
|
+
executables: []
|
40
|
+
|
41
|
+
extensions: []
|
42
|
+
|
43
|
+
extra_rdoc_files: []
|
44
|
+
|
45
|
+
files:
|
46
|
+
- db/migrate/20100819181805_create_data_migrations_table.rb
|
47
|
+
- lib/data_migrator.rb
|
48
|
+
- lib/generators/data_migration/data_migration_generator.rb
|
49
|
+
- lib/generators/data_migration/templates/migration_template.rb
|
50
|
+
- lib/generators/data_migration/USAGE
|
51
|
+
- lib/tasks/data_migrator.rake
|
52
|
+
- lib/version.rb
|
53
|
+
- MIT-LICENSE
|
54
|
+
- README.rdoc
|
55
|
+
- test/data_migrator_test.rb
|
56
|
+
- test/test_helper.rb
|
57
|
+
has_rdoc: true
|
58
|
+
homepage: https://github.com/portablemind/data_migrator
|
59
|
+
licenses: []
|
60
|
+
|
61
|
+
post_install_message:
|
62
|
+
rdoc_options: []
|
63
|
+
|
64
|
+
require_paths:
|
65
|
+
- lib
|
66
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
67
|
+
none: false
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
hash: 3
|
72
|
+
segments:
|
73
|
+
- 0
|
74
|
+
version: "0"
|
75
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
76
|
+
none: false
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
hash: 3
|
81
|
+
segments:
|
82
|
+
- 0
|
83
|
+
version: "0"
|
84
|
+
requirements: []
|
85
|
+
|
86
|
+
rubyforge_project:
|
87
|
+
rubygems_version: 1.3.7
|
88
|
+
signing_key:
|
89
|
+
specification_version: 3
|
90
|
+
summary: Creates Data Migrations for data similar to schema migrations.
|
91
|
+
test_files:
|
92
|
+
- test/data_migrator_test.rb
|
93
|
+
- test/test_helper.rb
|