moargration 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/Gemfile +7 -0
- data/README.md +47 -0
- data/Rakefile +8 -0
- data/lib/moargration.rb +35 -0
- data/moargration.gemspec +18 -0
- data/test/moargration_test.rb +33 -0
- data/test/test_helper.rb +22 -0
- metadata +55 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
# Moargration
|
2
|
+
|
3
|
+
Helping you migrate, MOAR.
|
4
|
+
|
5
|
+
This is Ruby gem that takes environment variables to assist the execution of database migrations that would otherwise require two-step deploys.
|
6
|
+
|
7
|
+
For more information refer to [Rails migrations with no downtime](http://pedro.herokuapp.com/past/2011/7/13/rails_migrations_with_no_downtime/).
|
8
|
+
|
9
|
+
|
10
|
+
## Setup
|
11
|
+
|
12
|
+
Add to a initializer in your app, eg `config/initializers/moargration.rb` for Rails apps:
|
13
|
+
|
14
|
+
Moargration.init
|
15
|
+
|
16
|
+
Worry not, Moargration won't impact your boot time until you actually need it.
|
17
|
+
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
So it's time to drop some columns.
|
22
|
+
|
23
|
+
Knowing that this can bring your app down, and that you normally need to do two deploys to safely dro pcolumns, you can use Moargration to setup the first step for you.
|
24
|
+
|
25
|
+
Just set an `ENV` var like:
|
26
|
+
|
27
|
+
MOARGRATION_IGNORE="users:notes,bio companies:another_stupid_column"
|
28
|
+
|
29
|
+
And bounce your servers. Moargration will make sure that once the servers are running again your ORM will be ignoring these columns so that you can safely run the migration to drop them.
|
30
|
+
|
31
|
+
After the migration finishes you can unset that variable and enjoy your new database schema.
|
32
|
+
|
33
|
+
|
34
|
+
## The example above is not completely obvious, I need a [BNF grammar](http://en.wikipedia.org/wiki/Backus%E2%80%93Naur_Form)
|
35
|
+
|
36
|
+
Sure thing, bro:
|
37
|
+
|
38
|
+
<ignore> ::= <definition> { " " <definition> }
|
39
|
+
<definition> ::= <table> ":" <fields>
|
40
|
+
<fields> ::= <field> { "," <field> }
|
41
|
+
|
42
|
+
|
43
|
+
## Notes
|
44
|
+
|
45
|
+
Created by Pedro Belo.
|
46
|
+
Licensed as MIT.
|
47
|
+
Use at your own risk.
|
data/Rakefile
ADDED
data/lib/moargration.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
module Moargration
|
2
|
+
class Exception < StandardError; end
|
3
|
+
|
4
|
+
extend self
|
5
|
+
|
6
|
+
def setup
|
7
|
+
return unless ignore = ENV["MOARGRATION_IGNORE"]
|
8
|
+
spec = parse(ignore)
|
9
|
+
hack_active_record(spec)
|
10
|
+
end
|
11
|
+
|
12
|
+
def columns_to_ignore
|
13
|
+
@@columns_to_ignore
|
14
|
+
end
|
15
|
+
|
16
|
+
def parse(text)
|
17
|
+
text.strip.split(" ").inject({}) do |parsed, definition|
|
18
|
+
table, fields = definition.split(":", 2)
|
19
|
+
parsed[table] = fields.split(",") if fields
|
20
|
+
parsed
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def hack_active_record(spec)
|
25
|
+
@@columns_to_ignore = spec
|
26
|
+
|
27
|
+
ActiveRecord::Base.class_eval do
|
28
|
+
def self.columns
|
29
|
+
super.reject do |column|
|
30
|
+
(Moargration.columns_to_ignore[table_name] || []).include?(column.name)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/moargration.gemspec
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
|
5
|
+
Gem::Specification.new do |gem|
|
6
|
+
gem.name = "moargration"
|
7
|
+
gem.version = "0.0.1"
|
8
|
+
gem.authors = ["Pedro Belo"]
|
9
|
+
gem.email = ["pedro@heroku.com"]
|
10
|
+
gem.description = %q{Helping you migrate, MOAR.}
|
11
|
+
gem.summary = %q{To assist app developers with tricky database migrations}
|
12
|
+
gem.homepage = "https://github.com/pedro/moargration"
|
13
|
+
|
14
|
+
gem.files = `git ls-files`.split($/)
|
15
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
16
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
17
|
+
gem.require_paths = ["lib"]
|
18
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require "./test/test_helper"
|
2
|
+
|
3
|
+
describe Moargration do
|
4
|
+
describe "parse_ignore_definition" do
|
5
|
+
it "reads a table with a simple field" do
|
6
|
+
Moargration.parse("table:field").must_equal("table" => %w( field ))
|
7
|
+
end
|
8
|
+
|
9
|
+
it "reads a table with multiple fields" do
|
10
|
+
Moargration.parse("table:f1,f2").must_equal("table" => %w( f1 f2 ))
|
11
|
+
end
|
12
|
+
|
13
|
+
it "reads multiple tables" do
|
14
|
+
Moargration.parse("t1:f1,f2 t2:f1").must_equal("t1" => %w( f1 f2 ), "t2" => %w( f1 ))
|
15
|
+
end
|
16
|
+
|
17
|
+
it "ignores tables without fields" do
|
18
|
+
Moargration.parse("t1:f1 t2 t3:f1").must_equal("t1" => %w( f1 ), "t3" => %w( f1 ))
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "hack_active_record" do
|
23
|
+
it "hacks the model to ignore the specified columns" do
|
24
|
+
Moargration.hack_active_record("samples" => %w( f1 ))
|
25
|
+
Sample.columns.map(&:name).wont_include("f1")
|
26
|
+
end
|
27
|
+
|
28
|
+
it "doesn't affect other models" do
|
29
|
+
Moargration.hack_active_record("samples" => %w( f1 ))
|
30
|
+
User.columns.map(&:name).must_include("f1")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require "minitest/spec"
|
2
|
+
require "minitest/autorun"
|
3
|
+
require "active_record"
|
4
|
+
require "./lib/moargration"
|
5
|
+
require "uri"
|
6
|
+
|
7
|
+
ActiveRecord::Base.establish_connection({
|
8
|
+
:adapter => "postgresql",
|
9
|
+
:host => "localhost",
|
10
|
+
:database => "moargration_test",
|
11
|
+
:min_messages => "warning"
|
12
|
+
})
|
13
|
+
ActiveRecord::Base.connection.execute "DROP TABLE IF EXISTS samples"
|
14
|
+
ActiveRecord::Base.connection.execute "CREATE TABLE samples ( id integer UNIQUE, f1 text, f2 text, f3 text)"
|
15
|
+
ActiveRecord::Base.connection.execute "DROP TABLE IF EXISTS users"
|
16
|
+
ActiveRecord::Base.connection.execute "CREATE TABLE users ( id integer UNIQUE, f1 text, f2 text, f3 text)"
|
17
|
+
|
18
|
+
class Sample < ActiveRecord::Base
|
19
|
+
end
|
20
|
+
|
21
|
+
class User < ActiveRecord::Base
|
22
|
+
end
|
metadata
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: moargration
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Pedro Belo
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-11-02 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: Helping you migrate, MOAR.
|
15
|
+
email:
|
16
|
+
- pedro@heroku.com
|
17
|
+
executables: []
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- .gitignore
|
22
|
+
- Gemfile
|
23
|
+
- README.md
|
24
|
+
- Rakefile
|
25
|
+
- lib/moargration.rb
|
26
|
+
- moargration.gemspec
|
27
|
+
- test/moargration_test.rb
|
28
|
+
- test/test_helper.rb
|
29
|
+
homepage: https://github.com/pedro/moargration
|
30
|
+
licenses: []
|
31
|
+
post_install_message:
|
32
|
+
rdoc_options: []
|
33
|
+
require_paths:
|
34
|
+
- lib
|
35
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
36
|
+
none: false
|
37
|
+
requirements:
|
38
|
+
- - ! '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ! '>='
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
requirements: []
|
48
|
+
rubyforge_project:
|
49
|
+
rubygems_version: 1.8.22
|
50
|
+
signing_key:
|
51
|
+
specification_version: 3
|
52
|
+
summary: To assist app developers with tricky database migrations
|
53
|
+
test_files:
|
54
|
+
- test/moargration_test.rb
|
55
|
+
- test/test_helper.rb
|