auto_migrations_rails4 1.0.0

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,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: []