migration-fu 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.
@@ -0,0 +1,4 @@
1
+ .svn
2
+ pkg
3
+ doc
4
+ Manifest
@@ -0,0 +1,51 @@
1
+ = MigrationFu
2
+
3
+ Rails gem / plugin for generating mysql 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
+ add_foreign_key(:addresses, :users, :on_delete => :cascade)
34
+ add_foreign_key(:addresses, :users, :on_delete => :cascade, :on_update => :cascade)
35
+
36
+ class CreateUsers < ActiveRecord::Migration
37
+
38
+ def self.up
39
+ create_table :users, :force => true do |t|
40
+ t.string :username, :null => false
41
+ t.string :password, :null => false
42
+ end
43
+
44
+ create_table :addresses, :force => true do |t|
45
+ t.references :user
46
+ t.string :street, :null => false
47
+ end
48
+
49
+ add_foreign_key(:addresses, :users, :on_delete => :cascade)
50
+ end
51
+ end
@@ -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 = 'Rails gem / plugin for generating mysql foreign key constraints.'
38
+ p.url = 'http://github.com/sleistner/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'
@@ -0,0 +1 @@
1
+ puts IO.read(File.join(File.dirname(__FILE__), 'README.rdoc'))
@@ -0,0 +1,58 @@
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, fk|
13
+ execute "ALTER TABLE #{ft} ADD CONSTRAINT #{id} FOREIGN KEY(#{fk}) REFERENCES #{tt}(id)" << conditions(options)
14
+ end
15
+ end
16
+
17
+ def remove_foreign_key(from_table, to_table, options = {})
18
+ process(from_table, to_table, options) do |ft, tt, id|
19
+ execute "ALTER TABLE #{ft} DROP FOREIGN KEY #{id}, DROP KEY #{id}"
20
+ end
21
+ end
22
+
23
+ def entirely_reset_column_information
24
+ ActiveRecord::Base.send(:subclasses).each(&:reset_column_information)
25
+ end
26
+
27
+ private
28
+
29
+ def conditions(options)
30
+ conditions = ''
31
+ options.each_pair do |key, value|
32
+ conditions << " #{key.to_s.gsub(/_/, ' ')} #{value.to_s.gsub(/_/, ' ')}".upcase if condition_valid?(key, value)
33
+ end
34
+ conditions
35
+ end
36
+
37
+ def condition_valid?(key, value)
38
+ OPTION_VALUES.include?(key.to_sym) && OPTION_KEYS.include?(value.to_sym)
39
+ end
40
+
41
+ def process(from_table, to_table, options)
42
+ id = options[:name] || "fk_#{from_table}_#{to_table}"
43
+ if options[:fk_field]
44
+ fk = options[:fk_field]
45
+ id = "#{id}_#{options[:fk_field]}"
46
+ else
47
+ fk = "#{to_table.to_s.singularize}_id"
48
+ end
49
+
50
+ if id.size > MAX_KEY_LENGTH
51
+ puts "*** foreign key id has more than #{MAX_KEY_LENGTH} characters - sliced to '#{id}'"
52
+ end
53
+ yield(from_table.to_s, to_table, id[0...MAX_KEY_LENGTH], fk)
54
+ end
55
+
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,5 @@
1
+ module Migration
2
+ module Fu
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "migration-fu"
7
+ s.version = Migration::Fu::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["me also"]
10
+ s.email = ["sumskyi@gmail.com"]
11
+ s.homepage = ""
12
+ s.summary = %q{fks}
13
+ s.description = %q{foreign keys support for MySQL}
14
+
15
+ s.rubyforge_project = "sumskyi-migration-fu"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+ end
@@ -0,0 +1,85 @@
1
+ require 'test/unit'
2
+ require 'rubygems'
3
+ begin require 'redgreen'; rescue LoadError; end
4
+ require File.dirname(__FILE__) + '/../lib/migration_fu'
5
+
6
+ class String
7
+ def singularize; self[0...-1] end
8
+ end
9
+
10
+ class ActiveRecord::Migration
11
+ def self.execute command; command end
12
+ end
13
+
14
+ class MigrationFuTest < Test::Unit::TestCase
15
+
16
+ ID = 'fk_users_files'
17
+ CUSTOM_ID = 'fk_my_name'
18
+ CUSTOM_FK = 'person_id'
19
+
20
+ def setup
21
+ @foo = ActiveRecord::Migration
22
+ end
23
+
24
+ def test_should_add_foreign_key_without_options
25
+ assert_equal add_command, add
26
+ end
27
+
28
+ def test_should_add_foreign_key_with_invalid_options_but_ignore_them
29
+ assert_equal add_command, add(:on_del => :ca)
30
+ end
31
+
32
+ def test_should_add_foreign_key_with_valid_options
33
+ assert_equal "#{add_command} ON DELETE CASCADE", add(:on_delete => :cascade)
34
+ assert_match(/ON DELETE CASCADE/, add(:on_update => :set_null, :on_delete => :cascade))
35
+ assert_match(/ON UPDATE SET NULL/, add(:on_update => :set_null, :on_delete => :cascade))
36
+ end
37
+
38
+ def test_should_add_foreign_key_with_optional_name
39
+ assert_equal add_command(CUSTOM_ID), add(:name => CUSTOM_ID)
40
+ end
41
+
42
+ #
43
+ def test_should_add_foreign_key_with_optional_fk_field
44
+ assert_equal add_command(CUSTOM_ID, :fk_field => CUSTOM_FK), add(:name => CUSTOM_ID, :fk_field => CUSTOM_FK)
45
+ end
46
+
47
+ def test_should_add_foreign_key_and_truncate_id
48
+ to = 'x' * 70
49
+ assert_equal add_command('fk_users_' << 'x' * 55, :to => to), @foo.add_foreign_key(:users, to.to_sym)
50
+ end
51
+
52
+ def test_should_remove_foreign_key
53
+ assert_equal remove_command, remove
54
+ end
55
+
56
+ def test_should_remove_foreign_key_with_optional_name
57
+ assert_equal remove_command(CUSTOM_ID), remove(:name => CUSTOM_ID)
58
+ end
59
+
60
+ private
61
+
62
+ def add(options = {})
63
+ @foo.add_foreign_key :users, :files, options
64
+ end
65
+
66
+ def remove(options = {})
67
+ @foo.remove_foreign_key :users, :files, options
68
+ end
69
+
70
+ def add_command(id = ID, opts = {})
71
+ opts = {:to => 'files'}.merge!(opts)
72
+ if opts[:fk_field]
73
+ fk = opts[:fk_field]
74
+ id = "#{id}_#{opts[:fk_field]}"
75
+ else
76
+ fk = "#{opts[:to].singularize}_id"
77
+ end
78
+ "ALTER TABLE users ADD CONSTRAINT #{id} FOREIGN KEY(#{fk}) REFERENCES #{opts[:to]}(id)"
79
+ end
80
+
81
+ def remove_command(id = ID)
82
+ "ALTER TABLE users DROP FOREIGN KEY #{id}, DROP KEY #{id}"
83
+ end
84
+
85
+ end
metadata ADDED
@@ -0,0 +1,76 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: migration-fu
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - me also
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-01-25 00:00:00 +02:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description: foreign keys support for MySQL
23
+ email:
24
+ - sumskyi@gmail.com
25
+ executables: []
26
+
27
+ extensions: []
28
+
29
+ extra_rdoc_files: []
30
+
31
+ files:
32
+ - .gitignore
33
+ - README.rdoc
34
+ - Rakefile
35
+ - init.rb
36
+ - install.rb
37
+ - lib/migration_fu.rb
38
+ - lib/version.rb
39
+ - migration-fu.gemspec
40
+ - test/migration_fu_test.rb
41
+ has_rdoc: true
42
+ homepage: ""
43
+ licenses: []
44
+
45
+ post_install_message:
46
+ rdoc_options: []
47
+
48
+ require_paths:
49
+ - lib
50
+ required_ruby_version: !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ hash: 3
56
+ segments:
57
+ - 0
58
+ version: "0"
59
+ required_rubygems_version: !ruby/object:Gem::Requirement
60
+ none: false
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ hash: 3
65
+ segments:
66
+ - 0
67
+ version: "0"
68
+ requirements: []
69
+
70
+ rubyforge_project: sumskyi-migration-fu
71
+ rubygems_version: 1.4.2
72
+ signing_key:
73
+ specification_version: 3
74
+ summary: fks
75
+ test_files:
76
+ - test/migration_fu_test.rb