phlawski-migration_fu 0.0.2
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/README.rdoc +61 -0
- data/Rakefile +45 -0
- data/init.rb +1 -0
- data/install.rb +1 -0
- data/lib/migration_fu.rb +54 -0
- data/migration_fu.gemspec +32 -0
- data/test/migration_fu_test.rb +69 -0
- metadata +69 -0
data/README.rdoc
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
= MigrationFu
|
2
|
+
|
3
|
+
Rails gem / plugin for generating foreign key constraints.
|
4
|
+
|
5
|
+
== Install
|
6
|
+
|
7
|
+
=== as gem
|
8
|
+
|
9
|
+
sudo gem install sleistner-migration_fu --source http://gems.github.com
|
10
|
+
|
11
|
+
=== or plugin
|
12
|
+
|
13
|
+
script/plugin install git://github.com/sleistner/migration_fu.git
|
14
|
+
|
15
|
+
== Usage
|
16
|
+
|
17
|
+
----------------- -----------------
|
18
|
+
| users | | addresses |
|
19
|
+
----------------- -----------------
|
20
|
+
| id | | id |
|
21
|
+
| username | <---- | user_id |
|
22
|
+
| password | | street |
|
23
|
+
----------------- -----------------
|
24
|
+
|
25
|
+
[ON DELETE {RESTRICT | CASCADE | SET NULL | NO ACTION}]
|
26
|
+
[ON UPDATE {RESTRICT | CASCADE | SET NULL | NO ACTION}]
|
27
|
+
|
28
|
+
see http://dev.mysql.com/doc/refman/5.0/en/innodb-foreign-key-constraints.html
|
29
|
+
|
30
|
+
arguments: from_table, to_table, options => { :name, on_delete, on_update }
|
31
|
+
|
32
|
+
add_foreign_key(:addresses, :users, :name => 'fk_add_user')
|
33
|
+
|
34
|
+
add_foreign_key(:addresses, :users, :on_delete => :cascade)
|
35
|
+
add_foreign_key(:addresses, :users, :on_delete => :set_null)
|
36
|
+
add_foreign_key(:addresses, :users, :on_delete => :restrict)
|
37
|
+
add_foreign_key(:addresses, :users, :on_delete => :no_action)
|
38
|
+
|
39
|
+
add_foreign_key(:addresses, :users, :on_update => :cascade)
|
40
|
+
add_foreign_key(:addresses, :users, :on_update => :set_null)
|
41
|
+
add_foreign_key(:addresses, :users, :on_update => :restrict)
|
42
|
+
add_foreign_key(:addresses, :users, :on_update => :no_action)
|
43
|
+
|
44
|
+
add_foreign_key(:addresses, :users, :on_delete => :cascade, :on_update => :cascade)
|
45
|
+
|
46
|
+
class CreateUsers < ActiveRecord::Migration
|
47
|
+
|
48
|
+
def self.up
|
49
|
+
create_table :users, :force => true do |t|
|
50
|
+
t.string :username, :null => false
|
51
|
+
t.string :password, :null => false
|
52
|
+
end
|
53
|
+
|
54
|
+
create_table :addresses, :force => true do |t|
|
55
|
+
t.references :user
|
56
|
+
t.string :street, :null => false
|
57
|
+
end
|
58
|
+
|
59
|
+
add_foreign_key(:addresses, :users, :on_delete => :cascade)
|
60
|
+
end
|
61
|
+
end
|
data/Rakefile
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'rake/testtask'
|
4
|
+
require 'rake/rdoctask'
|
5
|
+
require 'echoe'
|
6
|
+
|
7
|
+
desc 'Default: run unit tests.'
|
8
|
+
task :default => :test
|
9
|
+
|
10
|
+
desc 'Test the migration_fu plugin.'
|
11
|
+
Rake::TestTask.new(:test) do |t|
|
12
|
+
t.libs << 'lib'
|
13
|
+
t.pattern = 'test/**/*_test.rb'
|
14
|
+
t.verbose = true
|
15
|
+
end
|
16
|
+
|
17
|
+
desc 'Generate documentation for the migration_fu plugin.'
|
18
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
19
|
+
rdoc.rdoc_dir = 'rdoc'
|
20
|
+
rdoc.title = 'MigrationFu'
|
21
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
22
|
+
rdoc.rdoc_files.include('README')
|
23
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
24
|
+
end
|
25
|
+
|
26
|
+
namespace :test do
|
27
|
+
desc 'Measure test coverage'
|
28
|
+
task :coverage do
|
29
|
+
system("rcov --rails --text-summary -Ilib --xrefs --html test/unit/*_test.rb")
|
30
|
+
#test/functional/*_test.rb test/views/*_test.rb test/integration/*_test.rb")
|
31
|
+
system("open coverage/index.html") if PLATFORM['darwin']
|
32
|
+
system("firefox coverage/index.html") if PLATFORM['linux']
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
Echoe.new('migration_fu', '0.0.2') do |p|
|
37
|
+
p.description = 'Add or remove foreign keys'
|
38
|
+
p.url = 'http://github.com/phlawski/migration_fu'
|
39
|
+
p.author = 'Steffen Leistner'
|
40
|
+
p.email = 'sleistner@gmail.com'
|
41
|
+
p.ignore_pattern = ['tmp/*', 'script/*.rake']
|
42
|
+
p.development_dependencies = []
|
43
|
+
end
|
44
|
+
|
45
|
+
Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext }
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'migration_fu'
|
data/install.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
puts IO.read(File.join(File.dirname(__FILE__), 'README.rdoc'))
|
data/lib/migration_fu.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
|
3
|
+
class Migration
|
4
|
+
|
5
|
+
MAX_KEY_LENGTH = 64
|
6
|
+
OPTION_KEYS = [:restrict, :set_null, :cascade, :no_action]
|
7
|
+
OPTION_VALUES = [:on_update, :on_delete]
|
8
|
+
|
9
|
+
class << self
|
10
|
+
|
11
|
+
def add_foreign_key(from_table, to_table, options = {})
|
12
|
+
process(from_table, to_table, options) do |ft, tt, id|
|
13
|
+
fk_col_name = options[:fk_col_name] || "#{tt.singularize}_id"
|
14
|
+
execute "ALTER TABLE #{ft} ADD CONSTRAINT #{id} FOREIGN KEY(#{fk_col_name}) REFERENCES #{tt}(id)" << conditions(options)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def remove_foreign_key(from_table, to_table, options = {})
|
19
|
+
process(from_table, to_table, options) do |ft, tt, id|
|
20
|
+
execute "ALTER TABLE #{ft} DROP FOREIGN KEY #{id}"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def entirely_reset_column_information
|
25
|
+
ActiveRecord::Base.send(:subclasses).each(&:reset_column_information)
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def conditions(options)
|
31
|
+
conditions = ''
|
32
|
+
options.each_pair do |key, value|
|
33
|
+
conditions << " #{key.to_s.gsub(/_/, ' ')} #{value.to_s.gsub(/_/, ' ')}".upcase if condition_valid?(key, value)
|
34
|
+
end
|
35
|
+
conditions
|
36
|
+
end
|
37
|
+
|
38
|
+
def condition_valid?(key, value)
|
39
|
+
OPTION_VALUES.include?(key.to_sym) && OPTION_KEYS.include?(value.to_sym)
|
40
|
+
end
|
41
|
+
|
42
|
+
def process(from_table, to_table, options)
|
43
|
+
id = options[:name].to_s || "fk_#{from_table}_#{to_table}"
|
44
|
+
|
45
|
+
if id.size > MAX_KEY_LENGTH
|
46
|
+
id = id.slice(0...MAX_KEY_LENGTH)
|
47
|
+
puts "Warning: foreign key id has more then #{MAX_KEY_LENGTH} characters - sliced to '#{id}'"
|
48
|
+
end
|
49
|
+
yield(from_table.to_s, to_table.to_s, id)
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{migration_fu}
|
5
|
+
s.version = "0.0.2"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Steffen Leistner", "Piotr Hlawski"]
|
9
|
+
s.date = %q{2009-02-05}
|
10
|
+
s.description = %q{Add or remove foreign keys}
|
11
|
+
s.email = %q{sleistner@gmail.com}
|
12
|
+
s.extra_rdoc_files = ["README.rdoc", "lib/migration_fu.rb"]
|
13
|
+
s.files = ["migration_fu.gemspec", "install.rb", "README.rdoc", "nbproject/project.xml", "nbproject/project.properties", "test/migration_fu_test.rb", "init.rb", "lib/migration_fu.rb", "Rakefile", "Manifest"]
|
14
|
+
s.has_rdoc = true
|
15
|
+
s.homepage = %q{http://github.com/phlawski/migration_fu}
|
16
|
+
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Migration_fu", "--main", "README.rdoc"]
|
17
|
+
s.require_paths = ["lib"]
|
18
|
+
s.rubyforge_project = %q{migration_fu}
|
19
|
+
s.rubygems_version = %q{1.3.1}
|
20
|
+
s.summary = %q{Add or remove foreign keys}
|
21
|
+
s.test_files = ["test/migration_fu_test.rb"]
|
22
|
+
|
23
|
+
if s.respond_to? :specification_version then
|
24
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
25
|
+
s.specification_version = 2
|
26
|
+
|
27
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
28
|
+
else
|
29
|
+
end
|
30
|
+
else
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require File.dirname(__FILE__) + '/../lib/migration_fu'
|
3
|
+
|
4
|
+
class String
|
5
|
+
def singularize; self[0...-1] end
|
6
|
+
end
|
7
|
+
|
8
|
+
class ActiveRecord::Migration
|
9
|
+
def self.execute command; command end
|
10
|
+
end
|
11
|
+
|
12
|
+
class MigrationFuTest < Test::Unit::TestCase
|
13
|
+
|
14
|
+
ID = 'fk_users_files'
|
15
|
+
CUSTOM_ID = 'fk_my_name'
|
16
|
+
|
17
|
+
def setup
|
18
|
+
@foo = ActiveRecord::Migration
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_should_add_foreign_key_without_options
|
22
|
+
assert_equal add_command, add
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_should_add_foreign_key_with_invalid_options_but_ignore_them
|
26
|
+
assert_equal add_command, add(:on_del => :ca)
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_should_add_foreign_key_with_valid_options
|
30
|
+
assert_equal "#{add_command} ON DELETE CASCADE", add(:on_delete => :cascade)
|
31
|
+
assert_equal "#{add_command} ON UPDATE SET NULL ON DELETE CASCADE", add(:on_update => :set_null, :on_delete => :cascade)
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_should_add_foreign_key_with_optional_name
|
35
|
+
assert_equal add_command(CUSTOM_ID), add(:name => CUSTOM_ID)
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_should_add_foreign_key_and_truncate_id
|
39
|
+
to = 'x' * 70
|
40
|
+
assert_equal add_command('fk_users_' << 'x' * 55, to), @foo.add_foreign_key(:users, to.to_sym)
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_should_remove_foreign_key
|
44
|
+
assert_equal remove_command, remove
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_should_remove_foreign_key_with_optional_name
|
48
|
+
assert_equal remove_command(CUSTOM_ID), remove(:name => CUSTOM_ID)
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def add(options = {})
|
54
|
+
@foo.add_foreign_key :users, :files, options
|
55
|
+
end
|
56
|
+
|
57
|
+
def remove(options = {})
|
58
|
+
@foo.remove_foreign_key :users, :files, options
|
59
|
+
end
|
60
|
+
|
61
|
+
def add_command(id = ID, to = 'files')
|
62
|
+
"ALTER TABLE users ADD CONSTRAINT #{id} FOREIGN KEY(#{to.singularize}_id) REFERENCES #{to}(id)"
|
63
|
+
end
|
64
|
+
|
65
|
+
def remove_command(id = ID)
|
66
|
+
"ALTER TABLE users DROP FOREIGN KEY #{id}"
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
metadata
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: phlawski-migration_fu
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Steffen Leistner
|
8
|
+
- Piotr Hlawski
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2009-02-05 00:00:00 -08:00
|
14
|
+
default_executable:
|
15
|
+
dependencies: []
|
16
|
+
|
17
|
+
description: Add or remove foreign keys
|
18
|
+
email: sleistner@gmail.com
|
19
|
+
executables: []
|
20
|
+
|
21
|
+
extensions: []
|
22
|
+
|
23
|
+
extra_rdoc_files:
|
24
|
+
- README.rdoc
|
25
|
+
- lib/migration_fu.rb
|
26
|
+
files:
|
27
|
+
- migration_fu.gemspec
|
28
|
+
- install.rb
|
29
|
+
- README.rdoc
|
30
|
+
- nbproject/project.xml
|
31
|
+
- nbproject/project.properties
|
32
|
+
- test/migration_fu_test.rb
|
33
|
+
- init.rb
|
34
|
+
- lib/migration_fu.rb
|
35
|
+
- Rakefile
|
36
|
+
- Manifest
|
37
|
+
has_rdoc: true
|
38
|
+
homepage: http://github.com/phlawski/migration_fu
|
39
|
+
post_install_message:
|
40
|
+
rdoc_options:
|
41
|
+
- --line-numbers
|
42
|
+
- --inline-source
|
43
|
+
- --title
|
44
|
+
- Migration_fu
|
45
|
+
- --main
|
46
|
+
- README.rdoc
|
47
|
+
require_paths:
|
48
|
+
- lib
|
49
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: "0"
|
54
|
+
version:
|
55
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: "1.2"
|
60
|
+
version:
|
61
|
+
requirements: []
|
62
|
+
|
63
|
+
rubyforge_project: migration_fu
|
64
|
+
rubygems_version: 1.2.0
|
65
|
+
signing_key:
|
66
|
+
specification_version: 2
|
67
|
+
summary: Add or remove foreign keys
|
68
|
+
test_files:
|
69
|
+
- test/migration_fu_test.rb
|