rare_map 1.3.2 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +49 -124
- data/lib/rare_map/config_loader.rb +4 -2
- data/lib/rare_map/errors.rb +4 -0
- data/lib/rare_map/model_builder.rb +1 -5
- data/lib/rare_map/model_generator.rb +21 -17
- data/lib/rare_map/version.rb +3 -3
- data/lib/rare_map.rb +9 -24
- metadata +28 -27
data/README.rdoc
CHANGED
@@ -1,11 +1,9 @@
|
|
1
|
-
= rare_map >=
|
1
|
+
= rare_map >= 2.0.0
|
2
2
|
|
3
3
|
Relational db to ActiveREcord models MAPper
|
4
4
|
|
5
5
|
RareMap can be used for BOTH standalone application & Rails
|
6
6
|
|
7
|
-
WARN: rare_map >= 1.0.0 is totally not compatible with 0.9.x
|
8
|
-
|
9
7
|
* Installation:
|
10
8
|
|
11
9
|
gem install rare_map
|
@@ -13,63 +11,58 @@ WARN: rare_map >= 1.0.0 is totally not compatible with 0.9.x
|
|
13
11
|
== Basic RareMap use
|
14
12
|
|
15
13
|
==== Standalone:
|
16
|
-
Create a new
|
14
|
+
Create a new rare_map.yml with following lines in the root of your application
|
17
15
|
|
18
16
|
==== Rails:
|
19
|
-
|
17
|
+
Create a new config/rare_map.yml with following lines in rails
|
20
18
|
|
21
|
-
*
|
19
|
+
* rare_map.yml
|
22
20
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
database: db/db1.sqlite3
|
21
|
+
legacy:
|
22
|
+
adapter: sqlite3
|
23
|
+
database: db/db1.sqlite3
|
27
24
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
25
|
+
old_db:
|
26
|
+
adapter: mysql2
|
27
|
+
host: localhost
|
28
|
+
database: db_name
|
29
|
+
port: 3306
|
30
|
+
username: user
|
31
|
+
password: pw
|
35
32
|
|
36
33
|
* Run following command in the root of your application or rails
|
37
34
|
|
38
35
|
$ raremap
|
39
36
|
|
40
|
-
* Standalone: A demo.rb example is generated for you in the root of your
|
41
|
-
|
42
|
-
* Rails: Add following line to your config/application.rb
|
43
|
-
config.autoload_paths += Dir[Rails.root.join('app', 'models', '{**}')]
|
37
|
+
* Standalone: A demo.rb example is generated for you in the root of your application
|
44
38
|
|
45
39
|
== Advanced RareMap use
|
46
40
|
|
47
|
-
==== Seperate databases
|
41
|
+
==== Seperate databases into groups (highly recommended)
|
48
42
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
database: db/db4.sqlite3
|
43
|
+
her_group:
|
44
|
+
-
|
45
|
+
db1:
|
46
|
+
adapter: sqlite3
|
47
|
+
database: db/db1.sqlite3
|
48
|
+
-
|
49
|
+
db2:
|
50
|
+
adapter: sqlite3
|
51
|
+
database: db/db1.sqlite3
|
52
|
+
|
53
|
+
his_group:
|
54
|
+
-
|
55
|
+
db1:
|
56
|
+
adapter: sqlite3
|
57
|
+
database: db/db3.sqlite3
|
58
|
+
-
|
59
|
+
db2:
|
60
|
+
adapter: sqlite3
|
61
|
+
database: db/db4.sqlite3
|
69
62
|
|
70
63
|
There are benefits by separating databases into groups
|
71
64
|
1. Associations are built between databases within a group
|
72
|
-
2.
|
65
|
+
2. Group name is treated as a module namespace
|
73
66
|
3. Models of a group are organized within a folder
|
74
67
|
|
75
68
|
If all your data reside in several legacy databases, it is important to build back those associations across databases
|
@@ -97,92 +90,24 @@ If there are tons of tables, it is better to organize them well
|
|
97
90
|
|
98
91
|
You can place rare_map options in 3 ways
|
99
92
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
db1:
|
109
|
-
...
|
110
|
-
legacy_db:
|
111
|
-
adapter: sqlite3
|
112
|
-
database: db/db.sqlite3
|
113
|
-
rare_map_opts: # DB options
|
93
|
+
rare_map_opts: # Global options
|
94
|
+
...
|
95
|
+
group1:
|
96
|
+
-
|
97
|
+
rare_map_opts: # Group options
|
98
|
+
...
|
99
|
+
-
|
100
|
+
db1:
|
114
101
|
...
|
102
|
+
legacy_db:
|
103
|
+
adapter: sqlite3
|
104
|
+
database: db/db.sqlite3
|
105
|
+
rare_map_opts: # DB options
|
106
|
+
...
|
115
107
|
|
116
108
|
* Precedence: DB > Group > Global
|
117
109
|
|
118
110
|
|
119
|
-
= rare_map ~> 0.9.x(deprecated)
|
120
|
-
|
121
|
-
Relational DB to ActiveRecord models Mapper
|
122
|
-
|
123
|
-
* Installation:
|
124
|
-
|
125
|
-
gem install rare_map
|
126
|
-
|
127
|
-
== Basic RareMap use
|
128
|
-
|
129
|
-
Set up your legacay db under your Rails applicaiton
|
130
|
-
|
131
|
-
* database.yml
|
132
|
-
|
133
|
-
mylegacy_db1:
|
134
|
-
adapter: sqlite3
|
135
|
-
database: db/db1.sqlite3
|
136
|
-
|
137
|
-
mylegacy_db2:
|
138
|
-
adapter: sqlite3
|
139
|
-
database: db/db2/sqlite3
|
140
|
-
|
141
|
-
hislegacy_db1:
|
142
|
-
adapter: sqlite3
|
143
|
-
database: db/db1.sqlite3
|
144
|
-
|
145
|
-
"mylegacy" is treated as a group name.
|
146
|
-
|
147
|
-
You MUST give all your legacy databases a group name.
|
148
|
-
|
149
|
-
The associations of databases with the same group name will be built together.
|
150
|
-
|
151
|
-
|
152
|
-
* Create a {RAILS_ROOT}/demo.rb file with following content under your Rails application
|
153
|
-
|
154
|
-
RareMap.mapping
|
155
|
-
|
156
|
-
* Under terminal
|
157
|
-
|
158
|
-
ruby demo.rb
|
159
|
-
|
160
|
-
* Add following line to your config/application.rb
|
161
|
-
|
162
|
-
config.autoload_paths += Dir[Rails.root.join('app', 'models', '{**}')]
|
163
|
-
|
164
|
-
== Advanced RareMap use
|
165
|
-
|
166
|
-
If the foreign key of your legacy db is not end with '_id', you can change it manually.
|
167
|
-
|
168
|
-
foreign_keys = { :mylegacy => 'id', :hislegacy => 'id' }
|
169
|
-
|
170
|
-
If the foreign key is not started with regular table names, you can create aliases for them.
|
171
|
-
|
172
|
-
aliases = { :mylegacy => { :pclid => :protocol, personid => people }, :hislegacy => { :measid => measurement } }
|
173
|
-
|
174
|
-
Some of the databases like Oracle won't show the primary key on the dump of schema. If your primary key of a table is not 'id' and it didn't show the schema either. You can specify your special primary key beside 'id' if you want.
|
175
|
-
|
176
|
-
primary_keys = { :mylegacy => { :table1 => 'table1id' }, :hislegacy => { :table2 => 'table2id' } }
|
177
|
-
|
178
|
-
When you using the RareMap
|
179
|
-
|
180
|
-
info = RareMap.mapping(:foreign_key => foreign_keys, :alias => aliases, :primary_key => primary_keys)
|
181
|
-
|
182
|
-
[info]
|
183
|
-
It contains all details of your tables.
|
184
|
-
|
185
|
-
|
186
111
|
== Contributing to rare_map
|
187
112
|
|
188
113
|
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
|
@@ -1,12 +1,14 @@
|
|
1
1
|
require 'yaml'
|
2
|
+
require 'rare_map/errors'
|
2
3
|
|
3
4
|
module RareMap
|
4
5
|
module ConfigLoader
|
5
6
|
OPTS_KEY = 'rare_map_opts'
|
6
7
|
|
7
|
-
def load_config(path, file_name = '
|
8
|
+
def load_config(path, file_name = 'rare_map.yml')
|
9
|
+
raise ConfigNotFoundError unless File.exist? "#{path}#{file_name}"
|
8
10
|
config = YAML.load_file "#{path}#{file_name}"
|
9
|
-
organize_config_properties config['rare_map'] || {}
|
11
|
+
organize_config_properties config['rare_map'] || config || {}
|
10
12
|
end
|
11
13
|
|
12
14
|
private
|
@@ -13,44 +13,46 @@ module RareMap
|
|
13
13
|
models.each do |model|
|
14
14
|
output = ''
|
15
15
|
output <<
|
16
|
-
"
|
17
|
-
"
|
18
|
-
"
|
19
|
-
"
|
20
|
-
"
|
16
|
+
"module #{model.group.camelize}\n" <<
|
17
|
+
" class #{model.classify} < #{group_db2conn[[model.group, model.db_name]]}\n" <<
|
18
|
+
" self.table_name = '#{model.table.name}'\n" <<
|
19
|
+
" self.inheritance_column = 'ruby_type'\n" <<
|
20
|
+
" #{ "self.primary_key = '#{model.table.primary_key}'\n" if model.table.primary_key }\n" <<
|
21
|
+
" attr_accessible #{model.table.columns.map { |col| ":#{col.name}" }.join(', ')}\n\n"
|
21
22
|
|
22
23
|
belongs_to = model.relations.select { |rel| rel.type == :belongs_to }
|
23
24
|
unless belongs_to.empty?
|
24
25
|
output << belongs_to.
|
25
|
-
map { |rel| "
|
26
|
+
map { |rel| " belongs_to :#{rel.table.pluralize.singularize}, :foreign_key => '#{rel.foreign_key}', :class_name => '#{classify_by_table(rel.table, model, models)}'" }.
|
26
27
|
join("\n") << "\n"
|
27
28
|
end
|
28
29
|
|
29
30
|
has_one = model.relations.select { |rel| rel.type == :has_one }
|
30
31
|
unless has_one.empty?
|
31
32
|
output << has_one.
|
32
|
-
map { |rel| "
|
33
|
+
map { |rel| " has_one :#{rel.table.pluralize.singularize}, :foreign_key => '#{rel.foreign_key}', :class_name => '#{classify_by_table(rel.table, model, models)}'" }.
|
33
34
|
join("\n") << "\n"
|
34
35
|
end
|
35
36
|
|
36
37
|
has_many = model.relations.select { |rel| rel.type == :has_many }
|
37
38
|
unless has_many.empty?
|
38
39
|
output << has_many.
|
39
|
-
map { |rel| "
|
40
|
+
map { |rel| " has_many :#{rel.table.pluralize}, :foreign_key => '#{rel.foreign_key}', :class_name => '#{classify_by_table(rel.table, model, models)}'" }.
|
40
41
|
join("\n") << "\n"
|
41
42
|
end
|
42
43
|
|
43
44
|
has_many_through = model.relations.select { |rel| rel.type == :has_many_through }
|
44
45
|
unless has_many_through.empty?
|
45
46
|
output << has_many_through.
|
46
|
-
map { |rel| "
|
47
|
+
map { |rel| " has_many :#{rel.table.pluralize}#{"_by_#{rel.through}, :source => :#{rel.table.pluralize.singularize}" if has_many_through.count { |hmt| hmt.table == rel.table } > 1 || has_many.count { |hm| hm.table == rel.table } > 0 }, :through => :#{rel.through.pluralize}, :foreign_key => '#{rel.foreign_key}', :class_name => '#{classify_by_table(rel.table, model, models)}'" }.
|
47
48
|
join("\n") << "\n"
|
48
49
|
end
|
49
50
|
|
51
|
+
output << " end\n"
|
50
52
|
output << 'end'
|
51
53
|
|
52
|
-
Dir.mkdir path + "#{model.group}" unless Dir.exist? path + "#{model.group}"
|
53
|
-
f = File.new(path + "#{model.group}/#{model.classify.underscore}.rb", 'w')
|
54
|
+
Dir.mkdir path + "#{model.group.underscore}" unless Dir.exist? path + "#{model.group}"
|
55
|
+
f = File.new(path + "#{model.group.underscore}/#{model.classify.underscore}.rb", 'w')
|
54
56
|
f.write output
|
55
57
|
f.close
|
56
58
|
end
|
@@ -71,18 +73,20 @@ module RareMap
|
|
71
73
|
|
72
74
|
group2connection = Hash[models.map { |model| [[model.group, model.db_name], [model.connection, model.table.name]] }]
|
73
75
|
group2connection.each do |(group, db_name), (connection, table_name)|
|
74
|
-
model = "#{
|
76
|
+
model = "#{db_name}".camelize + 'Base'
|
75
77
|
|
76
78
|
output = ''
|
77
79
|
output <<
|
78
|
-
"
|
79
|
-
"
|
80
|
-
"
|
80
|
+
"module #{group.camelize}\n" <<
|
81
|
+
" class #{model} < ActiveRecord::Base\n" <<
|
82
|
+
" establish_connection #{connection.map { |k, v| ":#{k} => #{v.inspect}" }.join(', ')}\n" <<
|
83
|
+
" self.table_name = '#{table_name}'\n" <<
|
84
|
+
" end\n" <<
|
81
85
|
'end'
|
82
86
|
|
83
87
|
|
84
|
-
Dir.mkdir path + "#{group}" unless Dir.exist? path + "#{group}"
|
85
|
-
f = File.new(path + "#{group}/#{model.underscore}.rb", 'w')
|
88
|
+
Dir.mkdir path + "#{group.underscore}" unless Dir.exist? path + "#{group}"
|
89
|
+
f = File.new(path + "#{group.underscore}/#{model.underscore}.rb", 'w')
|
86
90
|
f.write output
|
87
91
|
f.close
|
88
92
|
|
data/lib/rare_map/version.rb
CHANGED
data/lib/rare_map.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
# $:.unshift File.dirname(__FILE__)
|
2
|
-
|
3
1
|
require 'rare_map/rails_locator'
|
4
2
|
require 'rare_map/config_loader'
|
5
3
|
require 'rare_map/schema_reader'
|
@@ -28,17 +26,19 @@ module RareMap
|
|
28
26
|
@models = build_models @db_profiles
|
29
27
|
generate_models @models, @rails_root
|
30
28
|
if @rails_root
|
31
|
-
puts '
|
32
|
-
puts '
|
33
|
-
puts '
|
34
|
-
create_initializer
|
29
|
+
puts '*****************************************************************'
|
30
|
+
puts ' Activerecord models are generated. Enjoy it!'
|
31
|
+
puts '*****************************************************************'
|
35
32
|
else
|
36
|
-
puts '
|
37
|
-
puts ' A demo.rb is generated'
|
38
|
-
puts '
|
33
|
+
puts '*****************************************************************'
|
34
|
+
puts ' A demo.rb is generated.'
|
35
|
+
puts '*****************************************************************'
|
39
36
|
generate_demo unless File.exist?('demo.rb')
|
40
37
|
end
|
41
38
|
@models
|
39
|
+
|
40
|
+
rescue ConfigNotFoundError => e
|
41
|
+
puts "Please put your database config in `#{'config/' if @rails_root}rare_map.yml`."
|
42
42
|
end
|
43
43
|
|
44
44
|
private
|
@@ -50,21 +50,6 @@ module RareMap
|
|
50
50
|
f.write "Dir[File.dirname(__FILE__) + '/app/models/**/*.rb'].each { |file| require file }\n"
|
51
51
|
f.close
|
52
52
|
end
|
53
|
-
|
54
|
-
def create_initializer
|
55
|
-
f = File.new(@rails_root + 'config/initializers/rare_map.rb', 'w')
|
56
|
-
f.write "bases = []; models = []\n"
|
57
|
-
f.write "Dir[Rails.root + 'app/models/**/*.rb'].each do |file|\n"
|
58
|
-
f.write " if file =~ /models\\/[^\\/]+\\/[^\\/]+_base.rb$/\n"
|
59
|
-
f.write " bases << file\n"
|
60
|
-
f.write " elsif file =~ /models\\/[^\\/]+\\/[^\\/]+.rb$/\n"
|
61
|
-
f.write " models << file\n"
|
62
|
-
f.write " end\n"
|
63
|
-
f.write "end\n"
|
64
|
-
f.write "bases.map { |b| require b }\n"
|
65
|
-
f.write "models.map { |m| require m }\n"
|
66
|
-
f.close
|
67
|
-
end
|
68
53
|
end
|
69
54
|
end
|
70
55
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rare_map
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -16,39 +16,39 @@ dependencies:
|
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
|
-
- -
|
19
|
+
- - ~>
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version: 3.2.
|
21
|
+
version: 3.2.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
25
|
none: false
|
26
26
|
requirements:
|
27
|
-
- -
|
27
|
+
- - ~>
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version: 3.2.
|
29
|
+
version: 3.2.0
|
30
30
|
- !ruby/object:Gem::Dependency
|
31
31
|
name: activesupport
|
32
32
|
requirement: !ruby/object:Gem::Requirement
|
33
33
|
none: false
|
34
34
|
requirements:
|
35
|
-
- -
|
35
|
+
- - ~>
|
36
36
|
- !ruby/object:Gem::Version
|
37
|
-
version: 3.2.
|
37
|
+
version: 3.2.0
|
38
38
|
type: :runtime
|
39
39
|
prerelease: false
|
40
40
|
version_requirements: !ruby/object:Gem::Requirement
|
41
41
|
none: false
|
42
42
|
requirements:
|
43
|
-
- -
|
43
|
+
- - ~>
|
44
44
|
- !ruby/object:Gem::Version
|
45
|
-
version: 3.2.
|
45
|
+
version: 3.2.0
|
46
46
|
- !ruby/object:Gem::Dependency
|
47
47
|
name: shoulda
|
48
48
|
requirement: !ruby/object:Gem::Requirement
|
49
49
|
none: false
|
50
50
|
requirements:
|
51
|
-
- -
|
51
|
+
- - ~>
|
52
52
|
- !ruby/object:Gem::Version
|
53
53
|
version: 3.3.2
|
54
54
|
type: :development
|
@@ -56,7 +56,7 @@ dependencies:
|
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
57
57
|
none: false
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - ~>
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: 3.3.2
|
62
62
|
- !ruby/object:Gem::Dependency
|
@@ -64,7 +64,7 @@ dependencies:
|
|
64
64
|
requirement: !ruby/object:Gem::Requirement
|
65
65
|
none: false
|
66
66
|
requirements:
|
67
|
-
- -
|
67
|
+
- - ~>
|
68
68
|
- !ruby/object:Gem::Version
|
69
69
|
version: '3.12'
|
70
70
|
type: :development
|
@@ -72,7 +72,7 @@ dependencies:
|
|
72
72
|
version_requirements: !ruby/object:Gem::Requirement
|
73
73
|
none: false
|
74
74
|
requirements:
|
75
|
-
- -
|
75
|
+
- - ~>
|
76
76
|
- !ruby/object:Gem::Version
|
77
77
|
version: '3.12'
|
78
78
|
- !ruby/object:Gem::Dependency
|
@@ -80,33 +80,33 @@ dependencies:
|
|
80
80
|
requirement: !ruby/object:Gem::Requirement
|
81
81
|
none: false
|
82
82
|
requirements:
|
83
|
-
- -
|
83
|
+
- - ~>
|
84
84
|
- !ruby/object:Gem::Version
|
85
|
-
version: 1.
|
85
|
+
version: '1.3'
|
86
86
|
type: :development
|
87
87
|
prerelease: false
|
88
88
|
version_requirements: !ruby/object:Gem::Requirement
|
89
89
|
none: false
|
90
90
|
requirements:
|
91
|
-
- -
|
91
|
+
- - ~>
|
92
92
|
- !ruby/object:Gem::Version
|
93
|
-
version: 1.
|
93
|
+
version: '1.3'
|
94
94
|
- !ruby/object:Gem::Dependency
|
95
95
|
name: rake
|
96
96
|
requirement: !ruby/object:Gem::Requirement
|
97
97
|
none: false
|
98
98
|
requirements:
|
99
|
-
- -
|
99
|
+
- - '>='
|
100
100
|
- !ruby/object:Gem::Version
|
101
|
-
version:
|
101
|
+
version: '0'
|
102
102
|
type: :development
|
103
103
|
prerelease: false
|
104
104
|
version_requirements: !ruby/object:Gem::Requirement
|
105
105
|
none: false
|
106
106
|
requirements:
|
107
|
-
- -
|
107
|
+
- - '>='
|
108
108
|
- !ruby/object:Gem::Version
|
109
|
-
version:
|
109
|
+
version: '0'
|
110
110
|
description: Relational db to ActiveREcord models MAPper
|
111
111
|
email: wnameless@gmail.com
|
112
112
|
executables:
|
@@ -115,6 +115,7 @@ extensions: []
|
|
115
115
|
extra_rdoc_files: []
|
116
116
|
files:
|
117
117
|
- lib/rare_map/config_loader.rb
|
118
|
+
- lib/rare_map/errors.rb
|
118
119
|
- lib/rare_map/model_builder.rb
|
119
120
|
- lib/rare_map/model_generator.rb
|
120
121
|
- lib/rare_map/rails_locator.rb
|
@@ -138,27 +139,27 @@ require_paths:
|
|
138
139
|
required_ruby_version: !ruby/object:Gem::Requirement
|
139
140
|
none: false
|
140
141
|
requirements:
|
141
|
-
- -
|
142
|
+
- - '>='
|
142
143
|
- !ruby/object:Gem::Version
|
143
144
|
version: '0'
|
144
145
|
segments:
|
145
146
|
- 0
|
146
|
-
hash:
|
147
|
+
hash: 2598832910408143833
|
147
148
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
148
149
|
none: false
|
149
150
|
requirements:
|
150
|
-
- -
|
151
|
+
- - '>='
|
151
152
|
- !ruby/object:Gem::Version
|
152
153
|
version: '0'
|
153
154
|
segments:
|
154
155
|
- 0
|
155
|
-
hash:
|
156
|
+
hash: 2598832910408143833
|
156
157
|
requirements: []
|
157
158
|
rubyforge_project:
|
158
|
-
rubygems_version: 1.8.
|
159
|
+
rubygems_version: 1.8.25
|
159
160
|
signing_key:
|
160
161
|
specification_version: 3
|
161
|
-
summary: rare_map-
|
162
|
+
summary: rare_map-2.0.0
|
162
163
|
test_files:
|
163
164
|
- test/helper.rb
|
164
165
|
- test/test_rare_map.rb
|