also_migrate_nj 0.3.6
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 +7 -0
- data/LICENSE +18 -0
- data/README.md +50 -0
- data/Rakefile +90 -0
- data/also_migrate.gemspec +32 -0
- data/config/gemsets.yml +4 -0
- data/config/gemspec.yml +12 -0
- data/init.rb +1 -0
- data/lib/also_migrate.rb +15 -0
- data/lib/also_migrate/gems.rb +154 -0
- data/lib/also_migrate/migration.rb +66 -0
- data/lib/also_migrate/migrator.rb +99 -0
- data/rails/init.rb +1 -0
- data/spec/Rakefile +13 -0
- data/spec/also_migrate/gems_spec.rb +249 -0
- data/spec/also_migrate_spec.rb +183 -0
- data/spec/config/database.yml.example +6 -0
- data/spec/db/migrate/001_create_articles.rb +15 -0
- data/spec/db/migrate/002_add_permalink.rb +9 -0
- data/spec/db/migrate/003_create_comments.rb +12 -0
- data/spec/fixtures/gemsets.yml +9 -0
- data/spec/fixtures/gemspec.yml +15 -0
- data/spec/spec_helper.rb +94 -0
- metadata +110 -0
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
Copyright (c) 2010
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
4
|
+
this software and associated documentation files (the "Software"), to deal in
|
5
|
+
the Software without restriction, including without limitation the rights to
|
6
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
7
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
8
|
+
subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
11
|
+
copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
15
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
16
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
17
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
18
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
AlsoMigrate
|
2
|
+
===========
|
3
|
+
|
4
|
+
Migrate multiple tables with similar schema at once.
|
5
|
+
|
6
|
+
Requirements
|
7
|
+
------------
|
8
|
+
|
9
|
+
<pre>
|
10
|
+
gem install also_migrate
|
11
|
+
</pre>
|
12
|
+
|
13
|
+
Configure
|
14
|
+
---------
|
15
|
+
|
16
|
+
<pre>
|
17
|
+
AlsoMigrate.configuration = [
|
18
|
+
{
|
19
|
+
:source => 'articles',
|
20
|
+
:destination => 'article_archives',
|
21
|
+
:add => [
|
22
|
+
# Parameters to ActiveRecord::ConnectionAdapters::SchemaStatements#add_column
|
23
|
+
[ 'deleted_at', :datetime, {} ]
|
24
|
+
],
|
25
|
+
:subtract => 'restored_at',
|
26
|
+
:ignore => 'deleted_at',
|
27
|
+
:indexes => 'id'
|
28
|
+
},
|
29
|
+
{
|
30
|
+
:source => 'users',
|
31
|
+
:destination => [ 'banned_users', 'deleted_users' ]
|
32
|
+
}
|
33
|
+
]
|
34
|
+
</pre>
|
35
|
+
|
36
|
+
Options:
|
37
|
+
|
38
|
+
* <code>source</code> Database schema source table
|
39
|
+
* <code>destination</code> Database schema destination table (can also be an array of tables)
|
40
|
+
* <code>add</code> Create columns that the original table doesn't have (defaults to none)
|
41
|
+
* <code>subtract</code> Exclude columns from the original table (defaults to none)
|
42
|
+
* <code>ignore</code> Ignore migrations that apply to certain columns (defaults to none)
|
43
|
+
* <code>indexes</code> Only index certain columns (duplicates all indexes by default)
|
44
|
+
|
45
|
+
That's it!
|
46
|
+
----------
|
47
|
+
|
48
|
+
Next time you migrate, <code>article_archives</code> is created if it doesn't exist.
|
49
|
+
|
50
|
+
Any new migration applied to <code>articles</code> is automatically applied to <code>article_archives</code>.
|
data/Rakefile
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/lib/also_migrate/gems'
|
2
|
+
|
3
|
+
AlsoMigrate::Gems.activate %w(rake rspec)
|
4
|
+
|
5
|
+
require 'rake'
|
6
|
+
require 'spec/rake/spectask'
|
7
|
+
|
8
|
+
def gemspec
|
9
|
+
@gemspec ||= begin
|
10
|
+
file = File.expand_path('../also_migrate.gemspec', __FILE__)
|
11
|
+
eval(File.read(file), binding, file)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
if defined?(Spec::Rake::SpecTask)
|
16
|
+
desc "Run specs"
|
17
|
+
Spec::Rake::SpecTask.new do |t|
|
18
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
19
|
+
t.spec_opts = %w(-fs --color)
|
20
|
+
t.warning = true
|
21
|
+
end
|
22
|
+
task :spec
|
23
|
+
task :default => :spec
|
24
|
+
end
|
25
|
+
|
26
|
+
desc "Build gem(s)"
|
27
|
+
task :gem do
|
28
|
+
old_gemset = ENV['GEMSET']
|
29
|
+
root = File.expand_path('../', __FILE__)
|
30
|
+
pkg = "#{root}/pkg"
|
31
|
+
system "rm -Rf #{pkg}"
|
32
|
+
AlsoMigrate::Gems.gemset_names.each do |gemset|
|
33
|
+
ENV['GEMSET'] = gemset.to_s
|
34
|
+
system "cd #{root} && gem build also_migrate.gemspec"
|
35
|
+
system "mkdir -p #{pkg} && mv *.gem pkg"
|
36
|
+
end
|
37
|
+
ENV['GEMSET'] = old_gemset
|
38
|
+
end
|
39
|
+
|
40
|
+
namespace :gem do
|
41
|
+
desc "Install gem(s)"
|
42
|
+
task :install do
|
43
|
+
Rake::Task['gem'].invoke
|
44
|
+
Dir["#{File.dirname(__FILE__)}/pkg/*.gem"].each do |pkg|
|
45
|
+
system "gem install #{pkg} --no-ri --no-rdoc"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
desc "Push gem(s)"
|
50
|
+
task :push do
|
51
|
+
Rake::Task['gem'].invoke
|
52
|
+
Dir["#{File.dirname(__FILE__)}/pkg/*.gem"].each do |pkg|
|
53
|
+
system "gem push #{pkg}"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
namespace :gems do
|
59
|
+
desc "Install gem dependencies (DEV=0 DOCS=0 GEMSPEC=default SUDO=0)"
|
60
|
+
task :install do
|
61
|
+
dev = ENV['DEV'] == '1'
|
62
|
+
docs = ENV['DOCS'] == '1' ? '' : '--no-ri --no-rdoc'
|
63
|
+
gemset = ENV['GEMSET']
|
64
|
+
sudo = ENV['SUDO'] == '1' ? 'sudo' : ''
|
65
|
+
|
66
|
+
AlsoMigrate::Gems.gemset = gemset if gemset
|
67
|
+
|
68
|
+
if dev
|
69
|
+
gems = AlsoMigrate::Gems.gemspec.development_dependencies
|
70
|
+
else
|
71
|
+
gems = AlsoMigrate::Gems.gemspec.dependencies
|
72
|
+
end
|
73
|
+
|
74
|
+
gems.each do |name|
|
75
|
+
name = name.to_s
|
76
|
+
version = AlsoMigrate::Gems.versions[name]
|
77
|
+
if Gem.source_index.find_name(name, version).empty?
|
78
|
+
version = version ? "-v #{version}" : ''
|
79
|
+
system "#{sudo} gem install #{name} #{version} #{docs}"
|
80
|
+
else
|
81
|
+
puts "already installed: #{name} #{version}"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
desc "Validate the gemspec"
|
88
|
+
task :gemspec do
|
89
|
+
gemspec.validate
|
90
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
root = File.expand_path('../', __FILE__)
|
3
|
+
lib = "#{root}/lib"
|
4
|
+
$:.unshift lib unless $:.include?(lib)
|
5
|
+
|
6
|
+
require 'also_migrate/gems'
|
7
|
+
AlsoMigrate::Gems.gemset ||= ENV['GEMSET'] || :default
|
8
|
+
|
9
|
+
Gem::Specification.new do |s|
|
10
|
+
AlsoMigrate::Gems.gemspec.hash.each do |key, value|
|
11
|
+
if key == 'name' && AlsoMigrate::Gems.gemset != :default
|
12
|
+
s.name = "#{value}-#{AlsoMigrate::Gems.gemset}"
|
13
|
+
elsif key == 'summary' && AlsoMigrate::Gems.gemset == :solo
|
14
|
+
s.summary = value + " (no dependencies)"
|
15
|
+
elsif !%w(dependencies development_dependencies).include?(key)
|
16
|
+
s.send "#{key}=", value
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
AlsoMigrate::Gems.dependencies.each do |g|
|
21
|
+
s.add_dependency g.to_s, AlsoMigrate::Gems.versions[g]
|
22
|
+
end
|
23
|
+
|
24
|
+
AlsoMigrate::Gems.development_dependencies.each do |g|
|
25
|
+
s.add_development_dependency g.to_s, AlsoMigrate::Gems.versions[g]
|
26
|
+
end
|
27
|
+
|
28
|
+
s.executables = `cd #{root} && git ls-files -- {bin}/*`.split("\n").collect { |f| File.basename(f) }
|
29
|
+
s.files = `cd #{root} && git ls-files`.split("\n")
|
30
|
+
s.require_paths = %w(lib)
|
31
|
+
s.test_files = `cd #{root} && git ls-files -- {features,test,spec}/*`.split("\n")
|
32
|
+
end
|
data/config/gemsets.yml
ADDED
data/config/gemspec.yml
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
name: also_migrate_nj
|
2
|
+
version: 0.3.6
|
3
|
+
authors:
|
4
|
+
- Winton Welsh
|
5
|
+
email: james@njtechnologies.co.uk
|
6
|
+
homepage: https://github.com/jamesharker/also_migrate
|
7
|
+
summary: Migrate multiple tables with similar schema at once.
|
8
|
+
description: Migrate multiple tables with similar schema at once.
|
9
|
+
dependencies: null
|
10
|
+
development_dependencies:
|
11
|
+
- rake
|
12
|
+
- rspec
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/rails/init"
|
data/lib/also_migrate.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/also_migrate/gems'
|
2
|
+
|
3
|
+
$:.unshift File.dirname(__FILE__)
|
4
|
+
|
5
|
+
require 'also_migrate/migration'
|
6
|
+
require 'also_migrate/migrator'
|
7
|
+
|
8
|
+
module AlsoMigrate
|
9
|
+
class <<self
|
10
|
+
attr_accessor :configuration
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
ActiveRecord::Migrator.send(:include, AlsoMigrate::Migrator)
|
15
|
+
ActiveRecord::Migration.send(:include, AlsoMigrate::Migration)
|
@@ -0,0 +1,154 @@
|
|
1
|
+
unless defined?(AlsoMigrate::Gems)
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
module AlsoMigrate
|
6
|
+
module Gems
|
7
|
+
class <<self
|
8
|
+
|
9
|
+
attr_accessor :config
|
10
|
+
attr_reader :gemset, :gemsets, :versions
|
11
|
+
|
12
|
+
class SimpleStruct
|
13
|
+
attr_reader :hash
|
14
|
+
|
15
|
+
def initialize(hash)
|
16
|
+
@hash = hash
|
17
|
+
@hash.each do |key, value|
|
18
|
+
self.class.send(:define_method, key) { @hash[key] }
|
19
|
+
self.class.send(:define_method, "#{key}=") { |v| @hash[key] = v }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
Gems.config = SimpleStruct.new(
|
25
|
+
:gemsets => [ "#{File.expand_path('../../../', __FILE__)}/config/gemsets.yml" ],
|
26
|
+
:gemspec => "#{File.expand_path('../../../', __FILE__)}/config/gemspec.yml",
|
27
|
+
:warn => true
|
28
|
+
)
|
29
|
+
|
30
|
+
def activate(*gems)
|
31
|
+
begin
|
32
|
+
require 'rubygems' unless defined?(::Gem)
|
33
|
+
rescue LoadError
|
34
|
+
puts "rubygems library could not be required" if @config.warn
|
35
|
+
end
|
36
|
+
|
37
|
+
self.gemset ||= gemset_from_loaded_specs
|
38
|
+
|
39
|
+
gems.flatten.collect(&:to_sym).each do |name|
|
40
|
+
version = @versions[name]
|
41
|
+
vendor = File.expand_path("../../../vendor/#{name}/lib", __FILE__)
|
42
|
+
if File.exists?(vendor)
|
43
|
+
$:.unshift vendor
|
44
|
+
elsif defined?(gem)
|
45
|
+
gem name.to_s, version
|
46
|
+
else
|
47
|
+
puts "#{name} #{"(#{version})" if version} failed to activate" if @config.warn
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def dependencies
|
53
|
+
dependency_filter(@gemspec.dependencies, @gemset)
|
54
|
+
end
|
55
|
+
|
56
|
+
def development_dependencies
|
57
|
+
dependency_filter(@gemspec.development_dependencies, @gemset)
|
58
|
+
end
|
59
|
+
|
60
|
+
def gemset=(gemset)
|
61
|
+
if gemset
|
62
|
+
@gemset = gemset.to_sym
|
63
|
+
|
64
|
+
@gemsets = @config.gemsets.reverse.collect { |config|
|
65
|
+
if config.is_a?(::String)
|
66
|
+
YAML::load(File.read(config)) rescue {}
|
67
|
+
elsif config.is_a?(::Hash)
|
68
|
+
config
|
69
|
+
end
|
70
|
+
}.inject({}) do |hash, config|
|
71
|
+
deep_merge(hash, symbolize_keys(config))
|
72
|
+
end
|
73
|
+
|
74
|
+
@versions = (@gemsets[gemspec.name.to_sym] || {}).inject({}) do |hash, (key, value)|
|
75
|
+
if !value.is_a?(::Hash) && value
|
76
|
+
hash[key] = value
|
77
|
+
elsif key == @gemset
|
78
|
+
(value || {}).each { |k, v| hash[k] = v }
|
79
|
+
end
|
80
|
+
hash
|
81
|
+
end
|
82
|
+
else
|
83
|
+
@gemset = nil
|
84
|
+
@gemsets = nil
|
85
|
+
@versions = nil
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def gemset_names
|
90
|
+
(
|
91
|
+
[ :default ] +
|
92
|
+
@gemsets[gemspec.name.to_sym].inject([]) { |array, (key, value)|
|
93
|
+
array.push(key) if value.is_a?(::Hash) || value.nil?
|
94
|
+
array
|
95
|
+
}
|
96
|
+
).uniq
|
97
|
+
end
|
98
|
+
|
99
|
+
def gemspec(reload=false)
|
100
|
+
if @gemspec && !reload
|
101
|
+
@gemspec
|
102
|
+
else
|
103
|
+
data = YAML::load(File.read(@config.gemspec)) rescue {}
|
104
|
+
@gemspec = SimpleStruct.new(data)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
private
|
109
|
+
|
110
|
+
def deep_merge(first, second)
|
111
|
+
merger = lambda do |key, v1, v2|
|
112
|
+
Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : v2
|
113
|
+
end
|
114
|
+
first.merge(second, &merger)
|
115
|
+
end
|
116
|
+
|
117
|
+
def dependency_filter(dependencies, match)
|
118
|
+
(dependencies || []).inject([]) { |array, value|
|
119
|
+
if value.is_a?(::Hash)
|
120
|
+
array += value[match.to_s] if value[match.to_s]
|
121
|
+
else
|
122
|
+
array << value
|
123
|
+
end
|
124
|
+
array
|
125
|
+
}.uniq.collect(&:to_sym)
|
126
|
+
end
|
127
|
+
|
128
|
+
def gemset_from_loaded_specs
|
129
|
+
if defined?(Gem)
|
130
|
+
Gem.loaded_specs.each do |name, spec|
|
131
|
+
if name == gemspec.name
|
132
|
+
return :default
|
133
|
+
elsif name[0..gemspec.name.length] == "#{gemspec.name}-"
|
134
|
+
return name[gemspec.name.length+1..-1].to_sym
|
135
|
+
end
|
136
|
+
end
|
137
|
+
:default
|
138
|
+
else
|
139
|
+
:none
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
def symbolize_keys(hash)
|
144
|
+
return {} unless hash.is_a?(::Hash)
|
145
|
+
hash.inject({}) do |options, (key, value)|
|
146
|
+
value = symbolize_keys(value) if value.is_a?(::Hash)
|
147
|
+
options[(key.to_sym rescue key) || key] = value
|
148
|
+
options
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module AlsoMigrate
|
2
|
+
module Migration
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
unless base.respond_to?(:method_missing_with_also_migrate)
|
6
|
+
base.extend ClassMethods
|
7
|
+
base.class_eval do
|
8
|
+
class <<self
|
9
|
+
alias_method :method_missing_without_also_migrate, :method_missing
|
10
|
+
alias_method :method_missing, :method_missing_with_also_migrate
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
module ClassMethods
|
17
|
+
|
18
|
+
def method_missing_with_also_migrate(method, *arguments, &block)
|
19
|
+
args = Marshal.load(Marshal.dump(arguments))
|
20
|
+
return_value = method_missing_without_also_migrate(method, *arguments, &block)
|
21
|
+
|
22
|
+
supported = [
|
23
|
+
:add_column, :add_index, :add_timestamps, :change_column,
|
24
|
+
:change_column_default, :change_table, :create_table,
|
25
|
+
:drop_table, :remove_column, :remove_columns,
|
26
|
+
:remove_timestamps, :rename_column, :rename_table
|
27
|
+
]
|
28
|
+
|
29
|
+
if !args.empty? && supported.include?(method)
|
30
|
+
connection = ActiveRecord::Base.connection
|
31
|
+
table_name = ActiveRecord::Migrator.proper_table_name(args[0])
|
32
|
+
|
33
|
+
# Find models
|
34
|
+
(::AlsoMigrate.configuration || []).each do |config|
|
35
|
+
next unless config[:source].to_s == table_name
|
36
|
+
|
37
|
+
# Don't change ignored columns
|
38
|
+
[ config[:ignore] ].flatten.compact.each do |column|
|
39
|
+
next if args.include?(column) || args.include?(column.intern)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Run migration
|
43
|
+
if method == :create_table
|
44
|
+
ActiveRecord::Migrator::AlsoMigrate.create_tables(config)
|
45
|
+
elsif method == :add_index && !config[:indexes].nil?
|
46
|
+
next
|
47
|
+
else
|
48
|
+
[ config[:destination] ].flatten.compact.each do |table|
|
49
|
+
if connection.table_exists?(table)
|
50
|
+
args[0] = table
|
51
|
+
begin
|
52
|
+
connection.send(method, *args, &block)
|
53
|
+
rescue Exception => e
|
54
|
+
puts "(also_migrate warning) #{e.message}"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
return return_value
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
module AlsoMigrate
|
2
|
+
module Migrator
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
unless base.included_modules.include?(InstanceMethods)
|
6
|
+
base.send :include, InstanceMethods
|
7
|
+
base.class_eval do
|
8
|
+
alias_method :migrate_without_also_migrate, :migrate
|
9
|
+
alias_method :migrate, :migrate_with_also_migrate
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
module InstanceMethods
|
15
|
+
|
16
|
+
def migrate_with_also_migrate
|
17
|
+
(::AlsoMigrate.configuration || []).each do |config|
|
18
|
+
AlsoMigrate.create_tables(config)
|
19
|
+
end
|
20
|
+
rescue Exception => e
|
21
|
+
puts "AlsoMigrate error: #{e.message}"
|
22
|
+
puts e.backtrace.join("\n")
|
23
|
+
ensure
|
24
|
+
migrate_without_also_migrate
|
25
|
+
end
|
26
|
+
|
27
|
+
module AlsoMigrate
|
28
|
+
class <<self
|
29
|
+
|
30
|
+
def connection
|
31
|
+
ActiveRecord::Base.connection
|
32
|
+
end
|
33
|
+
|
34
|
+
def create_tables(config)
|
35
|
+
[ config[:destination] ].flatten.compact.each do |new_table|
|
36
|
+
if !connection.table_exists?(new_table) && connection.table_exists?(config[:source])
|
37
|
+
columns = connection.columns(config[:source]).collect(&:name)
|
38
|
+
columns -= [ config[:subtract] ].flatten.compact.collect(&:to_s)
|
39
|
+
columns.collect! { |col| connection.quote_column_name(col) }
|
40
|
+
if config[:indexes]
|
41
|
+
engine =
|
42
|
+
if connection.class.to_s.include?('Mysql')
|
43
|
+
'ENGINE=' + connection.select_one(<<-SQL)['Engine']
|
44
|
+
SHOW TABLE STATUS
|
45
|
+
WHERE Name = '#{config[:source]}'
|
46
|
+
SQL
|
47
|
+
end
|
48
|
+
connection.execute(<<-SQL)
|
49
|
+
CREATE TABLE #{new_table} #{engine}
|
50
|
+
AS SELECT #{columns.join(',')}
|
51
|
+
FROM #{config[:source]}
|
52
|
+
WHERE false;
|
53
|
+
SQL
|
54
|
+
[ config[:indexes] ].flatten.compact.each do |column|
|
55
|
+
connection.add_index(new_table, column)
|
56
|
+
end
|
57
|
+
else
|
58
|
+
if connection.class.to_s.include?('SQLite')
|
59
|
+
col_string = connection.columns(config[:source]).collect {|c|
|
60
|
+
"#{c.name} #{c.sql_type}"
|
61
|
+
}.join(', ')
|
62
|
+
connection.execute(<<-SQL)
|
63
|
+
CREATE TABLE #{new_table}
|
64
|
+
(#{col_string})
|
65
|
+
SQL
|
66
|
+
else
|
67
|
+
connection.execute(<<-SQL)
|
68
|
+
CREATE TABLE #{new_table}
|
69
|
+
(LIKE) #{config[:source]};
|
70
|
+
SQL
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
if connection.table_exists?(new_table)
|
75
|
+
if config[:add] || config[:subtract]
|
76
|
+
columns = connection.columns(new_table).collect(&:name)
|
77
|
+
end
|
78
|
+
if config[:add]
|
79
|
+
config[:add].each do |column|
|
80
|
+
unless columns.include?(column[0])
|
81
|
+
connection.add_column(*([ new_table ] + column))
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
if config[:subtract]
|
86
|
+
[ config[:subtract] ].flatten.compact.each do |column|
|
87
|
+
if columns.include?(column)
|
88
|
+
connection.remove_column(new_table, column)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
data/rails/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../lib/also_migrate')
|
data/spec/Rakefile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../lib/also_migrate/gems')
|
2
|
+
|
3
|
+
AlsoMigrate::Gems.activate(:active_wrapper)
|
4
|
+
|
5
|
+
require 'active_wrapper/tasks'
|
6
|
+
|
7
|
+
#begin
|
8
|
+
ActiveWrapper::Tasks.new(
|
9
|
+
:base => File.dirname(__FILE__),
|
10
|
+
:env => ENV['ENV'] || 'test'
|
11
|
+
)
|
12
|
+
# rescue Exception
|
13
|
+
# end
|
@@ -0,0 +1,249 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe AlsoMigrate::Gems do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
@old_config = AlsoMigrate::Gems.config
|
7
|
+
|
8
|
+
AlsoMigrate::Gems.config.gemspec = "#{$root}/spec/fixtures/gemspec.yml"
|
9
|
+
AlsoMigrate::Gems.config.gemsets = [
|
10
|
+
"#{$root}/spec/fixtures/gemsets.yml"
|
11
|
+
]
|
12
|
+
AlsoMigrate::Gems.config.warn = true
|
13
|
+
|
14
|
+
AlsoMigrate::Gems.gemspec true
|
15
|
+
AlsoMigrate::Gems.gemset = nil
|
16
|
+
end
|
17
|
+
|
18
|
+
after(:each) do
|
19
|
+
AlsoMigrate::Gems.config = @old_config
|
20
|
+
end
|
21
|
+
|
22
|
+
describe :activate do
|
23
|
+
it "should activate gems" do
|
24
|
+
AlsoMigrate::Gems.stub!(:gem)
|
25
|
+
AlsoMigrate::Gems.should_receive(:gem).with('rspec', '=1.3.1')
|
26
|
+
AlsoMigrate::Gems.should_receive(:gem).with('rake', '=0.8.7')
|
27
|
+
AlsoMigrate::Gems.activate :rspec, 'rake'
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe :gemset= do
|
32
|
+
before(:each) do
|
33
|
+
AlsoMigrate::Gems.config.gemsets = [
|
34
|
+
{
|
35
|
+
:name => {
|
36
|
+
:rake => '>0.8.6',
|
37
|
+
:default => {
|
38
|
+
:externals => '=1.0.2'
|
39
|
+
}
|
40
|
+
}
|
41
|
+
},
|
42
|
+
"#{$root}/spec/fixtures/gemsets.yml"
|
43
|
+
]
|
44
|
+
end
|
45
|
+
|
46
|
+
describe :default do
|
47
|
+
before(:each) do
|
48
|
+
AlsoMigrate::Gems.gemset = :default
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should set @gemset" do
|
52
|
+
AlsoMigrate::Gems.gemset.should == :default
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should set @gemsets" do
|
56
|
+
AlsoMigrate::Gems.gemsets.should == {
|
57
|
+
:name => {
|
58
|
+
:rake => ">0.8.6",
|
59
|
+
:default => {
|
60
|
+
:externals => '=1.0.2',
|
61
|
+
:mysql => "=2.8.1",
|
62
|
+
:rspec => "=1.3.1"
|
63
|
+
},
|
64
|
+
:rspec2 => {
|
65
|
+
:mysql2 => "=0.2.6",
|
66
|
+
:rspec => "=2.3.0"
|
67
|
+
},
|
68
|
+
:solo => nil
|
69
|
+
}
|
70
|
+
}
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should set Gems.versions" do
|
74
|
+
AlsoMigrate::Gems.versions.should == {
|
75
|
+
:externals => "=1.0.2",
|
76
|
+
:mysql => "=2.8.1",
|
77
|
+
:rake => ">0.8.6",
|
78
|
+
:rspec => "=1.3.1"
|
79
|
+
}
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should return proper values for Gems.dependencies" do
|
83
|
+
AlsoMigrate::Gems.dependencies.should == [ :rake, :mysql ]
|
84
|
+
AlsoMigrate::Gems.development_dependencies.should == []
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should return proper values for Gems.gemset_names" do
|
88
|
+
AlsoMigrate::Gems.gemset_names.should == [ :default, :rspec2, :solo ]
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe :rspec2 do
|
93
|
+
before(:each) do
|
94
|
+
AlsoMigrate::Gems.gemset = "rspec2"
|
95
|
+
end
|
96
|
+
|
97
|
+
it "should set @gemset" do
|
98
|
+
AlsoMigrate::Gems.gemset.should == :rspec2
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should set @gemsets" do
|
102
|
+
AlsoMigrate::Gems.gemsets.should == {
|
103
|
+
:name => {
|
104
|
+
:rake => ">0.8.6",
|
105
|
+
:default => {
|
106
|
+
:externals => '=1.0.2',
|
107
|
+
:mysql => "=2.8.1",
|
108
|
+
:rspec => "=1.3.1"
|
109
|
+
},
|
110
|
+
:rspec2 => {
|
111
|
+
:mysql2=>"=0.2.6",
|
112
|
+
:rspec => "=2.3.0"
|
113
|
+
},
|
114
|
+
:solo => nil
|
115
|
+
}
|
116
|
+
}
|
117
|
+
end
|
118
|
+
|
119
|
+
it "should set Gems.versions" do
|
120
|
+
AlsoMigrate::Gems.versions.should == {
|
121
|
+
:mysql2 => "=0.2.6",
|
122
|
+
:rake => ">0.8.6",
|
123
|
+
:rspec => "=2.3.0"
|
124
|
+
}
|
125
|
+
end
|
126
|
+
|
127
|
+
it "should return proper values for Gems.dependencies" do
|
128
|
+
AlsoMigrate::Gems.dependencies.should == [ :rake, :mysql2 ]
|
129
|
+
AlsoMigrate::Gems.development_dependencies.should == []
|
130
|
+
end
|
131
|
+
|
132
|
+
it "should return proper values for Gems.gemset_names" do
|
133
|
+
AlsoMigrate::Gems.gemset_names.should == [ :default, :rspec2, :solo ]
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
describe :solo do
|
138
|
+
before(:each) do
|
139
|
+
AlsoMigrate::Gems.gemset = :solo
|
140
|
+
end
|
141
|
+
|
142
|
+
it "should set @gemset" do
|
143
|
+
AlsoMigrate::Gems.gemset.should == :solo
|
144
|
+
end
|
145
|
+
|
146
|
+
it "should set @gemsets" do
|
147
|
+
AlsoMigrate::Gems.gemsets.should == {
|
148
|
+
:name => {
|
149
|
+
:rake => ">0.8.6",
|
150
|
+
:default => {
|
151
|
+
:externals => '=1.0.2',
|
152
|
+
:mysql => "=2.8.1",
|
153
|
+
:rspec => "=1.3.1"
|
154
|
+
},
|
155
|
+
:rspec2 => {
|
156
|
+
:mysql2=>"=0.2.6",
|
157
|
+
:rspec => "=2.3.0"
|
158
|
+
},
|
159
|
+
:solo => nil
|
160
|
+
}
|
161
|
+
}
|
162
|
+
end
|
163
|
+
|
164
|
+
it "should set Gems.versions" do
|
165
|
+
AlsoMigrate::Gems.versions.should == {:rake=>">0.8.6"}
|
166
|
+
end
|
167
|
+
|
168
|
+
it "should return proper values for Gems.dependencies" do
|
169
|
+
AlsoMigrate::Gems.dependencies.should == [:rake]
|
170
|
+
AlsoMigrate::Gems.development_dependencies.should == []
|
171
|
+
end
|
172
|
+
|
173
|
+
it "should return proper values for Gems.gemset_names" do
|
174
|
+
AlsoMigrate::Gems.gemset_names.should == [ :default, :rspec2, :solo ]
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
describe :nil do
|
179
|
+
before(:each) do
|
180
|
+
AlsoMigrate::Gems.gemset = nil
|
181
|
+
end
|
182
|
+
|
183
|
+
it "should set everything to nil" do
|
184
|
+
AlsoMigrate::Gems.gemset.should == nil
|
185
|
+
AlsoMigrate::Gems.gemsets.should == nil
|
186
|
+
AlsoMigrate::Gems.versions.should == nil
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
describe :gemset_from_loaded_specs do
|
192
|
+
before(:each) do
|
193
|
+
Gem.stub!(:loaded_specs)
|
194
|
+
end
|
195
|
+
|
196
|
+
it "should return the correct gemset for name gem" do
|
197
|
+
Gem.should_receive(:loaded_specs).and_return({ "name" => nil })
|
198
|
+
AlsoMigrate::Gems.send(:gemset_from_loaded_specs).should == :default
|
199
|
+
end
|
200
|
+
|
201
|
+
it "should return the correct gemset for name-rspec gem" do
|
202
|
+
Gem.should_receive(:loaded_specs).and_return({ "name-rspec2" => nil })
|
203
|
+
AlsoMigrate::Gems.send(:gemset_from_loaded_specs).should == :rspec2
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
describe :reload_gemspec do
|
208
|
+
it "should populate @gemspec" do
|
209
|
+
AlsoMigrate::Gems.gemspec.hash.should == {
|
210
|
+
"name" => "name",
|
211
|
+
"version" => "0.1.0",
|
212
|
+
"authors" => ["Author"],
|
213
|
+
"email" => "email@email.com",
|
214
|
+
"homepage" => "http://github.com/author/name",
|
215
|
+
"summary" => "Summary",
|
216
|
+
"description" => "Description",
|
217
|
+
"dependencies" => [
|
218
|
+
"rake",
|
219
|
+
{ "default" => [ "mysql" ] },
|
220
|
+
{ "rspec2" => [ "mysql2" ] }
|
221
|
+
],
|
222
|
+
"development_dependencies" => nil
|
223
|
+
}
|
224
|
+
end
|
225
|
+
|
226
|
+
it "should create methods from keys of @gemspec" do
|
227
|
+
AlsoMigrate::Gems.gemspec.name.should == "name"
|
228
|
+
AlsoMigrate::Gems.gemspec.version.should == "0.1.0"
|
229
|
+
AlsoMigrate::Gems.gemspec.authors.should == ["Author"]
|
230
|
+
AlsoMigrate::Gems.gemspec.email.should == "email@email.com"
|
231
|
+
AlsoMigrate::Gems.gemspec.homepage.should == "http://github.com/author/name"
|
232
|
+
AlsoMigrate::Gems.gemspec.summary.should == "Summary"
|
233
|
+
AlsoMigrate::Gems.gemspec.description.should == "Description"
|
234
|
+
AlsoMigrate::Gems.gemspec.dependencies.should == [
|
235
|
+
"rake",
|
236
|
+
{ "default" => ["mysql"] },
|
237
|
+
{ "rspec2" => [ "mysql2" ] }
|
238
|
+
]
|
239
|
+
AlsoMigrate::Gems.gemspec.development_dependencies.should == nil
|
240
|
+
end
|
241
|
+
|
242
|
+
it "should produce a valid gemspec" do
|
243
|
+
AlsoMigrate::Gems.gemset = :default
|
244
|
+
gemspec = File.expand_path("../../../also_migrate.gemspec", __FILE__)
|
245
|
+
gemspec = eval(File.read(gemspec), binding, gemspec)
|
246
|
+
gemspec.validate.should == true
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
@@ -0,0 +1,183 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe AlsoMigrate do
|
4
|
+
|
5
|
+
[ "table doesn't exist yet", "table already exists" ].each do |description|
|
6
|
+
describe description do
|
7
|
+
describe 'with all options' do
|
8
|
+
|
9
|
+
before(:each) do
|
10
|
+
reset_fixture
|
11
|
+
|
12
|
+
if description == "table doesn't exist yet"
|
13
|
+
AlsoMigrate.configuration << {
|
14
|
+
:source => :articles,
|
15
|
+
:destination => :article_archives,
|
16
|
+
:add => [
|
17
|
+
[ 'deleted_at', :datetime ]
|
18
|
+
],
|
19
|
+
:subtract => 'restored_at',
|
20
|
+
:ignore => 'body',
|
21
|
+
:indexes => 'id'
|
22
|
+
}
|
23
|
+
end
|
24
|
+
|
25
|
+
$db.migrate(1)
|
26
|
+
$db.migrate(0)
|
27
|
+
$db.migrate(1)
|
28
|
+
|
29
|
+
if description == "table already exists"
|
30
|
+
AlsoMigrate.configuration << {
|
31
|
+
:source => :articles,
|
32
|
+
:destination => :article_archives,
|
33
|
+
:add => [
|
34
|
+
[ 'deleted_at', :datetime ]
|
35
|
+
],
|
36
|
+
:subtract => %w(restored_at),
|
37
|
+
:ignore => %w(body),
|
38
|
+
:indexes => %w(id)
|
39
|
+
}
|
40
|
+
$db.migrate(1)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should create the add column" do
|
45
|
+
(columns('article_archives') - columns('articles')).should == [ 'deleted_at' ]
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should not create the subtract column" do
|
49
|
+
(columns('articles') - columns('article_archives')).should == [ 'restored_at' ]
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'should migrate both tables up' do
|
53
|
+
migrate_with_state(2)
|
54
|
+
(@new_article_columns - @old_article_columns).should == [ 'permalink' ]
|
55
|
+
(@new_archive_columns - @old_archive_columns).should == [ 'permalink' ]
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'should migrate both tables down' do
|
59
|
+
$db.migrate(2)
|
60
|
+
migrate_with_state(1)
|
61
|
+
(@old_article_columns - @new_article_columns).should == [ 'permalink' ]
|
62
|
+
(@old_archive_columns - @new_archive_columns).should == [ 'permalink' ]
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should ignore the body column" do
|
66
|
+
(columns('article_archives') - columns('articles')).should == [ 'deleted_at' ]
|
67
|
+
connection.remove_column(:articles, :body)
|
68
|
+
(columns('article_archives') - columns('articles')).should == [ 'body', 'deleted_at' ]
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should only add an index for id" do
|
72
|
+
indexed_columns('articles').should == [ 'id', 'read' ]
|
73
|
+
indexed_columns('article_archives').should == [ 'id' ]
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe 'with no index option' do
|
78
|
+
|
79
|
+
before(:each) do
|
80
|
+
reset_fixture
|
81
|
+
|
82
|
+
if description == "table doesn't exist yet"
|
83
|
+
AlsoMigrate.configuration << {
|
84
|
+
:source => :articles,
|
85
|
+
:destination => :article_archives
|
86
|
+
}
|
87
|
+
end
|
88
|
+
|
89
|
+
$db.migrate(0)
|
90
|
+
$db.migrate(1)
|
91
|
+
|
92
|
+
if description == "table already exists"
|
93
|
+
AlsoMigrate.configuration << {
|
94
|
+
:source => :articles,
|
95
|
+
:destination => :article_archives
|
96
|
+
}
|
97
|
+
$db.migrate(1)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should add all indexes" do
|
102
|
+
indexed_columns('articles').should == [ 'id', 'read' ]
|
103
|
+
indexed_columns('article_archives').should == [ 'id', 'read' ]
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
describe "with other table" do
|
108
|
+
|
109
|
+
before(:each) do
|
110
|
+
reset_fixture
|
111
|
+
|
112
|
+
if description == "table doesn't exist yet"
|
113
|
+
AlsoMigrate.configuration << {
|
114
|
+
:source => :articles,
|
115
|
+
:destination => :article_archives
|
116
|
+
}
|
117
|
+
AlsoMigrate.configuration << {
|
118
|
+
:source => :comments,
|
119
|
+
:destination => :comment_archives
|
120
|
+
}
|
121
|
+
end
|
122
|
+
|
123
|
+
$db.migrate(0)
|
124
|
+
$db.migrate(1)
|
125
|
+
$db.migrate(2)
|
126
|
+
$db.migrate(3)
|
127
|
+
|
128
|
+
if description == "table already exists"
|
129
|
+
AlsoMigrate.configuration << {
|
130
|
+
:source => :articles,
|
131
|
+
:destination => :article_archives
|
132
|
+
}
|
133
|
+
AlsoMigrate.configuration << {
|
134
|
+
:source => :comments,
|
135
|
+
:destination => :comment_archives
|
136
|
+
}
|
137
|
+
$db.migrate(3)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
it "should not affect other table" do
|
142
|
+
columns('articles').should == columns('article_archives')
|
143
|
+
columns('comments').should == columns('comment_archives')
|
144
|
+
columns('articles').should == ["id", "title", "body", "read", "restored_at", "permalink"]
|
145
|
+
columns('comments').should == ["id", "header", "description"]
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
if description == "table already exists"
|
150
|
+
describe 'with add and subtract option' do
|
151
|
+
|
152
|
+
before(:each) do
|
153
|
+
reset_fixture
|
154
|
+
|
155
|
+
AlsoMigrate.configuration << {
|
156
|
+
:source => :articles,
|
157
|
+
:destination => :article_archives
|
158
|
+
}
|
159
|
+
|
160
|
+
$db.migrate(0)
|
161
|
+
$db.migrate(1)
|
162
|
+
|
163
|
+
AlsoMigrate.configuration = []
|
164
|
+
AlsoMigrate.configuration << {
|
165
|
+
:source => :articles,
|
166
|
+
:destination => :article_archives,
|
167
|
+
:add => [
|
168
|
+
[ 'deleted_at', :datetime ]
|
169
|
+
],
|
170
|
+
:subtract => 'restored_at'
|
171
|
+
}
|
172
|
+
end
|
173
|
+
|
174
|
+
it "should add and remove fields" do
|
175
|
+
columns('article_archives').should == %w(id title body read restored_at)
|
176
|
+
$db.migrate(1)
|
177
|
+
columns('article_archives').should == %w(id title body read deleted_at)
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class CreateArticles < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :articles do |t|
|
4
|
+
t.string :title
|
5
|
+
t.string :body
|
6
|
+
t.boolean :read
|
7
|
+
t.datetime :restored_at
|
8
|
+
end
|
9
|
+
add_index :articles, :read
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.down
|
13
|
+
drop_table :articles
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
name: name
|
2
|
+
version: 0.1.0
|
3
|
+
authors:
|
4
|
+
- Author
|
5
|
+
email: email@email.com
|
6
|
+
homepage: http://github.com/author/name
|
7
|
+
summary: Summary
|
8
|
+
description: Description
|
9
|
+
dependencies:
|
10
|
+
- rake
|
11
|
+
- default:
|
12
|
+
- mysql
|
13
|
+
- rspec2:
|
14
|
+
- mysql2
|
15
|
+
development_dependencies: null
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'pp'
|
2
|
+
|
3
|
+
$root = File.expand_path('../../', __FILE__)
|
4
|
+
require "#{$root}/lib/also_migrate/gems"
|
5
|
+
|
6
|
+
AlsoMigrate::Gems.activate :active_wrapper, :rspec
|
7
|
+
|
8
|
+
require 'active_wrapper'
|
9
|
+
|
10
|
+
require "#{$root}/lib/also_migrate"
|
11
|
+
require 'pp'
|
12
|
+
|
13
|
+
Spec::Runner.configure do |config|
|
14
|
+
end
|
15
|
+
|
16
|
+
$db, $log, $mail = ActiveWrapper.setup(
|
17
|
+
:base => File.dirname(__FILE__),
|
18
|
+
:env => 'test'
|
19
|
+
)
|
20
|
+
$db.establish_connection
|
21
|
+
|
22
|
+
def columns(table)
|
23
|
+
connection.columns(table).collect(&:name)
|
24
|
+
end
|
25
|
+
|
26
|
+
def connection
|
27
|
+
ActiveRecord::Base.connection
|
28
|
+
end
|
29
|
+
|
30
|
+
# For use with rspec textmate bundle
|
31
|
+
def debug(object)
|
32
|
+
puts "<pre>"
|
33
|
+
puts object.pretty_inspect.gsub('<', '<').gsub('>', '>')
|
34
|
+
puts "</pre>"
|
35
|
+
end
|
36
|
+
|
37
|
+
def indexed_columns(table_name)
|
38
|
+
# MySQL
|
39
|
+
if connection.class.to_s.include?('Mysql')
|
40
|
+
index_query = "SHOW INDEX FROM #{table_name}"
|
41
|
+
connection.select_all(index_query).collect do |r|
|
42
|
+
r["Column_name"]
|
43
|
+
end
|
44
|
+
# PostgreSQL
|
45
|
+
# http://stackoverflow.com/questions/2204058/show-which-columns-an-index-is-on-in-postgresql/2213199
|
46
|
+
elsif connection.class.to_s.include?('PostgreSQL')
|
47
|
+
index_query = <<-SQL
|
48
|
+
select
|
49
|
+
t.relname as table_name,
|
50
|
+
i.relname as index_name,
|
51
|
+
a.attname as column_name
|
52
|
+
from
|
53
|
+
pg_class t,
|
54
|
+
pg_class i,
|
55
|
+
pg_index ix,
|
56
|
+
pg_attribute a
|
57
|
+
where
|
58
|
+
t.oid = ix.indrelid
|
59
|
+
and i.oid = ix.indexrelid
|
60
|
+
and a.attrelid = t.oid
|
61
|
+
and a.attnum = ANY(ix.indkey)
|
62
|
+
and t.relkind = 'r'
|
63
|
+
and t.relname = '#{table_name}'
|
64
|
+
order by
|
65
|
+
t.relname,
|
66
|
+
i.relname
|
67
|
+
SQL
|
68
|
+
connection.select_all(index_query).collect do |r|
|
69
|
+
r["column_name"]
|
70
|
+
end
|
71
|
+
else
|
72
|
+
raise 'AlsoMigrate does not support this database adapter'
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def migrate_with_state(version)
|
77
|
+
@old_article_columns = columns("articles")
|
78
|
+
@old_archive_columns = columns("article_archives")
|
79
|
+
$db.migrate(version)
|
80
|
+
@new_article_columns = columns("articles")
|
81
|
+
@new_archive_columns = columns("article_archives")
|
82
|
+
end
|
83
|
+
|
84
|
+
def reset_fixture
|
85
|
+
AlsoMigrate.configuration = []
|
86
|
+
|
87
|
+
if connection.table_exists?('article_archives')
|
88
|
+
connection.execute('DROP TABLE article_archives')
|
89
|
+
end
|
90
|
+
|
91
|
+
if connection.table_exists?('comment_archives')
|
92
|
+
connection.execute('DROP TABLE comment_archives')
|
93
|
+
end
|
94
|
+
end
|
metadata
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: also_migrate_nj
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.6
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Winton Welsh
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-07-25 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rspec
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
description: Migrate multiple tables with similar schema at once.
|
47
|
+
email: james@njtechnologies.co.uk
|
48
|
+
executables: []
|
49
|
+
extensions: []
|
50
|
+
extra_rdoc_files: []
|
51
|
+
files:
|
52
|
+
- .gitignore
|
53
|
+
- LICENSE
|
54
|
+
- README.md
|
55
|
+
- Rakefile
|
56
|
+
- also_migrate.gemspec
|
57
|
+
- config/gemsets.yml
|
58
|
+
- config/gemspec.yml
|
59
|
+
- init.rb
|
60
|
+
- lib/also_migrate.rb
|
61
|
+
- lib/also_migrate/gems.rb
|
62
|
+
- lib/also_migrate/migration.rb
|
63
|
+
- lib/also_migrate/migrator.rb
|
64
|
+
- rails/init.rb
|
65
|
+
- spec/Rakefile
|
66
|
+
- spec/also_migrate/gems_spec.rb
|
67
|
+
- spec/also_migrate_spec.rb
|
68
|
+
- spec/config/database.yml.example
|
69
|
+
- spec/db/migrate/001_create_articles.rb
|
70
|
+
- spec/db/migrate/002_add_permalink.rb
|
71
|
+
- spec/db/migrate/003_create_comments.rb
|
72
|
+
- spec/fixtures/gemsets.yml
|
73
|
+
- spec/fixtures/gemspec.yml
|
74
|
+
- spec/spec_helper.rb
|
75
|
+
homepage: https://github.com/jamesharker/also_migrate
|
76
|
+
licenses: []
|
77
|
+
post_install_message:
|
78
|
+
rdoc_options: []
|
79
|
+
require_paths:
|
80
|
+
- lib
|
81
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
82
|
+
none: false
|
83
|
+
requirements:
|
84
|
+
- - ! '>='
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: '0'
|
87
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
88
|
+
none: false
|
89
|
+
requirements:
|
90
|
+
- - ! '>='
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '0'
|
93
|
+
requirements: []
|
94
|
+
rubyforge_project:
|
95
|
+
rubygems_version: 1.8.24
|
96
|
+
signing_key:
|
97
|
+
specification_version: 3
|
98
|
+
summary: Migrate multiple tables with similar schema at once.
|
99
|
+
test_files:
|
100
|
+
- spec/Rakefile
|
101
|
+
- spec/also_migrate/gems_spec.rb
|
102
|
+
- spec/also_migrate_spec.rb
|
103
|
+
- spec/config/database.yml.example
|
104
|
+
- spec/db/migrate/001_create_articles.rb
|
105
|
+
- spec/db/migrate/002_add_permalink.rb
|
106
|
+
- spec/db/migrate/003_create_comments.rb
|
107
|
+
- spec/fixtures/gemsets.yml
|
108
|
+
- spec/fixtures/gemspec.yml
|
109
|
+
- spec/spec_helper.rb
|
110
|
+
has_rdoc:
|