super_migration 0.0.0.pre1 → 0.0.1
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/README.rdoc +33 -1
- data/VERSION +1 -1
- data/lib/entities/fields_map.rb +18 -0
- data/lib/entities/record.rb +9 -0
- data/lib/example.rb +29 -0
- data/lib/super_migration.rb +111 -21
- metadata +7 -4
data/README.rdoc
CHANGED
@@ -1,6 +1,38 @@
|
|
1
1
|
= super_migration
|
2
2
|
|
3
|
-
|
3
|
+
Migrate legacy database content into a databse with a new structure.
|
4
|
+
|
5
|
+
== Example
|
6
|
+
|
7
|
+
require 'super_migration'
|
8
|
+
include SM
|
9
|
+
|
10
|
+
SuperMigration.setup do |config|
|
11
|
+
# same options as in database.yml
|
12
|
+
config.from_database :database => "sm1",
|
13
|
+
:adapter => "mysql",
|
14
|
+
:host => "localhost",
|
15
|
+
:username => "root",
|
16
|
+
:password => ""
|
17
|
+
|
18
|
+
config.to_database :database => "sm2",
|
19
|
+
:adapter => "mysql",
|
20
|
+
:host => "localhost",
|
21
|
+
:username => "root",
|
22
|
+
:password => ""
|
23
|
+
end
|
24
|
+
|
25
|
+
SuperMigration.migrate do
|
26
|
+
table :from => :books, :to => :livres do
|
27
|
+
|
28
|
+
field :from => :author, :to => :autheur
|
29
|
+
|
30
|
+
# apply a transformation to dob field
|
31
|
+
field :from => :title, :to => :titre do |title|
|
32
|
+
Date.today.to_s + title
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
4
36
|
|
5
37
|
== Note on Patches/Pull Requests
|
6
38
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.1
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module SM
|
2
|
+
# map @from to @to aditionally applying a block @block to @to
|
3
|
+
# e.g.
|
4
|
+
#
|
5
|
+
# for the following fields
|
6
|
+
#
|
7
|
+
# {:profile_name => :name, :block => BLOCK}, # => applies the BLOCK on the :name field and put it in profile_name
|
8
|
+
# {:profile_email => :email, :block => BLOCK},
|
9
|
+
# {:profile_website => :website} # => put the :profile_website data on the corresponding :website field
|
10
|
+
class FieldsMap
|
11
|
+
attr_accessor :from, :to, :block
|
12
|
+
def initialize(from, to, block = nil)
|
13
|
+
@from = from
|
14
|
+
@to = to
|
15
|
+
@block= block
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/example.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'super_migration'
|
2
|
+
include SM
|
3
|
+
|
4
|
+
SuperMigration.setup do |config|
|
5
|
+
# same options as in database.yml
|
6
|
+
config.from_database :database => "sm1",
|
7
|
+
:adapter => "mysql",
|
8
|
+
:host => "localhost",
|
9
|
+
:username => "root",
|
10
|
+
:password => ""
|
11
|
+
|
12
|
+
config.to_database :database => "sm2",
|
13
|
+
:adapter => "mysql",
|
14
|
+
:host => "localhost",
|
15
|
+
:username => "root",
|
16
|
+
:password => ""
|
17
|
+
end
|
18
|
+
|
19
|
+
SuperMigration.migrate do
|
20
|
+
table :from => :books, :to => :livres do
|
21
|
+
|
22
|
+
field :from => :author, :to => :autheur
|
23
|
+
|
24
|
+
# apply a transformation to dob field
|
25
|
+
field :from => :title, :to => :titre do |title|
|
26
|
+
Date.today.to_s + title
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/super_migration.rb
CHANGED
@@ -1,41 +1,131 @@
|
|
1
|
-
|
1
|
+
require 'rubygems'
|
2
|
+
require 'active_record'
|
3
|
+
require 'active_support'
|
2
4
|
|
3
|
-
|
5
|
+
Dir["#{File.dirname(__FILE__)}/entities/*.rb"].each { |file| require file }
|
4
6
|
|
7
|
+
module SM
|
5
8
|
class SuperMigration
|
6
|
-
|
7
|
-
|
9
|
+
@@from_db_options = nil
|
10
|
+
@@to_db_options = nil
|
11
|
+
|
12
|
+
# I have a feeling this may not be quite good
|
13
|
+
@@current_table_from = nil
|
14
|
+
@@current_table_to = nil
|
15
|
+
|
16
|
+
@@current_record = Record.new
|
17
|
+
# ---
|
8
18
|
|
9
19
|
def self.setup(&block)
|
10
20
|
block.call(self)
|
11
21
|
end
|
12
22
|
|
13
|
-
|
23
|
+
def self.migrate(&block)
|
24
|
+
yield
|
25
|
+
end
|
26
|
+
|
14
27
|
def self.from_database(options = {})
|
15
|
-
puts "from"
|
16
28
|
return if options.size < 4
|
17
|
-
|
18
|
-
from_host = options[:host]
|
19
|
-
from_username = options[:username]
|
20
|
-
from_password = options[:password]
|
21
|
-
|
29
|
+
@@from_db_options = options.dup
|
22
30
|
end
|
23
31
|
|
24
32
|
def self.to_database(options = {})
|
25
|
-
puts "to"
|
26
33
|
return if options.size < 4
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
34
|
+
@@to_db_options = options.dup
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.from_db_options
|
38
|
+
@@from_db_options
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.to_db_options
|
42
|
+
@@to_db_options
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.current_table_from
|
46
|
+
@@current_table_from
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.current_table_from=(table_from)
|
50
|
+
@@current_table_from = table_from
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.current_table_to
|
54
|
+
@@current_table_to
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.current_table_to=(table_to)
|
58
|
+
@@current_table_to = table_to
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.current_record
|
62
|
+
@@current_record
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.current_record=(record_hash)
|
66
|
+
@@current_record = record_hash
|
31
67
|
end
|
32
68
|
end
|
33
|
-
|
34
|
-
def
|
35
|
-
|
69
|
+
|
70
|
+
def define_init_classes(from, to)
|
71
|
+
# create a class with the name table[:from] in the SM module
|
72
|
+
# which inherits from ActiveRecord::Base
|
73
|
+
# call the establish_connection method for this class
|
74
|
+
|
75
|
+
SuperMigration.current_table_from = from.to_s.singularize.capitalize
|
76
|
+
SM.class_eval("class #{SuperMigration.current_table_from} < ActiveRecord::Base ; establish_connection(SuperMigration.from_db_options) ; end")
|
77
|
+
|
78
|
+
# create a class with the name table[:from] in the SM module
|
79
|
+
# which inherits from ActiveRecord::Base
|
80
|
+
# call the establish_connection nethod for this class
|
81
|
+
|
82
|
+
SuperMigration.current_table_to = to.to_s.singularize.capitalize
|
83
|
+
SM.class_eval("class #{SuperMigration.current_table_to} < ActiveRecord::Base ; establish_connection(SuperMigration.to_db_options); end")
|
36
84
|
end
|
37
85
|
|
38
|
-
def
|
39
|
-
return
|
86
|
+
def table(table = {}, &block)
|
87
|
+
return unless block_given?
|
88
|
+
|
89
|
+
define_init_classes(table[:from], table[:to])
|
90
|
+
|
91
|
+
puts "Migrating data from table #{table[:from]} to table #{table[:to]}"
|
92
|
+
puts "-----------------------------------------------------------------"
|
93
|
+
|
94
|
+
yield
|
95
|
+
|
96
|
+
from_table = SuperMigration.current_table_from
|
97
|
+
to_table = SuperMigration.current_table_to
|
98
|
+
|
99
|
+
Kernel.const_get(from_table).all.collect do |record|
|
100
|
+
rc = SuperMigration.current_record.dup
|
101
|
+
new_record_hash = Hash.new
|
102
|
+
|
103
|
+
rc.fields_maps.each do |field_map|
|
104
|
+
unless record.respond_to?(field_map.from)
|
105
|
+
raise "Undefined attribute name \"#{field_map.from}\" for Model #{from_table}."
|
106
|
+
end
|
107
|
+
|
108
|
+
if field_map.block
|
109
|
+
new_record_hash[field_map.to] = field_map.block.call(record.send(field_map.from))
|
110
|
+
else
|
111
|
+
new_record_hash[field_map.to] = record.send(field_map.from)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
new_record = Kernel.const_get(to_table).new(new_record_hash)
|
115
|
+
new_record.save!
|
116
|
+
end
|
117
|
+
|
118
|
+
# reinitialize current_record
|
119
|
+
SuperMigration.current_record = Hash.new
|
120
|
+
end
|
121
|
+
|
122
|
+
def field(options = {}, &block)
|
123
|
+
return if options.size < 2
|
124
|
+
if block_given?
|
125
|
+
raise "Arity for block is not good." if block.arity != 1
|
126
|
+
end
|
127
|
+
|
128
|
+
fields_map = FieldsMap.new(options[:from], options[:to], block)
|
129
|
+
SuperMigration.current_record.fields_maps << fields_map
|
40
130
|
end
|
41
131
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: super_migration
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Cristian Prodan
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-02-
|
12
|
+
date: 2010-02-22 00:00:00 +02:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -38,6 +38,9 @@ files:
|
|
38
38
|
- README.rdoc
|
39
39
|
- Rakefile
|
40
40
|
- VERSION
|
41
|
+
- lib/entities/fields_map.rb
|
42
|
+
- lib/entities/record.rb
|
43
|
+
- lib/example.rb
|
41
44
|
- lib/super_migration.rb
|
42
45
|
- test/helper.rb
|
43
46
|
- test/test_super_migration.rb
|
@@ -58,9 +61,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
58
61
|
version:
|
59
62
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
60
63
|
requirements:
|
61
|
-
- - "
|
64
|
+
- - ">="
|
62
65
|
- !ruby/object:Gem::Version
|
63
|
-
version:
|
66
|
+
version: "0"
|
64
67
|
version:
|
65
68
|
requirements: []
|
66
69
|
|