legacy_data 0.1.12 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.rvmrc +1 -0
- data/History.txt +2 -2
- data/README.md +6 -4
- data/Rakefile +9 -11
- data/VERSION +1 -1
- data/examples/generated/blog_mysql/factories.rb +3 -3
- data/examples/generated/blog_sqlite3/factories.rb +4 -4
- data/examples/generated/drupal_mysql/factories.rb +321 -321
- data/examples/generated/j2ee_petstore_mysql/factories.rb +39 -39
- data/examples/generated/j2ee_petstore_oracle/factories.rb +36 -36
- data/examples/generated/j2ee_petstore_sqlite3/factories.rb +39 -39
- data/legacy_data.gemspec +4 -3
- data/lib/{active_record/connection_adapters/oracleenhanced_adapter.rb → foreigner/connection_adapters/oracle_enhanced_adapter.rb} +0 -0
- data/lib/generators/models_from_tables/USAGE +12 -0
- data/lib/generators/models_from_tables/models_from_tables_generator.rb +70 -0
- data/lib/generators/models_from_tables/templates/model.rb +11 -0
- data/lib/legacy_data.rb +6 -7
- data/lib/legacy_data/schema.rb +1 -0
- data/lib/legacy_data/table_class_name_mapper.rb +4 -2
- data/lib/legacy_data/table_definition.rb +1 -2
- data/spec/functional/blog_adapterspec.rb +13 -13
- data/spec/functional/drupal_adapterspec.rb +14 -12
- data/spec/functional/functional_spec_helper.rb +3 -5
- data/spec/functional/j2ee_petstore_adapterspec.rb +14 -14
- data/spec/generators/models_from_tables/expected/factories.rb +5 -0
- data/spec/{expected → generators/models_from_tables/expected}/post.rb +0 -0
- data/spec/{models_from_tables_generator_spec.rb → generators/models_from_tables/models_from_tables_generator_spec.rb} +28 -28
- data/spec/legacy_data/schema_spec.rb +0 -1
- data/spec/legacy_data/table_class_name_mapper_spec.rb +1 -4
- data/spec/spec_helper.rb +46 -28
- metadata +66 -49
- data/generators/models_from_tables/USAGE +0 -6
- data/generators/models_from_tables/models_from_tables_generator.rb +0 -78
- data/generators/models_from_tables/templates/model.rb +0 -11
- data/spec/expected/factories.rb +0 -5
@@ -1,57 +1,57 @@
|
|
1
|
-
Factory.define :address do |
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
1
|
+
Factory.define :address do |address|
|
2
|
+
address.street1 'some string'
|
3
|
+
address.city 'some string'
|
4
|
+
address.state 'some string'
|
5
|
+
address.zip 'some string'
|
6
|
+
address.latitude 12.3
|
7
|
+
address.longitude 12.3
|
8
8
|
end
|
9
9
|
|
10
|
-
Factory.define :seller_contact_info do |
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
Factory.define :seller_contact_info do |seller_contact_info|
|
11
|
+
seller_contact_info.lastname 'some string'
|
12
|
+
seller_contact_info.firstname 'some string'
|
13
|
+
seller_contact_info.email 'some string'
|
14
14
|
end
|
15
15
|
|
16
|
-
Factory.define :category do |
|
17
|
-
|
18
|
-
|
16
|
+
Factory.define :category do |category|
|
17
|
+
category.name 'some string'
|
18
|
+
category.description 'some string'
|
19
19
|
end
|
20
20
|
|
21
|
-
Factory.define :id_gen do |
|
22
|
-
|
21
|
+
Factory.define :id_gen do |id_gen|
|
22
|
+
id_gen.gen_value 7
|
23
23
|
end
|
24
24
|
|
25
|
-
Factory.define :item do |
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
25
|
+
Factory.define :item do |item|
|
26
|
+
item.productid 'some string'
|
27
|
+
item.name 'some string'
|
28
|
+
item.description 'some string'
|
29
|
+
item.price 12.3
|
30
|
+
item.address_addressid 'some string'
|
31
|
+
item.contactinfo_contactinfoid 'some string'
|
32
|
+
item.totalscore 7
|
33
|
+
item.numberofvotes 7
|
34
|
+
item.disabled 7
|
35
35
|
end
|
36
36
|
|
37
|
-
Factory.define :product do |
|
38
|
-
|
39
|
-
|
40
|
-
|
37
|
+
Factory.define :product do |product|
|
38
|
+
product.categoryid 'some string'
|
39
|
+
product.name 'some string'
|
40
|
+
product.description 'some string'
|
41
41
|
end
|
42
42
|
|
43
|
-
Factory.define :tag do |
|
44
|
-
|
45
|
-
|
43
|
+
Factory.define :tag do |tag|
|
44
|
+
tag.tag 'some string'
|
45
|
+
tag.refcount 7
|
46
46
|
end
|
47
47
|
|
48
|
-
Factory.define :tag_item do |
|
49
|
-
|
50
|
-
|
48
|
+
Factory.define :tag_item do |tag_item|
|
49
|
+
tag_item.tagid 7
|
50
|
+
tag_item.itemid 'some string'
|
51
51
|
end
|
52
52
|
|
53
|
-
Factory.define :ziplocation do |
|
54
|
-
|
55
|
-
|
53
|
+
Factory.define :ziplocation do |ziplocation|
|
54
|
+
ziplocation.city 'some string'
|
55
|
+
ziplocation.state 'some string'
|
56
56
|
end
|
57
57
|
|
@@ -1,52 +1,52 @@
|
|
1
|
-
Factory.define :address do |
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
1
|
+
Factory.define :address do |address|
|
2
|
+
address.street1 'some string'
|
3
|
+
address.city 'some string'
|
4
|
+
address.state 'some string'
|
5
|
+
address.zip 'some string'
|
6
|
+
address.latitude 12.3
|
7
|
+
address.longitude 12.3
|
8
8
|
end
|
9
9
|
|
10
|
-
Factory.define :category do |
|
11
|
-
|
12
|
-
|
10
|
+
Factory.define :category do |category|
|
11
|
+
category.name 'some string'
|
12
|
+
category.description 'some string'
|
13
13
|
end
|
14
14
|
|
15
|
-
Factory.define :id_gen do |
|
16
|
-
|
15
|
+
Factory.define :id_gen do |id_gen|
|
16
|
+
id_gen.gen_value 7
|
17
17
|
end
|
18
18
|
|
19
|
-
Factory.define :item do |
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
19
|
+
Factory.define :item do |item|
|
20
|
+
item.productid 'some string'
|
21
|
+
item.name 'some string'
|
22
|
+
item.description 'some string'
|
23
|
+
item.price 12.3
|
24
|
+
item.address_addressid 'some string'
|
25
|
+
item.contactinfo_contactinfoid 'some string'
|
26
|
+
item.totalscore 7
|
27
|
+
item.numberofvotes 7
|
28
|
+
item.disabled 7
|
29
29
|
end
|
30
30
|
|
31
|
-
Factory.define :product do |
|
32
|
-
|
33
|
-
|
34
|
-
|
31
|
+
Factory.define :product do |product|
|
32
|
+
product.categoryid 'some string'
|
33
|
+
product.name 'some string'
|
34
|
+
product.description 'some string'
|
35
35
|
end
|
36
36
|
|
37
|
-
Factory.define :sellercontactinfo do |
|
38
|
-
|
39
|
-
|
40
|
-
|
37
|
+
Factory.define :sellercontactinfo do |sellercontactinfo|
|
38
|
+
sellercontactinfo.lastname 'some string'
|
39
|
+
sellercontactinfo.firstname 'some string'
|
40
|
+
sellercontactinfo.email 'some string'
|
41
41
|
end
|
42
42
|
|
43
|
-
Factory.define :tag do |
|
44
|
-
|
45
|
-
|
43
|
+
Factory.define :tag do |tag|
|
44
|
+
tag.tag 'some string'
|
45
|
+
tag.refcount 7
|
46
46
|
end
|
47
47
|
|
48
|
-
Factory.define :ziplocation do |
|
49
|
-
|
50
|
-
|
48
|
+
Factory.define :ziplocation do |ziplocation|
|
49
|
+
ziplocation.city 'some string'
|
50
|
+
ziplocation.state 'some string'
|
51
51
|
end
|
52
52
|
|
@@ -1,57 +1,57 @@
|
|
1
|
-
Factory.define :address do |
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
1
|
+
Factory.define :address do |address|
|
2
|
+
address.street1 'some string'
|
3
|
+
address.city 'some string'
|
4
|
+
address.state 'some string'
|
5
|
+
address.zip 'some string'
|
6
|
+
address.latitude 12.3
|
7
|
+
address.longitude 12.3
|
8
8
|
end
|
9
9
|
|
10
|
-
Factory.define :seller_contact_info do |
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
Factory.define :seller_contact_info do |seller_contact_info|
|
11
|
+
seller_contact_info.lastname 'some string'
|
12
|
+
seller_contact_info.firstname 'some string'
|
13
|
+
seller_contact_info.email 'some string'
|
14
14
|
end
|
15
15
|
|
16
|
-
Factory.define :category do |
|
17
|
-
|
18
|
-
|
16
|
+
Factory.define :category do |category|
|
17
|
+
category.name 'some string'
|
18
|
+
category.description 'some string'
|
19
19
|
end
|
20
20
|
|
21
|
-
Factory.define :id_gen do |
|
22
|
-
|
21
|
+
Factory.define :id_gen do |id_gen|
|
22
|
+
id_gen.gen_value 7
|
23
23
|
end
|
24
24
|
|
25
|
-
Factory.define :item do |
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
25
|
+
Factory.define :item do |item|
|
26
|
+
item.productid 'some string'
|
27
|
+
item.name 'some string'
|
28
|
+
item.description 'some string'
|
29
|
+
item.price 12.3
|
30
|
+
item.address_addressid 'some string'
|
31
|
+
item.contactinfo_contactinfoid 'some string'
|
32
|
+
item.totalscore 7
|
33
|
+
item.numberofvotes 7
|
34
|
+
item.disabled 7
|
35
35
|
end
|
36
36
|
|
37
|
-
Factory.define :product do |
|
38
|
-
|
39
|
-
|
40
|
-
|
37
|
+
Factory.define :product do |product|
|
38
|
+
product.categoryid 'some string'
|
39
|
+
product.name 'some string'
|
40
|
+
product.description 'some string'
|
41
41
|
end
|
42
42
|
|
43
|
-
Factory.define :tag do |
|
44
|
-
|
45
|
-
|
43
|
+
Factory.define :tag do |tag|
|
44
|
+
tag.tag 'some string'
|
45
|
+
tag.refcount 7
|
46
46
|
end
|
47
47
|
|
48
|
-
Factory.define :tag_item do |
|
49
|
-
|
50
|
-
|
48
|
+
Factory.define :tag_item do |tag_item|
|
49
|
+
tag_item.tagid 7
|
50
|
+
tag_item.itemid 'some string'
|
51
51
|
end
|
52
52
|
|
53
|
-
Factory.define :ziplocation do |
|
54
|
-
|
55
|
-
|
53
|
+
Factory.define :ziplocation do |ziplocation|
|
54
|
+
ziplocation.city 'some string'
|
55
|
+
ziplocation.state 'some string'
|
56
56
|
end
|
57
57
|
|
data/legacy_data.gemspec
CHANGED
@@ -16,11 +16,12 @@ Gem::Specification.new do |s|
|
|
16
16
|
s.rdoc_options = ["--charset=UTF-8"]
|
17
17
|
s.require_path = "lib"
|
18
18
|
|
19
|
-
s.add_dependency '
|
19
|
+
s.add_dependency 'railties', '~> 3.0.1'
|
20
|
+
s.add_dependency 'activerecord', '~> 3.0.1'
|
21
|
+
s.add_dependency 'activesupport', '~> 3.0.1'
|
20
22
|
s.add_dependency 'foreigner', '~> 0.9.1'
|
21
23
|
|
22
24
|
s.add_development_dependency 'rake', '~> 0.8.7'
|
23
|
-
s.add_development_dependency 'rspec', '~> 1.
|
25
|
+
s.add_development_dependency 'rspec', '~> 2.1.0'
|
24
26
|
s.add_development_dependency 'sqlite3-ruby', '~> 1.3.1'
|
25
|
-
s.add_development_dependency 'rails', '~> 2.3.5'
|
26
27
|
end
|
File without changes
|
@@ -0,0 +1,12 @@
|
|
1
|
+
Description:
|
2
|
+
Creates models for existing tables in a legacy database
|
3
|
+
|
4
|
+
Example:
|
5
|
+
rails generate models_from_tables
|
6
|
+
|
7
|
+
This will create:
|
8
|
+
an active record model for each table in your database
|
9
|
+
a factory for each model in spec/factories.rb
|
10
|
+
a temporary file showing the table name/class name mappings its using in app/models/table_mappings.yml
|
11
|
+
|
12
|
+
|
@@ -0,0 +1,70 @@
|
|
1
|
+
class ModelsFromTablesGenerator < Rails::Generators::Base
|
2
|
+
source_root File.expand_path('../templates', __FILE__)
|
3
|
+
|
4
|
+
argument :table_name, :type => :string, :required=>false, :default => nil
|
5
|
+
|
6
|
+
class_option :table_naming_convention, :type => :string, :default => '*',
|
7
|
+
:desc => 'Is there a prefix and/or suffix in the table names to strip when creating class names'
|
8
|
+
class_option :with_factories, :type => :boolean, :default => true,
|
9
|
+
:desc => 'Generate a FactoryGirl factory for each model'
|
10
|
+
class_option :skip_associated, :type => :boolean, :default => false,
|
11
|
+
:desc => "Do not follow database relations to other tables"
|
12
|
+
|
13
|
+
# check_class_collision #:suffix => "ControllerTest"
|
14
|
+
|
15
|
+
def generate_models_from_tables
|
16
|
+
LegacyData::TableClassNameMapper.naming_convention = options[:table_naming_convention]
|
17
|
+
|
18
|
+
analyzed_tables = LegacyData::Schema.analyze(:table_name=>table_name, :skip_associated=>options[:skip_associated])
|
19
|
+
|
20
|
+
unless analyzed_tables.blank?
|
21
|
+
spec_dir_exists = File.exist? "#{Rails.root}/spec"
|
22
|
+
|
23
|
+
LegacyData::TableClassNameMapper.let_user_validate_dictionary
|
24
|
+
|
25
|
+
analyzed_tables.each do |analyzed_table|
|
26
|
+
analyzed_table.class_name = LegacyData::TableClassNameMapper.class_name_for(analyzed_table[:table_name])
|
27
|
+
|
28
|
+
# m.class_collisions :class_path, analyzed_table[:class_name]
|
29
|
+
@definition = analyzed_table
|
30
|
+
template 'model.rb', File.join('app/models', "#{analyzed_table[:class_name].underscore}.rb")
|
31
|
+
|
32
|
+
add_factory_girl_factory analyzed_table if options[:with_factories] && spec_dir_exists
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
def add_factory_girl_factory analyzed_schema
|
39
|
+
factory_name = analyzed_schema[:class_name].underscore
|
40
|
+
columns = analyzed_schema[:columns]
|
41
|
+
|
42
|
+
File.open("#{Rails.root}/spec/factories.rb", 'a+') do |file|
|
43
|
+
file.write "Factory.define :#{factory_name} do |#{factory_name}|\n"
|
44
|
+
column_with_longest_name = columns.max {|a,b| a.name.length <=> b.name.length }
|
45
|
+
columns.each do |c|
|
46
|
+
if c.null == false && c.name != analyzed_schema[:primary_key]
|
47
|
+
value = case c.type
|
48
|
+
when :integer then %[7]
|
49
|
+
when :float then %[12.3]
|
50
|
+
when :decimal then %[12.3]
|
51
|
+
when :datetime then %[{Time.now}]
|
52
|
+
when :date then %[{Time.now}]
|
53
|
+
when :timestamp then %[{Time.now}]
|
54
|
+
when :time then %[{Time.now}]
|
55
|
+
when :text then %['some text value']
|
56
|
+
when :string then %['some string']
|
57
|
+
when :binary then %['some binary stuff']
|
58
|
+
when :boolean then %[false]
|
59
|
+
else
|
60
|
+
"'Sorry the models_to_tables_generator is not sure how to default columns of type #{c.type}'"
|
61
|
+
end
|
62
|
+
spaces = column_with_longest_name.name.size - c.name.size
|
63
|
+
file.write " #{factory_name}.#{c.name}#{' ' * spaces} #{value}\n"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
file.write "end\n\n"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class <%= @definition.class_name -%> < ActiveRecord::Base
|
2
|
+
<%= " set_table_name #{@definition.table_name.downcase.to_sym.inspect}\n" if @definition.unconventional_table_name? -%>
|
3
|
+
<%= " set_primary_key #{@definition.primary_key.to_sym.inspect}\n" if @definition.unconventional_primary_key? -%>
|
4
|
+
|
5
|
+
# Relationships
|
6
|
+
<%= @definition.relationships_to_s %>
|
7
|
+
|
8
|
+
# Constraints
|
9
|
+
<%= @definition.constraints_to_s %>
|
10
|
+
end
|
11
|
+
|
data/lib/legacy_data.rb
CHANGED
@@ -4,12 +4,11 @@ require 'legacy_data/table_definition'
|
|
4
4
|
require 'legacy_data/schema'
|
5
5
|
require 'legacy_data/table_class_name_mapper'
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
7
|
+
Foreigner.register 'oracle_enhanced', 'foreigner/connection_adapters/oracle_enhanced_adapter'
|
8
|
+
|
9
|
+
module LegacyData
|
10
|
+
# In Rails 2.3 this was ActiveRecord::Base.class_name but it no longer exists in Rails 3
|
11
|
+
def self.conventional_class_name table_name
|
12
|
+
table_name.underscore.downcase.pluralize.camelize.singularize
|
13
13
|
end
|
14
14
|
end
|
15
|
-
|
data/lib/legacy_data/schema.rb
CHANGED
@@ -109,6 +109,7 @@ module LegacyData
|
|
109
109
|
|
110
110
|
belongs_to = {}
|
111
111
|
connection.foreign_keys(table_name).each do |foreign_key|
|
112
|
+
col = foreign_key.options[:column] || foreign_key.options[:columns].first
|
112
113
|
options = {:foreign_key=>foreign_key.options[:column].downcase.to_sym}
|
113
114
|
options[:dependent] = :destroy if foreign_key.options[:dependent] == :delete
|
114
115
|
belongs_to[foreign_key.to_table.downcase] = options
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
|
1
3
|
module LegacyData
|
2
4
|
class TableClassNameMapper
|
3
5
|
include Singleton
|
@@ -43,7 +45,7 @@ Done analyzing the tables.
|
|
43
45
|
end
|
44
46
|
|
45
47
|
def dictionary_file_name
|
46
|
-
File.join(
|
48
|
+
File.join(Rails.root, 'app', 'models', 'table_mappings.yml')
|
47
49
|
end
|
48
50
|
|
49
51
|
def class_name_for table_name
|
@@ -57,7 +59,7 @@ Done analyzing the tables.
|
|
57
59
|
def compute_class_name table_name
|
58
60
|
table_name =~ /#{naming_convention}/i
|
59
61
|
stripped_table_name = $1 || table_name
|
60
|
-
dictionary[table_name] =
|
62
|
+
dictionary[table_name] = LegacyData.conventional_class_name stripped_table_name
|
61
63
|
end
|
62
64
|
|
63
65
|
def self.log msg
|