dm-migrations 0.9.2 → 0.9.3
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/History.txt +1 -0
- data/Manifest.txt +38 -0
- data/{README → README.txt} +1 -2
- data/Rakefile +22 -29
- data/db/migrations/1_create_people_table.rb +12 -0
- data/db/migrations/2_add_dob_to_people.rb +13 -0
- data/db/migrations/config.rb +4 -0
- data/examples/sample_migration.rb +61 -0
- data/examples/sample_migration_spec.rb +46 -0
- data/lib/dm-migrations/version.rb +5 -0
- data/lib/migration.rb +10 -12
- data/lib/sql.rb +3 -103
- data/lib/sql/postgresql.rb +10 -10
- data/lib/sql/sqlite3.rb +1 -8
- data/lib/sql/table_creator.rb +55 -0
- data/lib/sql/table_modifier.rb +53 -0
- data/spec/integration/migration_runner_spec.rb +58 -55
- data/spec/integration/migration_spec.rb +99 -99
- data/spec/integration/sql_spec.rb +118 -108
- data/spec/spec.opts +2 -1
- data/spec/spec_helper.rb +4 -11
- data/spec/unit/migration_spec.rb +447 -0
- data/spec/unit/sql/column_spec.rb +18 -0
- data/spec/unit/sql/postgresql_spec.rb +99 -0
- data/spec/unit/sql/sqlite3_extensions_spec.rb +109 -0
- data/spec/unit/sql/table_creator_spec.rb +93 -0
- data/spec/unit/sql/table_modifier_spec.rb +52 -0
- data/spec/unit/sql/table_spec.rb +31 -0
- data/spec/unit/sql_spec.rb +10 -0
- metadata +48 -17
data/History.txt
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
|
data/Manifest.txt
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
History.txt
|
2
|
+
LICENSE
|
3
|
+
Manifest.txt
|
4
|
+
README.txt
|
5
|
+
Rakefile
|
6
|
+
TODO
|
7
|
+
db/migrations/1_create_people_table.rb
|
8
|
+
db/migrations/2_add_dob_to_people.rb
|
9
|
+
db/migrations/config.rb
|
10
|
+
examples/sample_migration.rb
|
11
|
+
examples/sample_migration_spec.rb
|
12
|
+
lib/dm-migrations.rb
|
13
|
+
lib/dm-migrations/version.rb
|
14
|
+
lib/migration.rb
|
15
|
+
lib/migration_runner.rb
|
16
|
+
lib/spec/example/migration_example_group.rb
|
17
|
+
lib/spec/matchers/migration_matchers.rb
|
18
|
+
lib/sql.rb
|
19
|
+
lib/sql/column.rb
|
20
|
+
lib/sql/mysql.rb
|
21
|
+
lib/sql/postgresql.rb
|
22
|
+
lib/sql/sqlite3.rb
|
23
|
+
lib/sql/table.rb
|
24
|
+
lib/sql/table_creator.rb
|
25
|
+
lib/sql/table_modifier.rb
|
26
|
+
spec/integration/migration_runner_spec.rb
|
27
|
+
spec/integration/migration_spec.rb
|
28
|
+
spec/integration/sql_spec.rb
|
29
|
+
spec/spec.opts
|
30
|
+
spec/spec_helper.rb
|
31
|
+
spec/unit/migration_spec.rb
|
32
|
+
spec/unit/sql/column_spec.rb
|
33
|
+
spec/unit/sql/postgresql_spec.rb
|
34
|
+
spec/unit/sql/sqlite3_extensions_spec.rb
|
35
|
+
spec/unit/sql/table_creator_spec.rb
|
36
|
+
spec/unit/sql/table_modifier_spec.rb
|
37
|
+
spec/unit/sql/table_spec.rb
|
38
|
+
spec/unit/sql_spec.rb
|
data/{README → README.txt}
RENAMED
data/Rakefile
CHANGED
@@ -1,51 +1,44 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'spec'
|
3
|
-
require 'rake/clean'
|
4
|
-
require 'rake/gempackagetask'
|
5
3
|
require 'spec/rake/spectask'
|
6
4
|
require 'pathname'
|
7
5
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
end
|
6
|
+
ROOT = Pathname(__FILE__).dirname.expand_path
|
7
|
+
require ROOT + 'lib/dm-migrations/version'
|
8
|
+
|
9
|
+
AUTHOR = "Paul Sadauskas"
|
10
|
+
EMAIL = "psadauskas@gmail.com"
|
11
|
+
GEM_NAME = "dm-migrations"
|
12
|
+
GEM_VERSION = DataMapper::Migration::VERSION
|
13
|
+
GEM_DEPENDENCIES = [["dm-core", GEM_VERSION]]
|
14
|
+
GEM_CLEAN = ["log", "pkg"]
|
15
|
+
GEM_EXTRAS = { :has_rdoc => true, :extra_rdoc_files => %w[ README.txt LICENSE TODO ] }
|
16
|
+
|
17
|
+
PROJECT_NAME = "datamapper"
|
18
|
+
PROJECT_URL = "http://github.com/sam/dm-more/tree/master/dm-migrations"
|
19
|
+
PROJECT_DESCRIPTION = PROJECT_SUMMARY = "DataMapper plugin for writing and speccing migrations"
|
20
|
+
|
21
|
+
require ROOT.parent + 'tasks/hoe'
|
25
22
|
|
26
23
|
task :default => [ :spec ]
|
27
24
|
|
28
25
|
WIN32 = (RUBY_PLATFORM =~ /win32|mingw|cygwin/) rescue nil
|
29
26
|
SUDO = WIN32 ? '' : ('sudo' unless ENV['SUDOLESS'])
|
30
27
|
|
31
|
-
|
32
|
-
pkg.gem_spec = spec
|
33
|
-
end
|
34
|
-
|
35
|
-
desc "Install #{spec.name} #{spec.version} (default ruby)"
|
28
|
+
desc "Install #{GEM_NAME} #{GEM_VERSION} (default ruby)"
|
36
29
|
task :install => [ :package ] do
|
37
|
-
sh "#{SUDO} gem install --local pkg/#{
|
30
|
+
sh "#{SUDO} gem install --local pkg/#{GEM_NAME}-#{GEM_VERSION} --no-update-sources", :verbose => false
|
38
31
|
end
|
39
32
|
|
40
|
-
desc "Uninstall #{
|
33
|
+
desc "Uninstall #{GEM_NAME} #{GEM_VERSION} (default ruby)"
|
41
34
|
task :uninstall => [ :clobber ] do
|
42
|
-
sh "#{SUDO} gem uninstall #{
|
35
|
+
sh "#{SUDO} gem uninstall #{GEM_NAME} -v#{GEM_VERSION} -I -x", :verbose => false
|
43
36
|
end
|
44
37
|
|
45
38
|
namespace :jruby do
|
46
|
-
desc "Install #{
|
39
|
+
desc "Install #{GEM_NAME} #{GEM_VERSION} with JRuby"
|
47
40
|
task :install => [ :package ] do
|
48
|
-
sh %{#{SUDO} jruby -S gem install --local pkg/#{
|
41
|
+
sh %{#{SUDO} jruby -S gem install --local pkg/#{GEM_NAME}-#{GEM_VERSION} --no-update-sources}, :verbose => false
|
49
42
|
end
|
50
43
|
end
|
51
44
|
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../lib/migration_runner'
|
2
|
+
require 'fileutils'
|
3
|
+
FileUtils.touch(File.join(Dir.pwd, "migration_test.db"))
|
4
|
+
# DataMapper.setup(:default, "sqlite3://#{Dir.pwd}/migration_test.db")
|
5
|
+
DataMapper.setup(:default, "postgres://localhost/migration_test")
|
6
|
+
# DataMapper.setup(:default, "mysql://localhost/migration_test")
|
7
|
+
|
8
|
+
DataMapper::Logger.new(STDOUT, :debug)
|
9
|
+
DataMapper.logger.debug( "Starting Migration" )
|
10
|
+
|
11
|
+
migration 1, :create_people_table do
|
12
|
+
up do
|
13
|
+
create_table :people do
|
14
|
+
column :id, Integer, :serial => true
|
15
|
+
column :name, String, :size => 50
|
16
|
+
column :age, Integer
|
17
|
+
end
|
18
|
+
end
|
19
|
+
down do
|
20
|
+
drop_table :people
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
migration 2, :add_dob_to_people do
|
25
|
+
up do
|
26
|
+
modify_table :people do
|
27
|
+
add_column :dob, DateTime, :nullable? => true
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
down do
|
32
|
+
modify_table :people do
|
33
|
+
drop_column :dob
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# migrate_down!
|
39
|
+
# migrate_up!
|
40
|
+
#
|
41
|
+
# class Person
|
42
|
+
# include DataMapper::Resource
|
43
|
+
#
|
44
|
+
# property :id, Integer, :serial => true
|
45
|
+
# property :name, String, :size => 50
|
46
|
+
# property :age, Integer
|
47
|
+
# property :dob, DateTime, :default => Time.now
|
48
|
+
#
|
49
|
+
# end
|
50
|
+
#
|
51
|
+
# Person.create(:name => "Mark Bates", :age => 31)
|
52
|
+
# puts Person.first.inspect
|
53
|
+
# puts Person.all.inspect
|
54
|
+
|
55
|
+
if $0 == __FILE__
|
56
|
+
if $*.first == "down"
|
57
|
+
migrate_down!
|
58
|
+
else
|
59
|
+
migrate_up!
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/sample_migration'
|
2
|
+
require File.dirname(__FILE__) + '/../lib/spec/example/migration_example_group'
|
3
|
+
|
4
|
+
describe :create_people_table, :type => :migration do
|
5
|
+
|
6
|
+
before do
|
7
|
+
run_migration
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'should create a people table' do
|
11
|
+
repository(:default).should have_table(:people)
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'should have an id column as the primary key' do
|
15
|
+
table(:people).should have_column(:id)
|
16
|
+
table(:people).column(:id).type.should == 'integer'
|
17
|
+
#table(:people).column(:id).should be_primary_key
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'should have a name column as a string' do
|
21
|
+
table(:people).should have_column(:name)
|
22
|
+
table(:people).column(:name).type.should == 'character varying'
|
23
|
+
table(:people).column(:name).should permit_null
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'should have a nullable age column as a int' do
|
27
|
+
table(:people).should have_column(:age)
|
28
|
+
table(:people).column(:age).type.should == 'integer'
|
29
|
+
table(:people).column(:age).should permit_null
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
describe :add_dob_to_people, :type => :migration do
|
35
|
+
|
36
|
+
before do
|
37
|
+
run_migration
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should add a dob column as a timestamp' do
|
41
|
+
table(:people).should have_column(:dob)
|
42
|
+
table(:people).column(:dob).type.should == 'timestamp without time zone'
|
43
|
+
table(:people).column(:dob).should permit_null
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
data/lib/migration.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'rubygems'
|
2
|
-
gem 'dm-core', '=0.9.
|
2
|
+
gem 'dm-core', '=0.9.3'
|
3
3
|
require 'dm-core'
|
4
4
|
require 'benchmark'
|
5
5
|
require File.dirname(__FILE__) + '/sql'
|
@@ -51,30 +51,30 @@ module DataMapper
|
|
51
51
|
|
52
52
|
# perform the migration by running the code in the #up block
|
53
53
|
def perform_up
|
54
|
-
|
54
|
+
result = nil
|
55
55
|
if needs_up?
|
56
56
|
# DataMapper.database.adapter.transaction do
|
57
57
|
say_with_time "== Performing Up Migration ##{position}: #{name}", 0 do
|
58
|
-
|
58
|
+
result = @up_action.call
|
59
59
|
end
|
60
60
|
update_migration_info(:up)
|
61
61
|
# end
|
62
62
|
end
|
63
|
-
|
63
|
+
result
|
64
64
|
end
|
65
65
|
|
66
66
|
# un-do the migration by running the code in the #down block
|
67
67
|
def perform_down
|
68
|
-
|
68
|
+
result = nil
|
69
69
|
if needs_down?
|
70
70
|
# DataMapper.database.adapter.transaction do
|
71
71
|
say_with_time "== Performing Down Migration ##{position}: #{name}", 0 do
|
72
|
-
|
72
|
+
result = @down_action.call
|
73
73
|
end
|
74
74
|
update_migration_info(:down)
|
75
75
|
# end
|
76
76
|
end
|
77
|
-
|
77
|
+
result
|
78
78
|
end
|
79
79
|
|
80
80
|
# execute raw SQL
|
@@ -127,8 +127,6 @@ module DataMapper
|
|
127
127
|
puts text if @verbose
|
128
128
|
end
|
129
129
|
|
130
|
-
protected
|
131
|
-
|
132
130
|
# Inserts or removes a row into the `migration_info` table, so we can mark this migration as run, or un-done
|
133
131
|
def update_migration_info(direction)
|
134
132
|
save, @verbose = @verbose, false
|
@@ -144,7 +142,7 @@ module DataMapper
|
|
144
142
|
end
|
145
143
|
|
146
144
|
def create_migration_info_table_if_needed
|
147
|
-
save, @verbose = @verbose,
|
145
|
+
save, @verbose = @verbose, false
|
148
146
|
unless migration_info_table_exists?
|
149
147
|
execute("CREATE TABLE #{migration_info_table} (#{migration_name_column} VARCHAR(255) UNIQUE)")
|
150
148
|
end
|
@@ -168,13 +166,13 @@ module DataMapper
|
|
168
166
|
|
169
167
|
# True if the migration needs to be run
|
170
168
|
def needs_up?
|
171
|
-
|
169
|
+
return true unless migration_info_table_exists?
|
172
170
|
migration_record.empty?
|
173
171
|
end
|
174
172
|
|
175
173
|
# True if the migration has already been run
|
176
174
|
def needs_down?
|
177
|
-
|
175
|
+
return false unless migration_info_table_exists?
|
178
176
|
! migration_record.empty?
|
179
177
|
end
|
180
178
|
|
data/lib/sql.rb
CHANGED
@@ -1,110 +1,10 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/sql/table_creator'
|
2
|
+
require File.dirname(__FILE__) + '/sql/table_modifier'
|
3
|
+
|
1
4
|
require File.dirname(__FILE__) + '/sql/sqlite3'
|
2
5
|
require File.dirname(__FILE__) + '/sql/mysql'
|
3
6
|
require File.dirname(__FILE__) + '/sql/postgresql'
|
4
7
|
|
5
8
|
module SQL
|
6
9
|
|
7
|
-
class TableCreator
|
8
|
-
attr_accessor :table_name, :opts
|
9
|
-
|
10
|
-
def initialize(adapter, table_name, opts = {}, &block)
|
11
|
-
@adapter = adapter
|
12
|
-
@table_name = table_name.to_s
|
13
|
-
@opts = opts
|
14
|
-
|
15
|
-
@columns = []
|
16
|
-
|
17
|
-
self.instance_eval &block
|
18
|
-
end
|
19
|
-
|
20
|
-
def quoted_table_name
|
21
|
-
@adapter.send(:quote_table_name, table_name)
|
22
|
-
end
|
23
|
-
|
24
|
-
def column(name, type, opts = {})
|
25
|
-
@columns << Column.new(@adapter, name, type, opts)
|
26
|
-
end
|
27
|
-
|
28
|
-
def to_sql
|
29
|
-
"CREATE TABLE #{quoted_table_name} (#{@columns.map{ |c| c.to_sql }.join(', ')})"
|
30
|
-
end
|
31
|
-
|
32
|
-
class Column
|
33
|
-
attr_accessor :name, :type
|
34
|
-
|
35
|
-
def initialize(adapter, name, type, opts = {})
|
36
|
-
@adapter = adapter
|
37
|
-
@name = name.to_s
|
38
|
-
@opts = (opts ||= {})
|
39
|
-
@type = build_type(type)
|
40
|
-
end
|
41
|
-
|
42
|
-
def build_type(type_class)
|
43
|
-
schema = {:name => @name, :quote_column_name => quoted_name}.merge(@opts)
|
44
|
-
schema.merge!(@adapter.class.type_map[type_class])
|
45
|
-
@adapter.property_schema_statement(schema)
|
46
|
-
end
|
47
|
-
|
48
|
-
def to_sql
|
49
|
-
type
|
50
|
-
end
|
51
|
-
|
52
|
-
def quoted_name
|
53
|
-
@adapter.send(:quote_column_name, name)
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
end
|
58
|
-
|
59
|
-
class TableModifier
|
60
|
-
attr_accessor :table_name, :opts, :statements, :adapter
|
61
|
-
|
62
|
-
def initialize(adapter, table_name, opts = {}, &block)
|
63
|
-
@adapter = adapter
|
64
|
-
@table_name = table_name.to_s
|
65
|
-
@opts = (opts ||= {})
|
66
|
-
|
67
|
-
@statements = []
|
68
|
-
|
69
|
-
self.instance_eval &block
|
70
|
-
end
|
71
|
-
|
72
|
-
def add_column(name, type, opts = {})
|
73
|
-
column = SQL::TableCreator::Column.new(@adapter, name, type, opts)
|
74
|
-
@statements << "ALTER TABLE #{quoted_table_name} ADD COLUMN #{column.to_sql}"
|
75
|
-
end
|
76
|
-
|
77
|
-
def drop_column(name)
|
78
|
-
# raise NotImplemented for SQLite3. Can't ALTER TABLE, need to copy table.
|
79
|
-
# We'd have to inspect it, and we can't, since we aren't executing any queries yet.
|
80
|
-
# Just write the sql yourself.
|
81
|
-
if name.is_a?(Array)
|
82
|
-
name.each{ |n| drop_column(n) }
|
83
|
-
else
|
84
|
-
@statements << "ALTER TABLE #{quoted_table_name} DROP COLUMN #{quote_column_name(name)}"
|
85
|
-
end
|
86
|
-
end
|
87
|
-
alias drop_columns drop_column
|
88
|
-
|
89
|
-
def rename_column(name, new_name, opts = {})
|
90
|
-
# raise NotImplemented for SQLite3
|
91
|
-
@statements << "ALTER TABLE #{quoted_table_name} RENAME COLUMN #{quote_column_name(name)} TO #{quote_column_name(new_name)}"
|
92
|
-
end
|
93
|
-
|
94
|
-
def change_column(name, type, opts = {})
|
95
|
-
# raise NotImplemented for SQLite3
|
96
|
-
@statements << "ALTER TABLE #{quoted_table_name} ALTER COLUMN #{quote_column_name(name)} TYPE #{type}"
|
97
|
-
end
|
98
|
-
|
99
|
-
def quote_column_name(name)
|
100
|
-
@adapter.send(:quote_column_name, name.to_s)
|
101
|
-
end
|
102
|
-
|
103
|
-
def quoted_table_name
|
104
|
-
@adapter.send(:quote_table_name, table_name)
|
105
|
-
end
|
106
|
-
|
107
|
-
end
|
108
|
-
|
109
|
-
|
110
10
|
end
|