aspgems-foreign_key_migrations 2.0.0.beta1
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/.gitignore +3 -0
- data/CHANGELOG +109 -0
- data/Gemfile +3 -0
- data/MIT-LICENSE +20 -0
- data/README.md +91 -0
- data/Rakefile +69 -0
- data/foreign_key_migrations.gemspec +28 -0
- data/init.rb +1 -0
- data/install.rb +1 -0
- data/lib/foreign_key_migrations.rb +48 -0
- data/lib/foreign_key_migrations/active_record/base.rb +36 -0
- data/lib/foreign_key_migrations/active_record/connection_adapters/schema_statements.rb +23 -0
- data/lib/foreign_key_migrations/active_record/connection_adapters/table_definition.rb +50 -0
- data/lib/foreign_key_migrations/active_record/migration.rb +62 -0
- data/lib/foreign_key_migrations/version.rb +3 -0
- data/lib/generators/foreign_key_migrations/migration_generator.rb +38 -0
- data/lib/generators/foreign_key_migrations/templates/migration.rb +10 -0
- data/spec/aaa_create_tables_spec.rb +9 -0
- data/spec/connections/mysql/connection.rb +16 -0
- data/spec/connections/mysql2/connection.rb +16 -0
- data/spec/connections/postgresql/connection.rb +13 -0
- data/spec/migration_spec.rb +257 -0
- data/spec/models/comment.rb +3 -0
- data/spec/models/post.rb +3 -0
- data/spec/models/user.rb +2 -0
- data/spec/references_spec.rb +48 -0
- data/spec/schema/schema.rb +24 -0
- data/spec/schema_dumper_spec.rb +32 -0
- data/spec/schema_spec.rb +65 -0
- data/spec/spec_helper.rb +15 -0
- data/spec/support/helpers.rb +8 -0
- data/spec/support/matchers/foreign_key_migrations_matchers.rb +2 -0
- data/spec/support/matchers/have_index.rb +52 -0
- data/spec/support/matchers/reference.rb +66 -0
- metadata +144 -0
data/spec/models/post.rb
ADDED
data/spec/models/user.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
3
|
+
|
4
|
+
describe 'references method' do
|
5
|
+
|
6
|
+
before(:all) do
|
7
|
+
@target = ActiveRecord::Base
|
8
|
+
@table_name = 'comments'
|
9
|
+
@column_name = 'post_id'
|
10
|
+
@destination_table = 'posts'
|
11
|
+
@destinantion_column = :id
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should accept table name and column name to references" do
|
15
|
+
lambda { @target.references(@table_name, @column_name) }.should_not raise_error
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should return an array" do
|
19
|
+
@target.references(@table_name, @column_name).should be_an(Array)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should split column name to table name and primary key" do
|
23
|
+
result = @target.references(@table_name, @column_name)
|
24
|
+
result[0].should eql @destination_table
|
25
|
+
result[1].should eql @destinantion_column
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should handle parent_id as belonging to the same table" do
|
29
|
+
column_name = 'parent_id'
|
30
|
+
result = @target.references(@table_name, column_name)
|
31
|
+
result[0].should eql @table_name
|
32
|
+
result[1].should eql :id
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should accept :references option which overrides default table name" do
|
36
|
+
result = @target.references(@table_name, @column_name, :references => 'users')
|
37
|
+
result[0].should eql 'users'
|
38
|
+
result[1].should eql :id
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should accept :references option which overrides default table name and default column name" do
|
42
|
+
result = @target.references(@table_name, @column_name, :references => ['users', 'uuid'])
|
43
|
+
result[0].should eql 'users'
|
44
|
+
result[1].should eql 'uuid'
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
@@ -0,0 +1,24 @@
|
|
1
|
+
ActiveRecord::Schema.define do
|
2
|
+
|
3
|
+
create_table :users, :force => true do |t|
|
4
|
+
t.string :login
|
5
|
+
end
|
6
|
+
add_index :users, :login, :unique => true
|
7
|
+
|
8
|
+
create_table :members, :force => true do |t|
|
9
|
+
t.string :login
|
10
|
+
end
|
11
|
+
|
12
|
+
create_table :comments, :force => true do |t|
|
13
|
+
t.string :content
|
14
|
+
t.integer :user
|
15
|
+
t.integer :user_id
|
16
|
+
end
|
17
|
+
|
18
|
+
add_foreign_key :comments, :user_id, :users, :id
|
19
|
+
|
20
|
+
create_table :posts, :force => true do |t|
|
21
|
+
t.string :content
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
require 'stringio'
|
3
|
+
|
4
|
+
require 'models/post'
|
5
|
+
|
6
|
+
describe "Schema dump" do
|
7
|
+
|
8
|
+
let(:dump) do
|
9
|
+
stream = StringIO.new
|
10
|
+
ActiveRecord::SchemaDumper.ignore_tables = []
|
11
|
+
ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
|
12
|
+
stream.string
|
13
|
+
end
|
14
|
+
|
15
|
+
it "shouldn't include :index option for index" do
|
16
|
+
add_column(:author_id, :integer, :references => :users, :index => true) do
|
17
|
+
dump.should_not match(/index => true/)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
protected
|
22
|
+
def add_column(column_name, *args)
|
23
|
+
table = Post.table_name
|
24
|
+
ActiveRecord::Migration.suppress_messages do
|
25
|
+
ActiveRecord::Migration.add_column(table, column_name, *args)
|
26
|
+
Post.reset_column_information
|
27
|
+
yield if block_given?
|
28
|
+
ActiveRecord::Migration.remove_column(table, column_name)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
data/spec/schema_spec.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe ActiveRecord::Schema do
|
4
|
+
|
5
|
+
let(:schema) { ActiveRecord::Schema }
|
6
|
+
|
7
|
+
let(:connection) { ActiveRecord::Base.connection }
|
8
|
+
|
9
|
+
after(:all) do
|
10
|
+
# revert to general schema
|
11
|
+
ActiveRecord::Migration.suppress_messages do
|
12
|
+
load 'schema/schema.rb'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context "defining with auto_index" do
|
17
|
+
|
18
|
+
it "should pass" do
|
19
|
+
with_auto_index do
|
20
|
+
expect { define_schema }.should_not raise_error
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should create only explicity added indexes" do
|
25
|
+
with_auto_index do
|
26
|
+
define_schema
|
27
|
+
connection.tables.collect { |table| connection.indexes(table) }.flatten.should have_at_most(1).item
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
protected
|
34
|
+
def define_schema
|
35
|
+
ActiveRecord::Migration.suppress_messages do
|
36
|
+
schema.define do
|
37
|
+
create_table :users, :force => true do
|
38
|
+
end
|
39
|
+
|
40
|
+
create_table :posts, :force => true do |t|
|
41
|
+
t.integer :user_id
|
42
|
+
end
|
43
|
+
|
44
|
+
create_table :comments, :force => true do |t|
|
45
|
+
t.integer :user_id
|
46
|
+
end
|
47
|
+
|
48
|
+
# mysql will create index on FK automatically
|
49
|
+
unless ForeignKeyMigrationsHelpers.mysql?
|
50
|
+
add_index :posts, :user_id
|
51
|
+
add_index :comments, :user_id
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def with_auto_index(value = true)
|
58
|
+
old_value = ForeignKeyMigrations.auto_index
|
59
|
+
ForeignKeyMigrations.auto_index = value
|
60
|
+
yield
|
61
|
+
ensure
|
62
|
+
ForeignKeyMigrations.auto_index = old_value
|
63
|
+
end
|
64
|
+
|
65
|
+
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
|
+
require 'rspec'
|
5
|
+
require 'foreign_key_migrations'
|
6
|
+
require 'connection'
|
7
|
+
Dir[File.dirname(__FILE__) + "/support/**/*.rb"].each {|f| require f}
|
8
|
+
|
9
|
+
RSpec.configure do |config|
|
10
|
+
config.include(ForeignKeyMigrationsMatchers)
|
11
|
+
end
|
12
|
+
|
13
|
+
def load_schema
|
14
|
+
eval(File.read(File.join(File.dirname(__FILE__), 'schema', 'schema.rb')))
|
15
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module ForeignKeyMigrationsMatchers
|
2
|
+
|
3
|
+
class HaveIndex
|
4
|
+
|
5
|
+
def initialize(expectation, options = {})
|
6
|
+
set_required_columns(expectation, options)
|
7
|
+
end
|
8
|
+
|
9
|
+
def matches?(model)
|
10
|
+
@model = model
|
11
|
+
@model.indexes.any? do |index|
|
12
|
+
index.columns.to_set == @required_columns &&
|
13
|
+
(@unique ? index.unique : true) &&
|
14
|
+
(@name ? index.name == @name.to_s : true)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def failure_message_for_should(should_not = false)
|
19
|
+
invert = should_not ? "not to" : ""
|
20
|
+
"Expected #{@model.table_name} to #{invert} contain index on #{@required_columns.entries.inspect}"
|
21
|
+
end
|
22
|
+
|
23
|
+
def failure_message_for_should_not
|
24
|
+
failure_message_for_should(true)
|
25
|
+
end
|
26
|
+
|
27
|
+
def on(expectation)
|
28
|
+
set_required_columns(expectation)
|
29
|
+
self
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
def set_required_columns(expectation, options = {})
|
34
|
+
@required_columns = Array(expectation).collect(&:to_s).to_set
|
35
|
+
@unique = options.delete(:unique)
|
36
|
+
@name = options.delete(:name)
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
def have_index(*expectation)
|
42
|
+
options = expectation.extract_options!
|
43
|
+
HaveIndex.new(expectation, options)
|
44
|
+
end
|
45
|
+
|
46
|
+
def have_unique_index(*expectation)
|
47
|
+
options = expectation.extract_options!
|
48
|
+
options[:unique] = true
|
49
|
+
HaveIndex.new(expectation, options)
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module ForeignKeyMigrationsMatchers
|
2
|
+
|
3
|
+
class Reference
|
4
|
+
def initialize(expected)
|
5
|
+
@column_names = nil
|
6
|
+
unless expected.empty?
|
7
|
+
@references_column_names = Array(expected).collect(&:to_s)
|
8
|
+
@references_table_name = @references_column_names.shift
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def matches?(model)
|
13
|
+
@model = model
|
14
|
+
if @references_table_name
|
15
|
+
@result = @model.foreign_keys.select do |fk|
|
16
|
+
fk.references_table_name == @references_table_name &&
|
17
|
+
@references_column_names.empty? ? true : fk.references_column_names == @references_column_names
|
18
|
+
end
|
19
|
+
else
|
20
|
+
@result = @model.foreign_keys
|
21
|
+
end
|
22
|
+
if @column_names
|
23
|
+
@result.any? do |fk|
|
24
|
+
fk.column_names == @column_names &&
|
25
|
+
(@on_update ? fk.on_update == @on_update : true) &&
|
26
|
+
(@on_delete ? fk.on_delete == @on_delete : true)
|
27
|
+
end
|
28
|
+
else
|
29
|
+
!@result.empty?
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def failure_message_for_should(should_not = false)
|
34
|
+
target_column_names = @column_names.present? ? "(#{@column_names.join(', ')})" : ""
|
35
|
+
destinantion_column_names = @references_table_name ? "#{@references_table_name}(#{@references_column_names.join(', ')})" : "anything"
|
36
|
+
invert = should_not ? 'not' : ''
|
37
|
+
"Expected #{@model.table_name}#{target_column_names} to #{invert} reference #{destinantion_column_names}"
|
38
|
+
end
|
39
|
+
|
40
|
+
def failure_message_for_should_not
|
41
|
+
failure_message_for_should(true)
|
42
|
+
end
|
43
|
+
|
44
|
+
def on(*column_names)
|
45
|
+
@column_names = column_names.collect(&:to_s)
|
46
|
+
self
|
47
|
+
end
|
48
|
+
|
49
|
+
def on_update(action)
|
50
|
+
@on_update = action
|
51
|
+
self
|
52
|
+
end
|
53
|
+
|
54
|
+
def on_delete(action)
|
55
|
+
@on_delete = action
|
56
|
+
self
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
def reference(*expect)
|
62
|
+
Reference.new(expect)
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
metadata
ADDED
@@ -0,0 +1,144 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: aspgems-foreign_key_migrations
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: 6
|
5
|
+
version: 2.0.0.beta1
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- "Micha\xC5\x82 \xC5\x81omnicki"
|
9
|
+
- "Paco Guzm\xC3\xA1n"
|
10
|
+
autorequire:
|
11
|
+
bindir: bin
|
12
|
+
cert_chain: []
|
13
|
+
|
14
|
+
date: 2011-05-14 00:00:00 Z
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: aspgems-redhillonrails_core
|
18
|
+
prerelease: false
|
19
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
20
|
+
none: false
|
21
|
+
requirements:
|
22
|
+
- - ~>
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: 2.0.0.beta2
|
25
|
+
type: :runtime
|
26
|
+
version_requirements: *id001
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
prerelease: false
|
30
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
31
|
+
none: false
|
32
|
+
requirements:
|
33
|
+
- - ~>
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: 2.5.0
|
36
|
+
type: :development
|
37
|
+
version_requirements: *id002
|
38
|
+
- !ruby/object:Gem::Dependency
|
39
|
+
name: pg
|
40
|
+
prerelease: false
|
41
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: "0"
|
47
|
+
type: :development
|
48
|
+
version_requirements: *id003
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: mysql
|
51
|
+
prerelease: false
|
52
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: "0"
|
58
|
+
type: :development
|
59
|
+
version_requirements: *id004
|
60
|
+
- !ruby/object:Gem::Dependency
|
61
|
+
name: mysql2
|
62
|
+
prerelease: false
|
63
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
64
|
+
none: false
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: "0"
|
69
|
+
type: :development
|
70
|
+
version_requirements: *id005
|
71
|
+
description: Automatic Foreign Key automatically generates foreign-key constraints when creating tables or adding columns. It uses SQL-92 syntax and as such should be compatible with most databases that support foreign-key constraints.
|
72
|
+
email:
|
73
|
+
- michal.lomnicki@gmail.com
|
74
|
+
- fjguzman@aspgems.com
|
75
|
+
executables: []
|
76
|
+
|
77
|
+
extensions: []
|
78
|
+
|
79
|
+
extra_rdoc_files: []
|
80
|
+
|
81
|
+
files:
|
82
|
+
- .gitignore
|
83
|
+
- CHANGELOG
|
84
|
+
- Gemfile
|
85
|
+
- MIT-LICENSE
|
86
|
+
- README.md
|
87
|
+
- Rakefile
|
88
|
+
- foreign_key_migrations.gemspec
|
89
|
+
- init.rb
|
90
|
+
- install.rb
|
91
|
+
- lib/foreign_key_migrations.rb
|
92
|
+
- lib/foreign_key_migrations/active_record/base.rb
|
93
|
+
- lib/foreign_key_migrations/active_record/connection_adapters/schema_statements.rb
|
94
|
+
- lib/foreign_key_migrations/active_record/connection_adapters/table_definition.rb
|
95
|
+
- lib/foreign_key_migrations/active_record/migration.rb
|
96
|
+
- lib/foreign_key_migrations/version.rb
|
97
|
+
- lib/generators/foreign_key_migrations/migration_generator.rb
|
98
|
+
- lib/generators/foreign_key_migrations/templates/migration.rb
|
99
|
+
- spec/aaa_create_tables_spec.rb
|
100
|
+
- spec/connections/mysql/connection.rb
|
101
|
+
- spec/connections/mysql2/connection.rb
|
102
|
+
- spec/connections/postgresql/connection.rb
|
103
|
+
- spec/migration_spec.rb
|
104
|
+
- spec/models/comment.rb
|
105
|
+
- spec/models/post.rb
|
106
|
+
- spec/models/user.rb
|
107
|
+
- spec/references_spec.rb
|
108
|
+
- spec/schema/schema.rb
|
109
|
+
- spec/schema_dumper_spec.rb
|
110
|
+
- spec/schema_spec.rb
|
111
|
+
- spec/spec_helper.rb
|
112
|
+
- spec/support/helpers.rb
|
113
|
+
- spec/support/matchers/foreign_key_migrations_matchers.rb
|
114
|
+
- spec/support/matchers/have_index.rb
|
115
|
+
- spec/support/matchers/reference.rb
|
116
|
+
homepage: https://github.com/aspgems/foreign_key_migrations
|
117
|
+
licenses: []
|
118
|
+
|
119
|
+
post_install_message:
|
120
|
+
rdoc_options: []
|
121
|
+
|
122
|
+
require_paths:
|
123
|
+
- lib
|
124
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
125
|
+
none: false
|
126
|
+
requirements:
|
127
|
+
- - ">="
|
128
|
+
- !ruby/object:Gem::Version
|
129
|
+
version: "0"
|
130
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
131
|
+
none: false
|
132
|
+
requirements:
|
133
|
+
- - ">"
|
134
|
+
- !ruby/object:Gem::Version
|
135
|
+
version: 1.3.1
|
136
|
+
requirements: []
|
137
|
+
|
138
|
+
rubyforge_project:
|
139
|
+
rubygems_version: 1.7.2
|
140
|
+
signing_key:
|
141
|
+
specification_version: 3
|
142
|
+
summary: Automatically generate foreign-key constraints when creating tables
|
143
|
+
test_files: []
|
144
|
+
|