legacy_data 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/README.rdoc +1 -1
- data/VERSION +1 -1
- data/generators/models_from_tables/models_from_tables_generator.rb +12 -15
- data/generators/models_from_tables/templates/model.rb +7 -2
- data/legacy_data.gemspec +15 -3
- data/lib/legacy_data/schema.rb +59 -17
- data/lib/legacy_data/table_class_name_mapper.rb +15 -0
- data/spec/expected/post.rb +14 -0
- data/spec/functional/expected/comment.rb +13 -0
- data/spec/functional/expected/post.rb +13 -0
- data/spec/functional/functional_spec_helper.rb +13 -0
- data/spec/functional/models_from_tables_spec.rb +26 -0
- data/spec/legacy_data/schema_spec.rb +32 -7
- data/spec/legacy_data/table_class_name_mapper_spec.rb +1 -1
- data/spec/models_from_tables_generator_spec.rb +42 -0
- data/spec/spec_helper.rb +29 -4
- metadata +14 -2
data/.gitignore
CHANGED
data/README.rdoc
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.1
|
@@ -1,7 +1,8 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/../../lib/legacy_data
|
2
|
-
require File.dirname(__FILE__) + '/../../lib/legacy_data/
|
3
|
-
require File.dirname(__FILE__) + '/../../lib/legacy_data/
|
4
|
-
require File.dirname(__FILE__) + '/../../lib/
|
1
|
+
require File.dirname(__FILE__) + '/../../lib/legacy_data'
|
2
|
+
# require File.dirname(__FILE__) + '/../../lib/legacy_data/table_definition'
|
3
|
+
# require File.dirname(__FILE__) + '/../../lib/legacy_data/schema'
|
4
|
+
# require File.dirname(__FILE__) + '/../../lib/legacy_data/table_class_name_mapper'
|
5
|
+
# require File.dirname(__FILE__) + '/../../lib/active_record/connection_adapters/oracle_enhanced_adapter'
|
5
6
|
|
6
7
|
class ModelsFromTablesGenerator < Rails::Generator::Base
|
7
8
|
def manifest
|
@@ -10,15 +11,9 @@ class ModelsFromTablesGenerator < Rails::Generator::Base
|
|
10
11
|
|
11
12
|
LegacyData::TableClassNameMapper.naming_convention = options[:table_naming_convention]
|
12
13
|
|
13
|
-
analyzed_tables = LegacyData::Schema.analyze(
|
14
|
-
|
15
|
-
|
16
|
-
Done analyzing the tables.
|
17
|
-
Please review the class names shown above. If any do not look correct (for example it did not separate the words with CamelCase) please supply the correct mappings by editing the file #{LegacyData::TableClassNameMapper.dictionary_file_name}.
|
18
|
-
Once you're done hit <enter> to continue generating the models"
|
19
|
-
MSG
|
20
|
-
gets
|
21
|
-
LegacyData::TableClassNameMapper.load_dictionary
|
14
|
+
analyzed_tables = LegacyData::Schema.analyze(options)
|
15
|
+
|
16
|
+
LegacyData::TableClassNameMapper.let_user_validate_dictionary
|
22
17
|
|
23
18
|
analyzed_tables.each do |analyzed_table|
|
24
19
|
analyzed_table.class_name = LegacyData::TableClassNameMapper.class_name_for(analyzed_table[:table_name])
|
@@ -28,8 +23,8 @@ Done analyzing the tables.
|
|
28
23
|
:assigns => analyzed_table.to_hash
|
29
24
|
end
|
30
25
|
end
|
31
|
-
|
32
|
-
|
26
|
+
# rescue => e
|
27
|
+
# puts e.backtrace
|
33
28
|
end
|
34
29
|
|
35
30
|
protected
|
@@ -38,6 +33,8 @@ protected
|
|
38
33
|
'Only generate models for given table') { |value| options[:table_name] = value }
|
39
34
|
opt.on('--table-naming-convention [ARG]',
|
40
35
|
'Naming convention for tables in the database - will not be used when generating naming the models') { |value| options[:table_naming_convention] = value }
|
36
|
+
opt.on('--skip-associated',
|
37
|
+
'Do not follow foreign keys to model associated tables') { |value| options[:skip_associated] = true }
|
41
38
|
end
|
42
39
|
|
43
40
|
end
|
@@ -16,11 +16,15 @@ class <%= class_name -%> < ActiveRecord::Base
|
|
16
16
|
-%>
|
17
17
|
|
18
18
|
# Constraints
|
19
|
-
<%= "validates_uniqueness_of #{constraints[:unique ].map {|cols| cols.
|
19
|
+
<%= "validates_uniqueness_of #{constraints[:unique ].map {|cols| cols.downcase.to_sym.inspect}.join(', ')}" unless constraints[:unique].blank? %>
|
20
20
|
<%- constraints[:multi_column_unique].each do |cols|
|
21
21
|
-%> #validates_uniqueness_of_multiple_column_constraint :<%= cols.inspect %>
|
22
22
|
<%- end -%>
|
23
|
-
<%= "validates_presence_of #{constraints[:
|
23
|
+
<%= "validates_presence_of #{constraints[:presence_of].map {|cols| cols.downcase.to_sym.inspect}.join(', ')}" unless constraints[:presence_of].blank? %>
|
24
|
+
<%- constraints[:boolean_presence].each do |col|
|
25
|
+
-%> validates_inclusion_of <%= col %>, :in => %w(true false)
|
26
|
+
<%- end -%>
|
27
|
+
<%= "validates_numericality_of #{constraints[:numericality_of].map {|cols| cols.downcase.to_sym.inspect}.join(', ')}" unless constraints[:numericality_of].blank? %>
|
24
28
|
<%- constraints[:custom].each do |name, sql_rule|
|
25
29
|
-%> validate <%= "validate_#{name}".to_sym.inspect %>
|
26
30
|
def <%= "validate_#{name}" %>
|
@@ -29,3 +33,4 @@ class <%= class_name -%> < ActiveRecord::Base
|
|
29
33
|
end
|
30
34
|
<%- end %>
|
31
35
|
end
|
36
|
+
|
data/legacy_data.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{legacy_data}
|
8
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.1"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Alex Rothenberg"]
|
12
|
-
s.date = %q{2009-10-
|
12
|
+
s.date = %q{2009-10-08}
|
13
13
|
s.description = %q{Create ActiveRecord models from an existing database}
|
14
14
|
s.email = %q{alex@alexrothenberg.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -33,9 +33,15 @@ Gem::Specification.new do |s|
|
|
33
33
|
"lib/legacy_data/schema.rb",
|
34
34
|
"lib/legacy_data/table_class_name_mapper.rb",
|
35
35
|
"lib/legacy_data/table_definition.rb",
|
36
|
+
"spec/expected/post.rb",
|
37
|
+
"spec/functional/expected/comment.rb",
|
38
|
+
"spec/functional/expected/post.rb",
|
39
|
+
"spec/functional/functional_spec_helper.rb",
|
40
|
+
"spec/functional/models_from_tables_spec.rb",
|
36
41
|
"spec/legacy_data/schema_spec.rb",
|
37
42
|
"spec/legacy_data/table_class_name_mapper_spec.rb",
|
38
43
|
"spec/legacy_data/table_definition_spec.rb",
|
44
|
+
"spec/models_from_tables_generator_spec.rb",
|
39
45
|
"spec/spec_helper.rb"
|
40
46
|
]
|
41
47
|
s.has_rdoc = true
|
@@ -45,9 +51,15 @@ Gem::Specification.new do |s|
|
|
45
51
|
s.rubygems_version = %q{1.3.2}
|
46
52
|
s.summary = %q{Create ActiveRecord models from an existing database}
|
47
53
|
s.test_files = [
|
48
|
-
"spec/
|
54
|
+
"spec/expected/post.rb",
|
55
|
+
"spec/functional/expected/comment.rb",
|
56
|
+
"spec/functional/expected/post.rb",
|
57
|
+
"spec/functional/functional_spec_helper.rb",
|
58
|
+
"spec/functional/models_from_tables_spec.rb",
|
59
|
+
"spec/legacy_data/schema_spec.rb",
|
49
60
|
"spec/legacy_data/table_class_name_mapper_spec.rb",
|
50
61
|
"spec/legacy_data/table_definition_spec.rb",
|
62
|
+
"spec/models_from_tables_generator_spec.rb",
|
51
63
|
"spec/spec_helper.rb"
|
52
64
|
]
|
53
65
|
|
data/lib/legacy_data/schema.rb
CHANGED
@@ -8,14 +8,16 @@ module LegacyData
|
|
8
8
|
while table_name = next_table_to_process
|
9
9
|
table_definitions[table_name] = analyze_table(table_name)
|
10
10
|
|
11
|
-
[:
|
12
|
-
|
13
|
-
|
11
|
+
unless options[:skip_associated]
|
12
|
+
[:has_many, :belongs_to].each do |relation_type|
|
13
|
+
associated_tables = table_definitions[table_name][:relations][relation_type].keys.map(&:to_s)
|
14
|
+
associated_tables.each {|associated_table| add_pending_table(associated_table) }
|
15
|
+
end
|
14
16
|
end
|
15
17
|
end
|
16
|
-
|
17
18
|
remove_join_tables
|
18
19
|
end
|
20
|
+
|
19
21
|
def self.analyze_table table_name
|
20
22
|
new(table_name).analyze_table
|
21
23
|
end
|
@@ -62,7 +64,7 @@ module LegacyData
|
|
62
64
|
end
|
63
65
|
|
64
66
|
def analyze_table
|
65
|
-
|
67
|
+
log "analyzing #{table_name} => #{class_name}"
|
66
68
|
TableDefinition.new(:table_name => table_name,
|
67
69
|
:columns => column_names,
|
68
70
|
:primary_key => primary_key,
|
@@ -80,8 +82,11 @@ module LegacyData
|
|
80
82
|
end
|
81
83
|
|
82
84
|
def primary_key
|
83
|
-
|
84
|
-
|
85
|
+
if connection.respond_to?(:pk_and_sequence_for)
|
86
|
+
pk = connection.pk_and_sequence_for(table_name).first
|
87
|
+
elsif connection.respond_to?(:primary_key)
|
88
|
+
pk = connection.primary_key(table_name)
|
89
|
+
end
|
85
90
|
end
|
86
91
|
|
87
92
|
def relations
|
@@ -92,7 +97,7 @@ module LegacyData
|
|
92
97
|
end
|
93
98
|
|
94
99
|
def belongs_to_relations
|
95
|
-
return
|
100
|
+
return {} unless connection.respond_to? :foreign_keys_for
|
96
101
|
|
97
102
|
belongs_to = {}
|
98
103
|
connection.foreign_keys_for(table_name).each do |relation|
|
@@ -101,7 +106,7 @@ module LegacyData
|
|
101
106
|
belongs_to
|
102
107
|
end
|
103
108
|
def has_some_relations
|
104
|
-
return
|
109
|
+
return {} unless connection.respond_to? :foreign_keys_of
|
105
110
|
|
106
111
|
has_some = {}
|
107
112
|
connection.foreign_keys_of(table_name).each do |relation|
|
@@ -111,14 +116,44 @@ module LegacyData
|
|
111
116
|
end
|
112
117
|
|
113
118
|
def constraints
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
:
|
118
|
-
:
|
119
|
-
|
119
|
+
if @constraints.nil?
|
120
|
+
@constraints = {}
|
121
|
+
|
122
|
+
@constraints[:unique], @constraints[:multi_column_unique] = uniqueness_constraints
|
123
|
+
@constraints[:boolean_presence], @constraints[:presence_of] = presence_constraints
|
124
|
+
@constraints[:numericality_of] = integer_column_names
|
125
|
+
@constraints[:custom] = custom_constraints
|
126
|
+
end
|
127
|
+
@constraints
|
128
|
+
##### TO DO
|
129
|
+
# presence_of schoolparentid => school_parent - FOREIGN KEY
|
130
|
+
# # booleans presence_of => inclusion_of
|
131
|
+
# integer numericality_of - INTEGER COLUMNS (except foreign keys)
|
132
|
+
# custom /(.*) IN \(.*\)/i => inclusion_of $1, :in=> %w($2) -- TRY TO PARSE CUSTOM SQL RULES
|
133
|
+
#
|
120
134
|
end
|
121
135
|
|
136
|
+
def uniqueness_constraints
|
137
|
+
unique, multi_column_unique = unique_constraints.partition do |columns|
|
138
|
+
columns.size == 1
|
139
|
+
end
|
140
|
+
[unique.map(&:first), multi_column_unique]
|
141
|
+
end
|
142
|
+
|
143
|
+
def presence_constraints
|
144
|
+
boolean_presence, presence_of = non_nullable_constraints.partition do |column_name|
|
145
|
+
column_by_name(column_name).type == :boolean
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def column_by_name name
|
150
|
+
columns.detect {|column| column.name == name }
|
151
|
+
end
|
152
|
+
|
153
|
+
def integer_column_names
|
154
|
+
columns.select {|column| column.type == :integer }.map &:name
|
155
|
+
end
|
156
|
+
|
122
157
|
def columns
|
123
158
|
@columns ||= connection.columns(table_name, "#{table_name} Columns")
|
124
159
|
end
|
@@ -142,6 +177,14 @@ module LegacyData
|
|
142
177
|
end
|
143
178
|
user_constraints
|
144
179
|
end
|
180
|
+
|
181
|
+
def log msg
|
182
|
+
self.class.log msg
|
183
|
+
end
|
184
|
+
def self.log msg
|
185
|
+
puts msg
|
186
|
+
end
|
187
|
+
|
145
188
|
private
|
146
189
|
def self.connection
|
147
190
|
@conn ||= ActiveRecord::Base.connection
|
@@ -149,7 +192,6 @@ module LegacyData
|
|
149
192
|
def connection
|
150
193
|
self.class.connection
|
151
194
|
end
|
152
|
-
|
153
|
-
|
195
|
+
|
154
196
|
end
|
155
197
|
end
|
@@ -29,6 +29,17 @@ module LegacyData
|
|
29
29
|
YAML.dump(dictionary, out)
|
30
30
|
end
|
31
31
|
end
|
32
|
+
|
33
|
+
def let_user_validate_dictionary
|
34
|
+
save_dictionary
|
35
|
+
self.class.log <<-MSG
|
36
|
+
Done analyzing the tables.
|
37
|
+
Please review the class names shown above. If any do not look correct (for example it did not separate the words with CamelCase) please supply the correct mappings by editing the file #{LegacyData::TableClassNameMapper.dictionary_file_name}.
|
38
|
+
Once you're done hit <enter> to continue generating the models"
|
39
|
+
MSG
|
40
|
+
gets
|
41
|
+
load_dictionary
|
42
|
+
end
|
32
43
|
|
33
44
|
def dictionary_file_name
|
34
45
|
File.join(RAILS_ROOT, 'app', 'models', 'table_mappings.yml')
|
@@ -47,6 +58,10 @@ module LegacyData
|
|
47
58
|
stripped_table_name = $1 || table_name
|
48
59
|
dictionary[table_name] = ActiveRecord::Base.class_name(stripped_table_name.downcase.pluralize)
|
49
60
|
end
|
61
|
+
|
62
|
+
def self.log msg
|
63
|
+
puts msg
|
64
|
+
end
|
50
65
|
end
|
51
66
|
|
52
67
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
ActiveRecord::Base.establish_connection({:adapter=>'sqlite3', :database=> ":memory:"})
|
4
|
+
|
5
|
+
ActiveRecord::Base.connection.create_table :posts do |t|
|
6
|
+
t.string :title
|
7
|
+
t.text :body
|
8
|
+
end
|
9
|
+
ActiveRecord::Base.connection.create_table :comments do |t|
|
10
|
+
t.integer :post_id
|
11
|
+
t.text :body
|
12
|
+
end
|
13
|
+
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/functional_spec_helper')
|
2
|
+
|
3
|
+
describe 'Models From Tables generator' do
|
4
|
+
before :all do
|
5
|
+
silence_warnings { RAILS_ROOT = File.expand_path(File.dirname(__FILE__) + '/../../output/functional') }
|
6
|
+
FileUtils.mkdir_p(RAILS_ROOT + '/app/models')
|
7
|
+
|
8
|
+
LegacyData::Schema.stub!(:log)
|
9
|
+
end
|
10
|
+
after :all do
|
11
|
+
Object.send(:remove_const, :RAILS_ROOT)
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'should generate a posts model' do
|
15
|
+
invoke_generator('models_from_tables', ["--table-name", "posts"], :create)
|
16
|
+
|
17
|
+
File.read(RAILS_ROOT + '/app/models/post.rb').should == File.read(File.expand_path(File.dirname(__FILE__) + '/expected/post.rb'))
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'should generate all models in database' do
|
21
|
+
invoke_generator('models_from_tables', [], :create)
|
22
|
+
|
23
|
+
File.read(RAILS_ROOT + '/app/models/post.rb').should == File.read(File.expand_path(File.dirname(__FILE__) + '/expected/post.rb'))
|
24
|
+
File.read(RAILS_ROOT + '/app/models/comment.rb').should == File.read(File.expand_path(File.dirname(__FILE__) + '/expected/comment.rb'))
|
25
|
+
end
|
26
|
+
end
|
@@ -40,7 +40,7 @@ describe LegacyData::Schema do
|
|
40
40
|
describe 'analyzing a table' do
|
41
41
|
before :each do
|
42
42
|
@schema = LegacyData::Schema.new('some_table')
|
43
|
-
@schema.stub!(:
|
43
|
+
@schema.stub!(:log)
|
44
44
|
end
|
45
45
|
|
46
46
|
it 'should have all the information about the table' do
|
@@ -86,7 +86,7 @@ describe LegacyData::Schema do
|
|
86
86
|
|
87
87
|
it 'should give no "has_some" (has_many and has_one) relationships when the adapter does not support foreign keys' do
|
88
88
|
@connection.should_receive(:respond_to?).with(:foreign_keys_of).and_return(false)
|
89
|
-
@schema.has_some_relations.should ==
|
89
|
+
@schema.has_some_relations.should == {}
|
90
90
|
end
|
91
91
|
|
92
92
|
it 'should get all "has_some" (has_many and has_one) relationships when my primary key is the foreign key in another table ' do
|
@@ -99,7 +99,7 @@ describe LegacyData::Schema do
|
|
99
99
|
|
100
100
|
it 'should give no "belongs_to" when the adapter does not support foreign keys' do
|
101
101
|
@connection.should_receive(:respond_to?).with(:foreign_keys_for).and_return(false)
|
102
|
-
@schema.belongs_to_relations.should ==
|
102
|
+
@schema.belongs_to_relations.should == {}
|
103
103
|
end
|
104
104
|
|
105
105
|
it 'should get all "belongs_to" relationships when a foreign key is in my table' do
|
@@ -112,11 +112,36 @@ describe LegacyData::Schema do
|
|
112
112
|
|
113
113
|
describe 'constraints' do
|
114
114
|
it 'should have the different types of constraints' do
|
115
|
-
@schema.stub!(:
|
116
|
-
@schema.stub!(:
|
117
|
-
@schema.stub!(:
|
115
|
+
@schema.stub!(:uniqueness_constraints).and_return([unique =[mock], multi_column_unique=[mock]])
|
116
|
+
@schema.stub!(:presence_constraints ).and_return([boolean_presence=[mock], presence_of =[mock]])
|
117
|
+
@schema.stub!(:integer_column_names ).and_return(int_col_names =[mock])
|
118
|
+
@schema.stub!(:custom_constraints ).and_return(custom =[mock])
|
118
119
|
|
119
|
-
@schema.constraints.should == {:unique=>
|
120
|
+
@schema.constraints.should == {:unique =>unique,
|
121
|
+
:multi_column_unique=>multi_column_unique,
|
122
|
+
:boolean_presence =>boolean_presence,
|
123
|
+
:presence_of =>presence_of,
|
124
|
+
:numericality_of =>int_col_names,
|
125
|
+
:custom =>custom }
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'should have the uniqueness constraints (booleans are done differently)' do
|
129
|
+
@schema.stub!(:unique_constraints ).and_return([['unique_col'],
|
130
|
+
['col1', 'col2'],
|
131
|
+
['another_col'],
|
132
|
+
['col3', 'col4']])
|
133
|
+
|
134
|
+
@schema.uniqueness_constraints.should == [ ['unique_col' , 'another_col' ],
|
135
|
+
[['col1', 'col2'], ['col3', 'col4']]
|
136
|
+
]
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'should have the different types of constraints' do
|
140
|
+
@schema.stub!(:non_nullable_constraints).and_return(['int_col', 'bool_col'])
|
141
|
+
@schema.stub!(:column_by_name ).with('int_col' ).and_return(stub(:type=>:integer))
|
142
|
+
@schema.stub!(:column_by_name ).with('bool_col').and_return(stub(:type=>:boolean))
|
143
|
+
|
144
|
+
@schema.presence_constraints.should == [ ['bool_col'], ['int_col']]
|
120
145
|
end
|
121
146
|
|
122
147
|
it 'should get non-nullable constraints as all columns that do not allow null except the primary key' do
|
@@ -59,7 +59,7 @@ describe LegacyData::TableClassNameMapper do
|
|
59
59
|
|
60
60
|
describe 'persisting the dictionary' do
|
61
61
|
before :each do
|
62
|
-
RAILS_ROOT = 'test_rails_root'
|
62
|
+
silence_warnings { RAILS_ROOT = 'test_rails_root' }
|
63
63
|
@dictionary_file_name = LegacyData::TableClassNameMapper.dictionary_file_name
|
64
64
|
end
|
65
65
|
after :each do
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe 'Models From Tables generator' do
|
4
|
+
before :all do
|
5
|
+
silence_warnings { RAILS_ROOT = File.expand_path(File.dirname(__FILE__) + '/../../output') }
|
6
|
+
FileUtils.mkdir_p(RAILS_ROOT + '/app/models')
|
7
|
+
end
|
8
|
+
after :all do
|
9
|
+
Object.send(:remove_const, :RAILS_ROOT)
|
10
|
+
end
|
11
|
+
|
12
|
+
before :each do
|
13
|
+
@posts = LegacyData::TableDefinition.new( :class_name => 'Posts',
|
14
|
+
:table_name => 'posts',
|
15
|
+
:columns => ['title', 'body'],
|
16
|
+
:primary_key => 'id',
|
17
|
+
:relations => { :has_many =>{'comments'=>{:foreign_key=>'comment_id'}},
|
18
|
+
:belongs_to =>{},
|
19
|
+
:has_and_belongs_to_many=>[]
|
20
|
+
},
|
21
|
+
:constraints => { :unique =>['title'],
|
22
|
+
:multi_column_unique=>[],
|
23
|
+
:boolean_presence =>[],
|
24
|
+
:presence_of =>['body'],
|
25
|
+
:numericality_of =>[],
|
26
|
+
:custom =>[]
|
27
|
+
}
|
28
|
+
)
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should generate a posts model' do
|
33
|
+
LegacyData::Schema.should_receive(:analyze).with(hash_including(:table_name=>'posts')).and_return([@posts])
|
34
|
+
LegacyData::TableClassNameMapper.should_receive(:let_user_validate_dictionary)
|
35
|
+
LegacyData::TableClassNameMapper.stub!(:class_name_for).with('posts' ).and_return('Post')
|
36
|
+
LegacyData::TableClassNameMapper.stub!(:class_name_for).with('comments').and_return('Comment')
|
37
|
+
|
38
|
+
invoke_generator('models_from_tables', ["--table-name", "posts"], :create)
|
39
|
+
|
40
|
+
File.read(RAILS_ROOT + '/app/models/post.rb').should == File.read(File.expand_path(File.dirname(__FILE__) + '/expected/post.rb'))
|
41
|
+
end
|
42
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,15 +1,40 @@
|
|
1
|
-
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
|
-
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
1
|
require 'rubygems'
|
4
|
-
gem 'activerecord'
|
5
|
-
gem 'activerecord-oracle_enhanced-adapter'
|
6
2
|
require 'activerecord'
|
7
3
|
require 'active_record/connection_adapters/oracle_enhanced_adapter'
|
8
4
|
|
5
|
+
# $LOAD_PATH.unshift(File.dirname(__FILE__))
|
6
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
9
7
|
require 'legacy_data'
|
8
|
+
|
10
9
|
require 'spec'
|
11
10
|
require 'spec/autorun'
|
12
11
|
|
13
12
|
Spec::Runner.configure do |config|
|
14
13
|
|
15
14
|
end
|
15
|
+
|
16
|
+
### Load the rails generator code
|
17
|
+
require 'rails_generator'
|
18
|
+
require 'rails_generator/scripts'
|
19
|
+
require 'rails_generator/scripts/generate'
|
20
|
+
|
21
|
+
Rails::Generator::Base.reset_sources
|
22
|
+
def add_source(path)
|
23
|
+
Rails::Generator::Base.append_sources(Rails::Generator::PathSource.new(:builtin, path))
|
24
|
+
end
|
25
|
+
|
26
|
+
add_source(File.dirname(__FILE__) + '/../generators')
|
27
|
+
|
28
|
+
def load_generator(generator_name="models_from_tables", args=[])
|
29
|
+
Rails::Generator::Base.instance(generator_name,
|
30
|
+
(args.dup << '--quiet'),
|
31
|
+
{:generator=>generator_name, :command=>:create, :destination=>RAILS_ROOT})
|
32
|
+
end
|
33
|
+
|
34
|
+
def invoke_generator(generator_name, args, the_command= :create)
|
35
|
+
generator = load_generator(generator_name, args)
|
36
|
+
LegacyData::TableClassNameMapper.stub!(:log)
|
37
|
+
cmd = generator.command(the_command)
|
38
|
+
cmd.stub!(:logger).and_return(stub('stub').as_null_object)
|
39
|
+
cmd.invoke!
|
40
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: legacy_data
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alex Rothenberg
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-10-
|
12
|
+
date: 2009-10-08 00:00:00 -04:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -58,9 +58,15 @@ files:
|
|
58
58
|
- lib/legacy_data/schema.rb
|
59
59
|
- lib/legacy_data/table_class_name_mapper.rb
|
60
60
|
- lib/legacy_data/table_definition.rb
|
61
|
+
- spec/expected/post.rb
|
62
|
+
- spec/functional/expected/comment.rb
|
63
|
+
- spec/functional/expected/post.rb
|
64
|
+
- spec/functional/functional_spec_helper.rb
|
65
|
+
- spec/functional/models_from_tables_spec.rb
|
61
66
|
- spec/legacy_data/schema_spec.rb
|
62
67
|
- spec/legacy_data/table_class_name_mapper_spec.rb
|
63
68
|
- spec/legacy_data/table_definition_spec.rb
|
69
|
+
- spec/models_from_tables_generator_spec.rb
|
64
70
|
- spec/spec_helper.rb
|
65
71
|
has_rdoc: true
|
66
72
|
homepage: http://github.com/alexrothenberg/legacy_data
|
@@ -91,7 +97,13 @@ signing_key:
|
|
91
97
|
specification_version: 3
|
92
98
|
summary: Create ActiveRecord models from an existing database
|
93
99
|
test_files:
|
100
|
+
- spec/expected/post.rb
|
101
|
+
- spec/functional/expected/comment.rb
|
102
|
+
- spec/functional/expected/post.rb
|
103
|
+
- spec/functional/functional_spec_helper.rb
|
104
|
+
- spec/functional/models_from_tables_spec.rb
|
94
105
|
- spec/legacy_data/schema_spec.rb
|
95
106
|
- spec/legacy_data/table_class_name_mapper_spec.rb
|
96
107
|
- spec/legacy_data/table_definition_spec.rb
|
108
|
+
- spec/models_from_tables_generator_spec.rb
|
97
109
|
- spec/spec_helper.rb
|