auto_migrations_rails4 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ NmM4MDg0ODdlNmZlMmQ1ZWFkZTJiZjY3ZWMwZDBkMDNkZTIzNjYwNg==
5
+ data.tar.gz: !binary |-
6
+ N2NhM2YyNjE2YmYyZTA2NDVmYTg0MTcwZTkxMGUzY2VkMWU4NzIxNA==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ ZGI0ZGRjMmI2ZjZmMWE4YzMzNzkxNWEzOTRmZjQ0MjI3MGU0ZjAzZjVkMTRi
10
+ ZDE5NzA3MzU0NGY0YTNlYTRhYzQyNzdjNDhjYTY4MDhmZDg5YTllOGQzN2Q2
11
+ MjI2ZTRhZTkwYjI3ZWEyZDY2M2VjMDcxZDEyZmNjZDAzNzZlNjg=
12
+ data.tar.gz: !binary |-
13
+ YjRmMjQ0YWUzMDcxZTI0MWQ0MDRiNThmNDRkOGM2NDU2MzQwZDJkNmIyMTMx
14
+ YjFiYjQ3ZDBkNWIyNWUyZDY2YTUxYzU4NWY4YTlkMTIyM2E1MGJmZjk5MWIz
15
+ MjQ0MTVjNGNlZWY2N2I1NmMwMjQxNGRkMGI1ZWE3NzA4M2M3Njg=
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2007 PJ Hyett
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,46 @@
1
+ == AutoMigrations
2
+
3
+ Forget migrations, auto-migrate!
4
+
5
+
6
+ == Usage
7
+
8
+ Write out your schema (or use an existing one)
9
+
10
+ $ cat db/schema.rb
11
+
12
+ ActiveRecord::Schema.define do
13
+
14
+ create_table :posts do |t|
15
+ t.string :title
16
+ t.text :body
17
+ t.timestamps
18
+ end
19
+
20
+ end
21
+
22
+ $ rake db:auto:migrate
23
+
24
+ Created posts table
25
+
26
+ ...a few days later
27
+
28
+ $ cat db/schema.rb
29
+
30
+ ActiveRecord::Schema.define do
31
+
32
+ create_table :posts do |t|
33
+ t.string :title
34
+ t.text :content
35
+ t.timestamps
36
+ end
37
+
38
+ end
39
+
40
+ $ rake db:auto:migrate
41
+ -- add_column("posts", :content, :text)
42
+ -> 0.0307s
43
+ -- remove_column("posts", "body")
44
+ -> 0.0311s
45
+
46
+ * PJ Hyett [ pjhyett@gmail.com ]
@@ -0,0 +1,39 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rdoc/task'
4
+
5
+ begin
6
+ require 'jeweler'
7
+ Jeweler::Tasks.new do |gemspec|
8
+ gemspec.name = "auto_migrations_rails4"
9
+ gemspec.summary = "Auto database migration for Rails 4."
10
+ gemspec.description = "Auto database migration for Rails 4."
11
+ gemspec.email = "zhangyuanyi@gmail.com"
12
+ gemspec.homepage = "http://github.com/yzhang/auto_migrations_rails4"
13
+ gemspec.authors = ["yzhang (originally by PJ Hyett)"]
14
+ end
15
+ Jeweler::GemcutterTasks.new
16
+ rescue LoadError
17
+ puts "Jeweler not available. Install it with: sudo gem install jeweler -s http://gemcutter.org"
18
+ end
19
+
20
+ desc 'Default: run unit tests.'
21
+ task :default => :test
22
+
23
+ desc 'Test the auto_migrations plugin.'
24
+ Rake::TestTask.new(:test) do |t|
25
+ t.libs << 'lib'
26
+ t.pattern = 'test/**/*_test.rb'
27
+ t.verbose = true
28
+ end
29
+
30
+ desc 'Generate documentation for the auto_migrations plugin.'
31
+ Rake::RDocTask.new(:rdoc) do |rdoc|
32
+ files = ['README', 'LICENSE', 'lib/**/*.rb']
33
+ rdoc.rdoc_files.add(files)
34
+ rdoc.main = "README" # page to start on
35
+ rdoc.title = "auto_migrations"
36
+ rdoc.template = File.exists?(t="/Users/chris/ruby/projects/err/rock/template.rb") ? t : "/var/www/rock/template.rb"
37
+ rdoc.rdoc_dir = 'doc' # rdoc output folder
38
+ rdoc.options << '--inline-source'
39
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.0
@@ -0,0 +1,36 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "auto_migrations_rails4"
8
+ s.version = "1.0.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["yzhang (originally by PJ Hyett)"]
12
+ s.date = "2013-08-10"
13
+ s.description = "Auto database migration for Rails 4."
14
+ s.email = "zhangyuanyi@gmail.com"
15
+ s.extra_rdoc_files = [
16
+ "LICENSE.txt",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ "LICENSE.txt",
22
+ "README.rdoc",
23
+ "Rakefile",
24
+ "VERSION",
25
+ "auto_migrations_rails4.gemspec",
26
+ "init.rb",
27
+ "lib/auto_migrations_rails4.rb",
28
+ "lib/tasks/auto_migrations_rails4_tasks.rake",
29
+ "test/auto_migrations_rails4_test.rb"
30
+ ]
31
+ s.homepage = "http://github.com/yzhang/auto_migrations_rails4"
32
+ s.require_paths = ["lib"]
33
+ s.rubygems_version = "2.0.6"
34
+ s.summary = "Auto database migration for Rails 4."
35
+ end
36
+
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'auto_migrations'
@@ -0,0 +1,186 @@
1
+ # load rake
2
+ Dir[File.join(File.dirname(__FILE__),'tasks/**/*.rake')].each { |f| load f } if defined?(Rake)
3
+
4
+ module AutoMigrations
5
+ def self.run
6
+ # Turn off schema_info code for auto-migration
7
+ class << ActiveRecord::Schema
8
+ alias :old_define :define
9
+ attr_accessor :version
10
+ def define(info={}, &block) @version = Time.now.utc.strftime("%Y%m%d%H%M%S"); instance_eval(&block) end
11
+ end
12
+
13
+ load(File.join(Rails.root, 'db', 'schema.rb'))
14
+ ActiveRecord::Migration.drop_unused_tables
15
+ ActiveRecord::Migration.drop_unused_indexes
16
+ ActiveRecord::Migration.update_schema_version(ActiveRecord::Schema.version) if ActiveRecord::Schema.version
17
+
18
+ class << ActiveRecord::Schema
19
+ alias :define :old_define
20
+ end
21
+ end
22
+
23
+ def self.schema_to_migration(with_reset = false)
24
+ schema_in = File.read(File.join(Rails.root, "db", "schema.rb"))
25
+ schema_in.gsub!(/#(.)+\n/, '')
26
+ schema_in.sub!(/ActiveRecord::Schema.define(.+)do[ ]?\n/, '')
27
+ schema_in.gsub!(/^/, ' ')
28
+ schema = "class InitialSchema < ActiveRecord::Migration\n def self.up\n"
29
+ schema += " # We're resetting the migrations database...\n" +
30
+ " drop_table :schema_migrations\n" +
31
+ " initialize_schema_migrations_table\n\n" if with_reset
32
+ schema += schema_in
33
+ schema << "\n def self.down\n"
34
+ schema << (ActiveRecord::Base.connection.tables - %w(schema_info schema_migrations)).map do |table|
35
+ " drop_table :#{table}\n"
36
+ end.join
37
+ schema << " end\nend\n"
38
+ migration_file = File.join(Rails.root, "db", "migrate", "001_initial_schema.rb")
39
+ File.open(migration_file, "w") { |f| f << schema }
40
+ puts "Migration created at db/migrate/001_initial_schema.rb"
41
+ end
42
+
43
+ def self.included(base)
44
+ base.extend ClassMethods
45
+ class << base
46
+ cattr_accessor :tables_in_schema, :indexes_in_schema
47
+ self.tables_in_schema, self.indexes_in_schema = [], []
48
+ alias_method_chain :method_missing, :auto_migration
49
+ end
50
+ end
51
+
52
+ module ClassMethods
53
+
54
+ def method_missing_with_auto_migration(method, *args, &block)
55
+ case method
56
+ when :create_table
57
+ auto_create_table(method, *args, &block)
58
+ when :add_index
59
+ auto_add_index(method, *args, &block)
60
+ else
61
+ method_missing_without_auto_migration(method, *args, &block)
62
+ end
63
+ end
64
+
65
+ def auto_create_table(method, *args, &block)
66
+ table_name = args.shift.to_s
67
+ options = args.pop || {}
68
+
69
+ (self.tables_in_schema ||= []) << table_name
70
+
71
+ # Table doesn't exist, create it
72
+ unless ActiveRecord::Base.connection.tables.include?(table_name)
73
+ return method_missing_without_auto_migration(method, *[table_name, options], &block)
74
+ end
75
+
76
+ # Grab database columns
77
+ fields_in_db = ActiveRecord::Base.connection.columns(table_name).inject({}) do |hash, column|
78
+ hash[column.name] = column
79
+ hash
80
+ end
81
+
82
+ # Grab schema columns (lifted from active_record/connection_adapters/abstract/schema_statements.rb)
83
+ table_definition = create_table_definition table_name, options[:temporary], options[:options]
84
+ primary_key = options[:primary_key] || "id"
85
+ table_definition.primary_key(primary_key) unless options[:id] == false
86
+ yield table_definition
87
+ fields_in_schema = table_definition.columns.inject({}) do |hash, column|
88
+ hash[column.name.to_s] = column
89
+ hash
90
+ end
91
+
92
+ # Add fields to db new to schema
93
+ (fields_in_schema.keys - fields_in_db.keys).each do |field|
94
+ column = fields_in_schema[field]
95
+ options = {:limit => column.limit, :precision => column.precision, :scale => column.scale}
96
+ options[:default] = column.default if !column.default.nil?
97
+ options[:null] = column.null if !column.null.nil?
98
+ add_column table_name, column.name, column.type.to_sym, options
99
+ end
100
+
101
+ # Remove fields from db no longer in schema
102
+ (fields_in_db.keys - fields_in_schema.keys & fields_in_db.keys).each do |field|
103
+ column = fields_in_db[field]
104
+ remove_column table_name, column.name
105
+ end
106
+
107
+ (fields_in_schema.keys & fields_in_db.keys).each do |field|
108
+ if field != primary_key #ActiveRecord::Base.get_primary_key(table_name)
109
+ changed = false # flag
110
+ new_type = fields_in_schema[field].type.to_sym
111
+ new_attr = {}
112
+
113
+ # First, check if the field type changed
114
+ if fields_in_schema[field].type.to_sym != fields_in_db[field].type.to_sym
115
+ changed = true
116
+ end
117
+
118
+ # Special catch for precision/scale, since *both* must be specified together
119
+ # Always include them in the attr struct, but they'll only get applied if changed = true
120
+ new_attr[:precision] = fields_in_schema[field][:precision]
121
+ new_attr[:scale] = fields_in_schema[field][:scale]
122
+
123
+ # Next, iterate through our extended attributes, looking for any differences
124
+ # This catches stuff like :null, :precision, etc
125
+ fields_in_schema[field].each_pair do |att,value|
126
+ next if att == :type or att == :base or att == :name # special cases
127
+ if !value.nil? && value != fields_in_db[field].send(att)
128
+ new_attr[att] = value
129
+ changed = true
130
+ end
131
+ end
132
+
133
+ # Change the column if applicable
134
+ change_column table_name, field, new_type, new_attr if changed
135
+ end
136
+ end
137
+ end
138
+
139
+ def auto_add_index(method, *args, &block)
140
+ table_name = args.shift.to_s
141
+ fields = Array(args.shift).map(&:to_s)
142
+ options = args.shift
143
+
144
+ index_name = options[:name] if options
145
+ index_name ||= ActiveRecord::Base.connection.index_name(table_name, :column => fields)
146
+
147
+ (self.indexes_in_schema ||= []) << index_name
148
+
149
+ unless ActiveRecord::Base.connection.indexes(table_name).detect { |i| i.name == index_name }
150
+ method_missing_without_auto_migration(method, *[table_name, fields, options], &block)
151
+ end
152
+ end
153
+
154
+ def drop_unused_tables
155
+ (ActiveRecord::Base.connection.tables - tables_in_schema - %w(schema_info schema_migrations)).each do |table|
156
+ drop_table table
157
+ end
158
+ end
159
+
160
+ def drop_unused_indexes
161
+ tables_in_schema.each do |table_name|
162
+ indexes_in_db = ActiveRecord::Base.connection.indexes(table_name).map(&:name)
163
+ (indexes_in_db - indexes_in_schema & indexes_in_db).each do |index_name|
164
+ remove_index table_name, :name => index_name
165
+ end
166
+ end
167
+ end
168
+
169
+ def update_schema_version(version)
170
+ if ActiveRecord::Base.connection.tables.include?("schema_migrations")
171
+ ActiveRecord::Base.connection.update("INSERT INTO schema_migrations VALUES ('#{version}')")
172
+ end
173
+ schema_file = File.join(Rails.root, "db", "schema.rb")
174
+ schema = File.read(schema_file)
175
+ schema.sub!(/:version => \d+/, ":version => #{version}")
176
+ File.open(schema_file, "w") { |f| f << schema }
177
+ end
178
+
179
+ private
180
+ def create_table_definition(name, temporary, options)
181
+ ActiveRecord::ConnectionAdapters::TableDefinition.new({}, name, temporary, options)
182
+ end
183
+ end
184
+ end
185
+
186
+ ActiveRecord::Migration.send :include, AutoMigrations
@@ -0,0 +1,20 @@
1
+ namespace :db do
2
+ namespace :auto do
3
+ desc "Use schema.rb to auto-migrate"
4
+ task :migrate => :environment do
5
+ AutoMigrations.run
6
+ end
7
+ end
8
+
9
+ namespace :schema do
10
+ desc "Create migration from schema.rb"
11
+ task :to_migration => :environment do
12
+ AutoMigrations.schema_to_migration
13
+ end
14
+
15
+ desc "Create migration from schema.rb and reset migrations log"
16
+ task :to_migration_with_reset => :environment do
17
+ AutoMigrations.schema_to_migration(true)
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,8 @@
1
+ require 'test/unit'
2
+
3
+ class AutoMigrationsTest < Test::Unit::TestCase
4
+ # Replace this with your real tests.
5
+ def test_this_plugin
6
+ flunk
7
+ end
8
+ end
metadata ADDED
@@ -0,0 +1,54 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: auto_migrations_rails4
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - yzhang (originally by PJ Hyett)
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-08-10 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Auto database migration for Rails 4.
14
+ email: zhangyuanyi@gmail.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files:
18
+ - LICENSE.txt
19
+ - README.rdoc
20
+ files:
21
+ - .document
22
+ - LICENSE.txt
23
+ - README.rdoc
24
+ - Rakefile
25
+ - VERSION
26
+ - auto_migrations_rails4.gemspec
27
+ - init.rb
28
+ - lib/auto_migrations_rails4.rb
29
+ - lib/tasks/auto_migrations_rails4_tasks.rake
30
+ - test/auto_migrations_rails4_test.rb
31
+ homepage: http://github.com/yzhang/auto_migrations_rails4
32
+ licenses: []
33
+ metadata: {}
34
+ post_install_message:
35
+ rdoc_options: []
36
+ require_paths:
37
+ - lib
38
+ required_ruby_version: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ! '>='
41
+ - !ruby/object:Gem::Version
42
+ version: '0'
43
+ required_rubygems_version: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ! '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ requirements: []
49
+ rubyforge_project:
50
+ rubygems_version: 2.0.6
51
+ signing_key:
52
+ specification_version: 4
53
+ summary: Auto database migration for Rails 4.
54
+ test_files: []