legacy_data 0.1.12 → 0.2.0
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/.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
|