alexrothenberg-legacy_data 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/.document +5 -0
- data/.gitignore +5 -0
- data/LICENSE +20 -0
- data/README.rdoc +20 -0
- data/Rakefile +50 -0
- data/VERSION +1 -0
- data/generators/legacy_models/USAGE +6 -0
- data/generators/legacy_models/legacy_models_generator.rb +22 -0
- data/generators/legacy_models/templates/model.rb +25 -0
- data/legacy_data.gemspec +62 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb +50 -0
- data/lib/legacy_data.rb +2 -0
- data/lib/legacy_data/schema.rb +98 -0
- data/spec/legacy_data_schema_spec.rb +105 -0
- data/spec/spec_helper.rb +15 -0
- metadata +89 -0
data/.document
ADDED
data/LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright (c) 2009 Alex Rothenberg
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
4
|
+
a copy of this software and associated documentation files (the
|
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
9
|
+
the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be
|
|
12
|
+
included in all copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
= legacy_data
|
|
2
|
+
|
|
3
|
+
How can you start a rails project on top of a large legacy database ... use the legacy_data plugin.
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
== Note on Patches/Pull Requests
|
|
8
|
+
|
|
9
|
+
* Fork the project.
|
|
10
|
+
* Make your feature addition or bug fix.
|
|
11
|
+
* Add tests for it. This is important so I don't break it in a
|
|
12
|
+
future version unintentionally.
|
|
13
|
+
* Commit, do not mess with rakefile, version, or history.
|
|
14
|
+
(if you want to have your own version, that is fine but
|
|
15
|
+
bump version in a commit by itself I can ignore when I pull)
|
|
16
|
+
* Send me a pull request. Bonus points for topic branches.
|
|
17
|
+
|
|
18
|
+
== Copyright
|
|
19
|
+
|
|
20
|
+
Copyright (c) 2009 Alex Rothenberg. See LICENSE for details.
|
data/Rakefile
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
require 'rubygems'
|
|
2
|
+
require 'rake'
|
|
3
|
+
|
|
4
|
+
begin
|
|
5
|
+
require 'jeweler'
|
|
6
|
+
Jeweler::Tasks.new do |gem|
|
|
7
|
+
gem.name = "legacy_data"
|
|
8
|
+
gem.summary = %Q{Create ActiveRecord models from an existing database}
|
|
9
|
+
gem.description = %Q{Create ActiveRecord models from an existing database}
|
|
10
|
+
gem.email = "alex@alexrothenberg.com"
|
|
11
|
+
gem.homepage = "http://github.com/alexrothenberg/legacy_data"
|
|
12
|
+
gem.authors = ["Alex Rothenberg"]
|
|
13
|
+
gem.add_development_dependency "rspec"
|
|
14
|
+
gem.add_dependency('activerecord')
|
|
15
|
+
|
|
16
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
|
17
|
+
end
|
|
18
|
+
rescue LoadError
|
|
19
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
require 'spec/rake/spectask'
|
|
23
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
|
24
|
+
spec.libs << 'lib' << 'spec'
|
|
25
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
|
29
|
+
spec.libs << 'lib' << 'spec'
|
|
30
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
|
31
|
+
spec.rcov = true
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
task :spec => :check_dependencies
|
|
35
|
+
|
|
36
|
+
task :default => :spec
|
|
37
|
+
|
|
38
|
+
require 'rake/rdoctask'
|
|
39
|
+
Rake::RDocTask.new do |rdoc|
|
|
40
|
+
if File.exist?('VERSION')
|
|
41
|
+
version = File.read('VERSION')
|
|
42
|
+
else
|
|
43
|
+
version = ""
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
rdoc.rdoc_dir = 'rdoc'
|
|
47
|
+
rdoc.title = "legacy_data #{version}"
|
|
48
|
+
rdoc.rdoc_files.include('README*')
|
|
49
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
|
50
|
+
end
|
data/VERSION
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.0.1
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/../../lib/legacy_data/schema'
|
|
2
|
+
require File.dirname(__FILE__) + '/../../lib/active_record/connection_adapters/oracle_enhanced_adapter'
|
|
3
|
+
|
|
4
|
+
class LegacyModelsGenerator < Rails::Generator::Base
|
|
5
|
+
def manifest
|
|
6
|
+
record do |m|
|
|
7
|
+
m.directory File.join('app/models')
|
|
8
|
+
|
|
9
|
+
LegacyData::Schema.tables(/^tb/).each do |table_name|
|
|
10
|
+
puts "analyzing #{table_name}"
|
|
11
|
+
analysis = LegacyData::Schema.new(table_name).analyze_table
|
|
12
|
+
|
|
13
|
+
file_name = analysis[:class_name].underscore
|
|
14
|
+
m.template 'model.rb',
|
|
15
|
+
File.join('app/models', "#{file_name}.rb"),
|
|
16
|
+
:assigns => analysis
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
class <%= class_name -%> < ActiveRecord::Base
|
|
2
|
+
set_table_name :<%= table_name %>
|
|
3
|
+
set_primary_key :<%= primary_key %>
|
|
4
|
+
|
|
5
|
+
# Relationships
|
|
6
|
+
<%- relations[:has_some].each do |class_name, foreign_key|
|
|
7
|
+
-%> has_many <%= class_name.inspect %>, :foreign_key => <%= foreign_key.inspect %>
|
|
8
|
+
<%- end -%>
|
|
9
|
+
<%- relations[:belongs_to].each do |class_name, foreign_key|
|
|
10
|
+
-%> belongs_to <%= class_name.inspect %>, :foreign_key => <%= foreign_key.inspect %>
|
|
11
|
+
<%- end -%>
|
|
12
|
+
|
|
13
|
+
# Constraints
|
|
14
|
+
<%= "validates_uniqueness_of #{constraints[:unique ].map {|cols| cols.first.downcase.to_sym.inspect}.join(', ')}" unless constraints[:unique].blank? %>
|
|
15
|
+
<%- constraints[:multi_column_unique].each do |cols|
|
|
16
|
+
-%> #validates_uniqueness_of_multiple_column_constraint :<%= cols.inspect %>
|
|
17
|
+
<%- end -%>
|
|
18
|
+
<%= "validates_presence_of #{constraints[:non_nullable].map {|cols| cols.first.downcase.to_sym.inspect}.join(', ')}" unless constraints[:non_nullable].blank? %>
|
|
19
|
+
<%- constraints[:custom].each do |name, sql_rule|
|
|
20
|
+
-%> validate <%= "validate_#{name}".to_sym.inspect %>
|
|
21
|
+
def <%= "validate_#{name}" %>
|
|
22
|
+
# TODO: validate this SQL constraint "<%= sql_rule %>"
|
|
23
|
+
end
|
|
24
|
+
<%- end %>
|
|
25
|
+
end
|
data/legacy_data.gemspec
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Generated by jeweler
|
|
2
|
+
# DO NOT EDIT THIS FILE
|
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
|
|
4
|
+
# -*- encoding: utf-8 -*-
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |s|
|
|
7
|
+
s.name = %q{legacy_data}
|
|
8
|
+
s.version = "0.0.1"
|
|
9
|
+
|
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
|
11
|
+
s.authors = ["Alex Rothenberg"]
|
|
12
|
+
s.date = %q{2009-09-16}
|
|
13
|
+
s.description = %q{Create ActiveRecord models from an existing database}
|
|
14
|
+
s.email = %q{alex@alexrothenberg.com}
|
|
15
|
+
s.extra_rdoc_files = [
|
|
16
|
+
"LICENSE",
|
|
17
|
+
"README.rdoc"
|
|
18
|
+
]
|
|
19
|
+
s.files = [
|
|
20
|
+
".document",
|
|
21
|
+
".gitignore",
|
|
22
|
+
"LICENSE",
|
|
23
|
+
"README.rdoc",
|
|
24
|
+
"Rakefile",
|
|
25
|
+
"VERSION",
|
|
26
|
+
"generators/legacy_models/USAGE",
|
|
27
|
+
"generators/legacy_models/legacy_models_generator.rb",
|
|
28
|
+
"generators/legacy_models/templates/model.rb",
|
|
29
|
+
"legacy_data.gemspec",
|
|
30
|
+
"lib/active_record/connection_adapters/oracle_enhanced_adapter.rb",
|
|
31
|
+
"lib/legacy_data.rb",
|
|
32
|
+
"lib/legacy_data/schema.rb",
|
|
33
|
+
"spec/legacy_data_schema_spec.rb",
|
|
34
|
+
"spec/spec_helper.rb"
|
|
35
|
+
]
|
|
36
|
+
s.has_rdoc = true
|
|
37
|
+
s.homepage = %q{http://github.com/alexrothenberg/legacy_data}
|
|
38
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
|
39
|
+
s.require_paths = ["lib"]
|
|
40
|
+
s.rubygems_version = %q{1.3.2}
|
|
41
|
+
s.summary = %q{Create ActiveRecord models from an existing database}
|
|
42
|
+
s.test_files = [
|
|
43
|
+
"spec/legacy_data_schema_spec.rb",
|
|
44
|
+
"spec/spec_helper.rb"
|
|
45
|
+
]
|
|
46
|
+
|
|
47
|
+
if s.respond_to? :specification_version then
|
|
48
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
|
49
|
+
s.specification_version = 3
|
|
50
|
+
|
|
51
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
|
52
|
+
s.add_development_dependency(%q<rspec>, [">= 0"])
|
|
53
|
+
s.add_runtime_dependency(%q<activerecord>, [">= 0"])
|
|
54
|
+
else
|
|
55
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
|
56
|
+
s.add_dependency(%q<activerecord>, [">= 0"])
|
|
57
|
+
end
|
|
58
|
+
else
|
|
59
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
|
60
|
+
s.add_dependency(%q<activerecord>, [">= 0"])
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
module OracleEnhancedAdapterConstraintsMethods
|
|
2
|
+
|
|
3
|
+
def foreign_keys_for(table_name)
|
|
4
|
+
(owner, table_name) = @connection.describe(table_name)
|
|
5
|
+
|
|
6
|
+
# RSI: changed select from all_constraints to user_constraints - much faster in large data dictionaries
|
|
7
|
+
fks = select_rows(<<-SQL, 'Foreign Keys')
|
|
8
|
+
select parent_c.table_name, cc.column_name
|
|
9
|
+
from user_constraints c, user_constraints parent_c, user_cons_columns cc
|
|
10
|
+
where c.owner = '#{owner}'
|
|
11
|
+
and c.table_name = '#{table_name}'
|
|
12
|
+
and c.r_constraint_name = parent_c.constraint_name
|
|
13
|
+
and c.constraint_type = 'R'
|
|
14
|
+
and cc.owner = c.owner
|
|
15
|
+
and cc.constraint_name = c.constraint_name
|
|
16
|
+
SQL
|
|
17
|
+
end
|
|
18
|
+
def foreign_keys_of(table_name)
|
|
19
|
+
(owner, table_name) = @connection.describe(table_name)
|
|
20
|
+
|
|
21
|
+
# RSI: changed select from all_constraints to user_constraints - much faster in large data dictionaries
|
|
22
|
+
fks = select_rows(<<-SQL, 'Remote Foriegn Keys')
|
|
23
|
+
select c.table_name, cc.column_name
|
|
24
|
+
from user_constraints c, user_constraints parent_c, user_cons_columns cc
|
|
25
|
+
where c.owner = '#{owner}'
|
|
26
|
+
and parent_c.table_name = '#{table_name}'
|
|
27
|
+
and c.r_constraint_name = parent_c.constraint_name
|
|
28
|
+
and c.constraint_type = 'R'
|
|
29
|
+
and cc.owner = c.owner
|
|
30
|
+
and cc.constraint_name = c.constraint_name
|
|
31
|
+
SQL
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def constraints(table_name)
|
|
35
|
+
(owner, table_name) = @connection.describe(table_name)
|
|
36
|
+
|
|
37
|
+
# RSI: changed select from all_constraints to user_constraints - much faster in large data dictionaries
|
|
38
|
+
fks = select_rows(<<-SQL, 'User Contraints')
|
|
39
|
+
select c.constraint_name, c.search_condition
|
|
40
|
+
from user_constraints c
|
|
41
|
+
where c.owner = '#{owner}'
|
|
42
|
+
and c.table_name = '#{table_name}'
|
|
43
|
+
and c.constraint_type = 'C'
|
|
44
|
+
and c.generated = 'USER NAME'
|
|
45
|
+
and c.status = 'ENABLED'
|
|
46
|
+
SQL
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.send(:include, OracleEnhancedAdapterConstraintsMethods) if defined? ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter
|
data/lib/legacy_data.rb
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
module LegacyData
|
|
2
|
+
class Schema
|
|
3
|
+
attr_reader :table_name
|
|
4
|
+
|
|
5
|
+
def initialize(table_name)
|
|
6
|
+
@table_name = table_name
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def analyze_table
|
|
10
|
+
{ :table_name => table_name,
|
|
11
|
+
:class_name => class_name,
|
|
12
|
+
:primary_key => primary_key,
|
|
13
|
+
:relations => relations,
|
|
14
|
+
:constraints => constraints
|
|
15
|
+
}
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def self.tables name_pattern=/.*/
|
|
19
|
+
connection.tables.select {|table_name| table_name =~ name_pattern }
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def class_name
|
|
25
|
+
class_name_for(self.table_name)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def class_name_for table
|
|
29
|
+
ActiveRecord::Base.class_name(table.downcase.pluralize)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def primary_key
|
|
33
|
+
pk_and_sequence_for = connection.pk_and_sequence_for(table_name)
|
|
34
|
+
pk_and_sequence_for.first if pk_and_sequence_for.respond_to? :first
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def relations
|
|
38
|
+
{ :belongs_to => belongs_to_relations,
|
|
39
|
+
:has_some => has_some_relations
|
|
40
|
+
}
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def belongs_to_relations
|
|
44
|
+
return [] unless connection.respond_to? :foreign_keys_for
|
|
45
|
+
|
|
46
|
+
belongs_to = {}
|
|
47
|
+
connection.foreign_keys_for(table_name).each do |relation|
|
|
48
|
+
class_name = class_name_for(relation.first).underscore.to_sym
|
|
49
|
+
belongs_to[class_name] = relation.second.downcase.to_sym
|
|
50
|
+
end
|
|
51
|
+
belongs_to
|
|
52
|
+
end
|
|
53
|
+
def has_some_relations
|
|
54
|
+
return [] unless connection.respond_to? :foreign_keys_of
|
|
55
|
+
|
|
56
|
+
has_some = {}
|
|
57
|
+
connection.foreign_keys_of(table_name).each do |relation|
|
|
58
|
+
class_name = class_name_for(relation.first).underscore.pluralize.to_sym
|
|
59
|
+
has_some[class_name] = relation.second.downcase.to_sym
|
|
60
|
+
end
|
|
61
|
+
has_some
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def constraints
|
|
65
|
+
unique, multi_column_unique = unique_constraints.partition {|columns| columns.size == 1}
|
|
66
|
+
{ :unique => unique,
|
|
67
|
+
:multi_column_unique => multi_column_unique,
|
|
68
|
+
:non_nullable => non_nullable_constraints,
|
|
69
|
+
:custom => custom_constraints
|
|
70
|
+
}
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def non_nullable_constraints
|
|
74
|
+
connection.columns(table_name, "#{table_name} Columns").reject(&:null).map(&:name)
|
|
75
|
+
end
|
|
76
|
+
def unique_constraints
|
|
77
|
+
connection.indexes(table_name).select(&:unique).map(&:columns)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def custom_constraints
|
|
81
|
+
return [] unless connection.respond_to? :constraints
|
|
82
|
+
user_constraints = {}
|
|
83
|
+
connection.constraints(table_name).each do |constraint|
|
|
84
|
+
user_constraints[constraint.first.underscore.to_sym] = constraint.second
|
|
85
|
+
end
|
|
86
|
+
user_constraints
|
|
87
|
+
end
|
|
88
|
+
private
|
|
89
|
+
def self.connection
|
|
90
|
+
@conn ||= ActiveRecord::Base.connection
|
|
91
|
+
end
|
|
92
|
+
def connection
|
|
93
|
+
self.class.connection
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
end
|
|
98
|
+
end
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
|
2
|
+
|
|
3
|
+
describe LegacyData::Schema do
|
|
4
|
+
before :each do
|
|
5
|
+
LegacyData::Schema.instance_variable_set('@conn', nil)
|
|
6
|
+
ActiveRecord::Base.stub(:connection).and_return(@connection=stub(:connection))
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
it "should get a list of the tables from the database" do
|
|
10
|
+
@connection.should_receive(:tables).and_return(['comments', 'people', 'posts'])
|
|
11
|
+
LegacyData::Schema.tables.should == ['comments', 'people', 'posts']
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it "should get a filtered list of the tables from the database" do
|
|
15
|
+
@connection.should_receive(:tables).and_return(['comments', 'people', 'posts'])
|
|
16
|
+
LegacyData::Schema.tables(/^p/).should == ['people', 'posts']
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
describe 'analyzing a table' do
|
|
20
|
+
before :each do
|
|
21
|
+
@schema = LegacyData::Schema.new('some_table')
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it 'should have all the information about the table' do
|
|
25
|
+
@schema.should_receive(:class_name)
|
|
26
|
+
@schema.should_receive(:primary_key)
|
|
27
|
+
@schema.should_receive(:relations)
|
|
28
|
+
@schema.should_receive(:constraints)
|
|
29
|
+
|
|
30
|
+
@schema.analyze_table.keys.should include(:table_name, :class_name, :primary_key, :relations, :constraints)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it 'should have the correct table name' do
|
|
34
|
+
@schema.table_name.should == 'some_table'
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it 'should have the correct class name' do
|
|
38
|
+
ActiveRecord::Base.should_receive(:class_name).with('some_tables').and_return('SomeClass')
|
|
39
|
+
@schema.class_name.should == 'SomeClass'
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it 'should handle tables with a singular name that ends with s' do
|
|
43
|
+
@schema.class_name_for('ADDRESS').should == 'Address'
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it 'should handle tables with an irregular pluralization name' do
|
|
47
|
+
@schema.class_name_for('TBPERSON').should == 'Tbperson'
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it 'should have the correct primary_key' do
|
|
51
|
+
@connection.should_receive(:pk_and_sequence_for).with('some_table').and_return(['PK', 'SEQ'])
|
|
52
|
+
@schema.primary_key.should == 'PK'
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it 'should give no "has_some" (has_many and has_one) relationships when the adapter does not support foreign keys' do
|
|
56
|
+
@connection.should_receive(:respond_to?).with(:foreign_keys_of).and_return(false)
|
|
57
|
+
@schema.has_some_relations.should == []
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
it 'should get all "has_some" (has_many and has_one) relationships when my primary key is the foreign key in another table ' do
|
|
61
|
+
@connection.should_receive(:respond_to?).with(:foreign_keys_of).and_return(true)
|
|
62
|
+
@connection.should_receive(:foreign_keys_of).and_return([['OTHER_TABLE', 'PK'], ['THE_TABLE', 'PK']])
|
|
63
|
+
@schema.has_some_relations.should == {:other_tables => :pk, :the_tables => :pk}
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it 'should give no "belongs_to" when the adapter does not support foreign keys' do
|
|
67
|
+
@connection.should_receive(:respond_to?).with(:foreign_keys_for).and_return(false)
|
|
68
|
+
@schema.belongs_to_relations.should == []
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
it 'should get all "belongs_to" relationships when a foreign key is in my table' do
|
|
72
|
+
@connection.should_receive(:respond_to?).with(:foreign_keys_for).and_return(true)
|
|
73
|
+
@connection.should_receive(:foreign_keys_for).and_return([['OTHER_TABLE', 'FK_1'], ['THE_TABLE', 'the_table_id']])
|
|
74
|
+
@schema.belongs_to_relations.should == {:other_table => :fk_1, :the_table => :the_table_id}
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
it 'should have the correct constraints'
|
|
78
|
+
|
|
79
|
+
it 'should get non-nullable constraints' do
|
|
80
|
+
@connection.should_receive(:columns).with('some_table', 'some_table Columns').and_return([col1=stub(:null=>false, :name=>'col1'),
|
|
81
|
+
col2=stub(:null=>true, :name=>'col2'),
|
|
82
|
+
col3=stub(:null=>false, :name=>'col3')])
|
|
83
|
+
@schema.non_nullable_constraints.should == ['col1', 'col3']
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
it 'should get uniqueness constraints' do
|
|
87
|
+
@connection.should_receive(:indexes).with('some_table').and_return([idx1=stub(:unique=>true, :columns=>['col1']),
|
|
88
|
+
idx2=stub(:unique=>false, :columns=>['col2']),
|
|
89
|
+
idx3=stub(:unique=>true, :columns=>['col3', 'col4'])])
|
|
90
|
+
@schema.unique_constraints.should == [['col1'], ['col3', 'col4']]
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
it 'should give no custom constraints when the adapter does not support it' do
|
|
94
|
+
@connection.should_receive(:respond_to?).with(:constraints).and_return(false)
|
|
95
|
+
@schema.custom_constraints.should == []
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
it 'should get all "belongs_to" relationships when a foreign key is in my table' do
|
|
99
|
+
@connection.should_receive(:respond_to?).with(:constraints).and_return(true)
|
|
100
|
+
@connection.should_receive(:constraints).and_return([['SomeConstraint', 'custom sql 1'], ['anotherconstraint', 'more custom sql']])
|
|
101
|
+
@schema.custom_constraints.should == {:some_constraint => 'custom sql 1', :anotherconstraint => 'more custom sql'}
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
end
|
|
105
|
+
end
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
|
2
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
|
3
|
+
require 'rubygems'
|
|
4
|
+
gem 'activerecord'
|
|
5
|
+
gem 'activerecord-oracle_enhanced-adapter'
|
|
6
|
+
require 'activerecord'
|
|
7
|
+
require 'active_record/connection_adapters/oracle_enhanced_adapter'
|
|
8
|
+
|
|
9
|
+
require 'legacy_data'
|
|
10
|
+
require 'spec'
|
|
11
|
+
require 'spec/autorun'
|
|
12
|
+
|
|
13
|
+
Spec::Runner.configure do |config|
|
|
14
|
+
|
|
15
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: alexrothenberg-legacy_data
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Alex Rothenberg
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
|
|
12
|
+
date: 2009-09-16 00:00:00 -07:00
|
|
13
|
+
default_executable:
|
|
14
|
+
dependencies:
|
|
15
|
+
- !ruby/object:Gem::Dependency
|
|
16
|
+
name: rspec
|
|
17
|
+
type: :development
|
|
18
|
+
version_requirement:
|
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
20
|
+
requirements:
|
|
21
|
+
- - ">="
|
|
22
|
+
- !ruby/object:Gem::Version
|
|
23
|
+
version: "0"
|
|
24
|
+
version:
|
|
25
|
+
- !ruby/object:Gem::Dependency
|
|
26
|
+
name: activerecord
|
|
27
|
+
type: :runtime
|
|
28
|
+
version_requirement:
|
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ">="
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: "0"
|
|
34
|
+
version:
|
|
35
|
+
description: Create ActiveRecord models from an existing database
|
|
36
|
+
email: alex@alexrothenberg.com
|
|
37
|
+
executables: []
|
|
38
|
+
|
|
39
|
+
extensions: []
|
|
40
|
+
|
|
41
|
+
extra_rdoc_files:
|
|
42
|
+
- LICENSE
|
|
43
|
+
- README.rdoc
|
|
44
|
+
files:
|
|
45
|
+
- .document
|
|
46
|
+
- .gitignore
|
|
47
|
+
- LICENSE
|
|
48
|
+
- README.rdoc
|
|
49
|
+
- Rakefile
|
|
50
|
+
- VERSION
|
|
51
|
+
- generators/legacy_models/USAGE
|
|
52
|
+
- generators/legacy_models/legacy_models_generator.rb
|
|
53
|
+
- generators/legacy_models/templates/model.rb
|
|
54
|
+
- legacy_data.gemspec
|
|
55
|
+
- lib/active_record/connection_adapters/oracle_enhanced_adapter.rb
|
|
56
|
+
- lib/legacy_data.rb
|
|
57
|
+
- lib/legacy_data/schema.rb
|
|
58
|
+
- spec/legacy_data_schema_spec.rb
|
|
59
|
+
- spec/spec_helper.rb
|
|
60
|
+
has_rdoc: true
|
|
61
|
+
homepage: http://github.com/alexrothenberg/legacy_data
|
|
62
|
+
licenses:
|
|
63
|
+
post_install_message:
|
|
64
|
+
rdoc_options:
|
|
65
|
+
- --charset=UTF-8
|
|
66
|
+
require_paths:
|
|
67
|
+
- lib
|
|
68
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
69
|
+
requirements:
|
|
70
|
+
- - ">="
|
|
71
|
+
- !ruby/object:Gem::Version
|
|
72
|
+
version: "0"
|
|
73
|
+
version:
|
|
74
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
75
|
+
requirements:
|
|
76
|
+
- - ">="
|
|
77
|
+
- !ruby/object:Gem::Version
|
|
78
|
+
version: "0"
|
|
79
|
+
version:
|
|
80
|
+
requirements: []
|
|
81
|
+
|
|
82
|
+
rubyforge_project:
|
|
83
|
+
rubygems_version: 1.3.5
|
|
84
|
+
signing_key:
|
|
85
|
+
specification_version: 3
|
|
86
|
+
summary: Create ActiveRecord models from an existing database
|
|
87
|
+
test_files:
|
|
88
|
+
- spec/legacy_data_schema_spec.rb
|
|
89
|
+
- spec/spec_helper.rb
|