sbf-dm-migrations 1.3.0.beta
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.
- checksums.yaml +7 -0
- data/.gitignore +38 -0
- data/.rspec +1 -0
- data/.rubocop.yml +468 -0
- data/.travis.yml +52 -0
- data/Gemfile +61 -0
- data/LICENSE +20 -0
- data/README.rdoc +39 -0
- data/Rakefile +4 -0
- 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/dm-migrations.gemspec +20 -0
- data/examples/Rakefile +149 -0
- data/examples/sample_migration.rb +58 -0
- data/examples/sample_migration_spec.rb +46 -0
- data/lib/dm-migrations/adapters/dm-do-adapter.rb +304 -0
- data/lib/dm-migrations/adapters/dm-mysql-adapter.rb +306 -0
- data/lib/dm-migrations/adapters/dm-oracle-adapter.rb +339 -0
- data/lib/dm-migrations/adapters/dm-postgres-adapter.rb +152 -0
- data/lib/dm-migrations/adapters/dm-sqlite-adapter.rb +88 -0
- data/lib/dm-migrations/adapters/dm-sqlserver-adapter.rb +184 -0
- data/lib/dm-migrations/adapters/dm-yaml-adapter.rb +21 -0
- data/lib/dm-migrations/auto_migration.rb +227 -0
- data/lib/dm-migrations/exceptions/duplicate_migration.rb +6 -0
- data/lib/dm-migrations/migration.rb +323 -0
- data/lib/dm-migrations/migration_runner.rb +76 -0
- data/lib/dm-migrations/sql/column.rb +5 -0
- data/lib/dm-migrations/sql/mysql.rb +84 -0
- data/lib/dm-migrations/sql/oracle.rb +9 -0
- data/lib/dm-migrations/sql/postgres.rb +89 -0
- data/lib/dm-migrations/sql/sqlite.rb +59 -0
- data/lib/dm-migrations/sql/sqlserver.rb +9 -0
- data/lib/dm-migrations/sql/table.rb +15 -0
- data/lib/dm-migrations/sql/table_creator.rb +105 -0
- data/lib/dm-migrations/sql/table_modifier.rb +57 -0
- data/lib/dm-migrations/sql.rb +7 -0
- data/lib/dm-migrations/version.rb +5 -0
- data/lib/dm-migrations.rb +3 -0
- data/lib/spec/example/migration_example_group.rb +69 -0
- data/lib/spec/matchers/migration_matchers.rb +96 -0
- data/spec/integration/auto_migration_spec.rb +590 -0
- data/spec/integration/auto_upgrade_spec.rb +41 -0
- data/spec/integration/migration_runner_spec.rb +84 -0
- data/spec/integration/migration_spec.rb +156 -0
- data/spec/integration/sql_spec.rb +290 -0
- data/spec/isolated/require_after_setup_spec.rb +24 -0
- data/spec/isolated/require_before_setup_spec.rb +24 -0
- data/spec/isolated/require_spec.rb +23 -0
- data/spec/spec_helper.rb +16 -0
- data/spec/unit/migration_spec.rb +501 -0
- data/spec/unit/sql/column_spec.rb +14 -0
- data/spec/unit/sql/postgres_spec.rb +90 -0
- data/spec/unit/sql/sqlite_extensions_spec.rb +103 -0
- data/spec/unit/sql/table_creator_spec.rb +91 -0
- data/spec/unit/sql/table_modifier_spec.rb +47 -0
- data/spec/unit/sql/table_spec.rb +26 -0
- data/spec/unit/sql_spec.rb +7 -0
- data/tasks/spec.rake +21 -0
- data/tasks/yard.rake +9 -0
- data/tasks/yardstick.rake +19 -0
- metadata +120 -0
@@ -0,0 +1,84 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
|
3
|
+
describe 'The migration runner' do
|
4
|
+
supported_by :postgres, :mysql, :sqlite, :oracle, :sqlserver do
|
5
|
+
before(:all) do
|
6
|
+
@adapter = DataMapper::Spec.adapter
|
7
|
+
@repository = DataMapper.repository(@adapter.name)
|
8
|
+
end
|
9
|
+
|
10
|
+
describe 'empty migration runner' do
|
11
|
+
it 'returns an empty array if no migrations have been defined' do
|
12
|
+
expect(migrations).to be_kind_of(Array)
|
13
|
+
expect(migrations.size).to eq 0
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe 'migration runner' do
|
18
|
+
# set up some 'global' setup and teardown tasks
|
19
|
+
before(:each) do
|
20
|
+
# FIXME: workaround because dm-migrations can only handle the :default repo
|
21
|
+
# DataMapper::Repository.adapters[:default] = DataMapper::Repository.adapters[adapter.to_sym]
|
22
|
+
migration(1, :create_people_table) { nil }
|
23
|
+
end
|
24
|
+
|
25
|
+
after(:each) do
|
26
|
+
migrations.clear
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '#migration' do
|
30
|
+
it 'creates a new migration object, and add it to the list of migrations' do
|
31
|
+
expect(migrations).to be_kind_of(Array)
|
32
|
+
expect(migrations.size).to eq 1
|
33
|
+
expect(migrations.first.name).to eq 'create_people_table'
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'allows multiple migrations to be added' do
|
37
|
+
migration(2, :add_dob_to_people) { nil }
|
38
|
+
migration(2, :add_favorite_pet_to_people) { nil }
|
39
|
+
migration(3, :add_something_else_to_people) { nil }
|
40
|
+
expect(migrations.size).to eq 4
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'raises an error on adding with a duplicated name' do
|
44
|
+
expect { migration(1, :create_people_table) { nil } }.to raise_error(RuntimeError, /Migration name conflict/)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe '#migrate_up! and #migrate_down!' do
|
49
|
+
before(:each) do
|
50
|
+
migration(2, :add_dob_to_people) { nil }
|
51
|
+
migration(2, :add_favorite_pet_to_people) { nil }
|
52
|
+
migration(3, :add_something_else_to_people) { nil }
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'calling migrate_up! migrates up all the migrations' do
|
56
|
+
# add our expectation that migrate_up should be called
|
57
|
+
migrations.each do |m|
|
58
|
+
expect(m).to receive(:perform_up)
|
59
|
+
end
|
60
|
+
migrate_up!
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'calling migrate_up! with an argument only migrates to that level' do
|
64
|
+
migrations.each do |m|
|
65
|
+
if m.position <= 2
|
66
|
+
expect(m).to receive(:perform_up)
|
67
|
+
else
|
68
|
+
expect(m).not_to receive(:perform_up)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
migrate_up!(2)
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'calling migrate_down! migrates down all the migrations' do
|
75
|
+
# add our expectation that migrate_up should be called
|
76
|
+
migrations.each do |m|
|
77
|
+
expect(m).to receive(:perform_down)
|
78
|
+
end
|
79
|
+
migrate_down!
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,156 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
|
3
|
+
describe 'A Migration' do
|
4
|
+
supported_by :postgres, :mysql, :sqlite, :oracle, :sqlserver do
|
5
|
+
describe DataMapper::Migration, 'interface' do
|
6
|
+
before(:all) do
|
7
|
+
@adapter = DataMapper::Spec.adapter
|
8
|
+
end
|
9
|
+
|
10
|
+
before do
|
11
|
+
@migration = DataMapper::Migration.new(1, :create_people_table, verbose: false) { nil }
|
12
|
+
end
|
13
|
+
|
14
|
+
before do
|
15
|
+
@original = $stderr
|
16
|
+
$stderr = StringIO.new
|
17
|
+
end
|
18
|
+
|
19
|
+
after do
|
20
|
+
$stderr = @original
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'has a position attribute' do
|
24
|
+
expect(@migration).to respond_to(:position)
|
25
|
+
|
26
|
+
expect(@migration.position).to eq 1
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'has a name attribute' do
|
30
|
+
expect(@migration).to respond_to(:name)
|
31
|
+
|
32
|
+
expect(@migration.name).to eq :create_people_table
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'has a :repository option' do
|
36
|
+
m = DataMapper::Migration.new(2, :create_dogs_table, repository: :alternate) { nil }
|
37
|
+
|
38
|
+
expect(m.instance_variable_get(:@repository)).to eq :alternate
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'uses the default repository by default' do
|
42
|
+
expect(@migration.instance_variable_get(:@repository)).to eq :default
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'still supports a :database option' do
|
46
|
+
m = DataMapper::Migration.new(2, :create_legacy_table, database: :legacy) { nil }
|
47
|
+
|
48
|
+
expect(m.instance_variable_get(:@repository)).to eq :legacy
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'warns when :database is used' do
|
52
|
+
DataMapper::Migration.new(2, :create_legacy_table, database: :legacy) { nil }
|
53
|
+
expect($stderr.string.chomp).to eq 'Using the :database option with migrations is deprecated, use :repository instead'
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'has a verbose option' do
|
57
|
+
m = DataMapper::Migration.new(2, :create_dogs_table, verbose: false) { nil }
|
58
|
+
expect(m.instance_variable_get(:@verbose)).to eq false
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'is verbose by default' do
|
62
|
+
m = DataMapper::Migration.new(2, :create_dogs_table) { nil }
|
63
|
+
expect(m.instance_variable_get(:@verbose)).to eq true
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'is sortable, first by position, then name' do
|
67
|
+
m1 = DataMapper::Migration.new(1, :create_people_table) { nil }
|
68
|
+
m2 = DataMapper::Migration.new(2, :create_dogs_table) { nil }
|
69
|
+
m3 = DataMapper::Migration.new(2, :create_cats_table) { nil }
|
70
|
+
m4 = DataMapper::Migration.new(4, :create_birds_table) { nil }
|
71
|
+
|
72
|
+
expect([m1, m2, m3, m4].sort).to eq [m1, m3, m2, m4]
|
73
|
+
end
|
74
|
+
|
75
|
+
adapter = DataMapper::Spec.adapter_name
|
76
|
+
|
77
|
+
expected_module_lambda = {
|
78
|
+
sqlite: -> { SQL::Sqlite },
|
79
|
+
mysql: -> { SQL::Mysql },
|
80
|
+
postgres: -> { SQL::Postgres }
|
81
|
+
}[adapter.to_sym]
|
82
|
+
|
83
|
+
expected_module = expected_module_lambda&.call
|
84
|
+
|
85
|
+
if expected_module
|
86
|
+
it "extends with #{expected_module} when adapter is #{adapter}" do
|
87
|
+
migration = DataMapper::Migration.new(1, :"#{adapter}_adapter_test") { nil }
|
88
|
+
expect((class << migration.adapter; self; end).included_modules).to include(expected_module)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe DataMapper::Migration, 'defining actions' do
|
94
|
+
before do
|
95
|
+
@migration = DataMapper::Migration.new(1, :create_people_table, verbose: false) { nil }
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'has an #up method' do
|
99
|
+
expect(@migration).to respond_to(:up)
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'saves the block passed into the #up method in @up_action' do
|
103
|
+
action = -> {}
|
104
|
+
@migration.up(&action)
|
105
|
+
|
106
|
+
expect(@migration.instance_variable_get(:@up_action)).to eq action
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'has a #down method' do
|
110
|
+
expect(@migration).to respond_to(:down)
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'saves the block passed into the #down method in @down_action' do
|
114
|
+
action = -> {}
|
115
|
+
@migration.down(&action)
|
116
|
+
|
117
|
+
expect(@migration.instance_variable_get(:@down_action)).to eq action
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'makes available an #execute method' do
|
121
|
+
expect(@migration).to respond_to(:execute)
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'makes available an #select method' do
|
125
|
+
expect(@migration).to respond_to(:select)
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'runs the sql passed into the #execute method'
|
129
|
+
# TODO: Find out how to stub the DataMapper::database.execute method
|
130
|
+
end
|
131
|
+
|
132
|
+
describe DataMapper::Migration, 'output' do
|
133
|
+
before do
|
134
|
+
@migration = DataMapper::Migration.new(1, :create_people_table) { nil }
|
135
|
+
@migration.stub!(:write) # so that we don't actually write anything to the console!
|
136
|
+
end
|
137
|
+
|
138
|
+
it "#say's a string with an indent" do
|
139
|
+
expect(@migration).to receive(:write).with(' Foobar')
|
140
|
+
@migration.say('Foobar', 2)
|
141
|
+
end
|
142
|
+
|
143
|
+
it "#say's with a default indent of 4" do
|
144
|
+
expect(@migration).to receive(:write).with(' Foobar')
|
145
|
+
@migration.say('Foobar')
|
146
|
+
end
|
147
|
+
|
148
|
+
it '#say_with_time the running time of a block' do
|
149
|
+
expect(@migration).to receive(:write).with(/Block/)
|
150
|
+
expect(@migration).to receive(:write).with(/-> \d+/)
|
151
|
+
|
152
|
+
@migration.say_with_time('Block') { nil }
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
@@ -0,0 +1,290 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
|
3
|
+
# Column type is expected to be inherited from DataMapper::Property::Text (CLOB, TEXT or whatever)
|
4
|
+
class MyCustomProperty < DataMapper::Property::Text; end
|
5
|
+
|
6
|
+
describe 'SQL generation' do
|
7
|
+
supported_by :postgres, :mysql, :sqlite, :oracle, :sqlserver do
|
8
|
+
describe DataMapper::Migration, '#create_table helper' do
|
9
|
+
before :all do
|
10
|
+
@adapter = DataMapper::Spec.adapter
|
11
|
+
@repository = DataMapper.repository(@adapter.name)
|
12
|
+
|
13
|
+
case DataMapper::Spec.adapter_name.to_sym
|
14
|
+
when :sqlite
|
15
|
+
@adapter.extend(SQL::Sqlite)
|
16
|
+
when :mysql
|
17
|
+
@adapter.extend(SQL::Mysql)
|
18
|
+
when :postgres
|
19
|
+
@adapter.extend(SQL::Postgres)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
before do
|
24
|
+
@creator = DataMapper::Migration::TableCreator.new(@adapter, :people) do
|
25
|
+
column :id, DataMapper::Property::Serial
|
26
|
+
column :name, 'VARCHAR(50)', allow_nil: false
|
27
|
+
column :long_string, String, size: 200
|
28
|
+
column :very_custom, MyCustomProperty
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'has a #create_table helper' do
|
33
|
+
@migration = DataMapper::Migration.new(1, :create_people_table, verbose: false) { nil }
|
34
|
+
expect(@migration).to respond_to(:create_table)
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'has a table_name' do
|
38
|
+
expect(@creator.table_name).to eq 'people'
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'has an adapter' do
|
42
|
+
expect(@creator.instance_eval('@adapter', __FILE__, __LINE__)).to eq @adapter
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'has an options hash' do
|
46
|
+
expect(@creator.opts).to be_kind_of(Hash)
|
47
|
+
expect(@creator.opts).to eq({})
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'has an array of columns' do
|
51
|
+
expect(@creator.instance_eval('@columns', __FILE__, __LINE__)).to be_kind_of(Array)
|
52
|
+
expect(@creator.instance_eval('@columns', __FILE__, __LINE__).size).to eq 4
|
53
|
+
expect(@creator.instance_eval('@columns', __FILE__, __LINE__).first).to be_kind_of(DataMapper::Migration::TableCreator::Column)
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'quotes the table name for the adapter' do
|
57
|
+
expect(@creator.quoted_table_name).to eq((DataMapper::Spec.adapter_name.to_sym == :mysql) ? '`people`' : '"people"')
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'allows for custom options' do
|
61
|
+
columns = @creator.instance_eval('@columns', __FILE__, __LINE__)
|
62
|
+
col = columns.detect { |c| c.name == 'long_string' }
|
63
|
+
expect(col.instance_eval('@type', __FILE__, __LINE__)).to include('200')
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'generates a NOT NULL column when :allow_nil is false' do
|
67
|
+
expect(@creator.instance_eval('@columns', __FILE__, __LINE__)[1].type).to match(/NOT NULL/)
|
68
|
+
end
|
69
|
+
|
70
|
+
case DataMapper::Spec.adapter_name.to_sym
|
71
|
+
when :mysql
|
72
|
+
it 'creates an InnoDB database for MySQL' do
|
73
|
+
# can't get an exact == comparison here because character set and collation may differ per connection
|
74
|
+
expect(@creator.to_sql).to match(/^CREATE TABLE `people` \(`id` SERIAL PRIMARY KEY, `name` VARCHAR\(50\) NOT NULL, `long_string` VARCHAR\(200\), `very_custom` TEXT\) ENGINE = InnoDB CHARACTER SET \w+ COLLATE \w+\z/)
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'allows for custom table creation options for MySQL' do
|
78
|
+
opts = {
|
79
|
+
storage_engine: 'MyISAM',
|
80
|
+
character_set: 'big5',
|
81
|
+
collation: 'big5_chinese_ci'
|
82
|
+
}
|
83
|
+
|
84
|
+
creator = DataMapper::Migration::TableCreator.new(@adapter, :people, opts) do
|
85
|
+
column :id, DataMapper::Property::Serial
|
86
|
+
end
|
87
|
+
|
88
|
+
expect(creator.to_sql).to match(/^CREATE TABLE `people` \(`id` SERIAL PRIMARY KEY\) ENGINE = MyISAM CHARACTER SET big5 COLLATE big5_chinese_ci\z/)
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'respects default storage engine types specified by the MySQL adapter' do
|
92
|
+
adapter = DataMapper::Spec.adapter
|
93
|
+
adapter.extend(SQL::Mysql)
|
94
|
+
|
95
|
+
adapter.storage_engine = 'MyISAM'
|
96
|
+
|
97
|
+
creator = DataMapper::Migration::TableCreator.new(adapter, :people) do
|
98
|
+
column :id, DataMapper::Property::Serial
|
99
|
+
end
|
100
|
+
|
101
|
+
expect(creator.to_sql).to match(/^CREATE TABLE `people` \(`id` SERIAL PRIMARY KEY\) ENGINE = MyISAM CHARACTER SET \w+ COLLATE \w+\z/)
|
102
|
+
end
|
103
|
+
|
104
|
+
when :postgres
|
105
|
+
it 'outputs a CREATE TABLE statement when sent #to_sql' do
|
106
|
+
expect(@creator.to_sql).to eq 'CREATE TABLE "people" ("id" SERIAL PRIMARY KEY, "name" VARCHAR(50) NOT NULL, "long_string" VARCHAR(200), ' \
|
107
|
+
'"very_custom" TEXT)'
|
108
|
+
end
|
109
|
+
when :sqlite3, :sqlite
|
110
|
+
it 'outputs a CREATE TABLE statement when sent #to_sql' do
|
111
|
+
expect(@creator.to_sql).to eq 'CREATE TABLE "people" ("id" INTEGER PRIMARY KEY AUTOINCREMENT, "name" VARCHAR(50) NOT NULL, "long_string" ' \
|
112
|
+
'VARCHAR(200), "very_custom" TEXT)'
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
context 'when the default string length is modified' do
|
117
|
+
before do
|
118
|
+
@original = DataMapper::Property::String.length
|
119
|
+
DataMapper::Property::String.length(255)
|
120
|
+
|
121
|
+
@creator = DataMapper::Migration::TableCreator.new(@adapter, :people) do
|
122
|
+
column :string, String
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
after do
|
127
|
+
DataMapper::Property::String.length(@original)
|
128
|
+
end
|
129
|
+
|
130
|
+
it 'uses the new length for the character column' do
|
131
|
+
expect(@creator.to_sql).to match(/CHAR\(255\)/)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
describe DataMapper::Migration, '#modify_table helper' do
|
137
|
+
before do
|
138
|
+
@migration = DataMapper::Migration.new(1, :create_people_table, verbose: false) { nil }
|
139
|
+
end
|
140
|
+
|
141
|
+
it 'has a #modify_table helper' do
|
142
|
+
expect(@migration).to respond_to(:modify_table)
|
143
|
+
end
|
144
|
+
|
145
|
+
describe '#change_column' do
|
146
|
+
before do
|
147
|
+
@modifier = DataMapper::Migration::TableModifier.new(@adapter, :people) do
|
148
|
+
change_column :name, 'VARCHAR(200)'
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
case DataMapper::Spec.adapter_name.to_sym
|
153
|
+
when :mysql
|
154
|
+
it 'alters the column' do
|
155
|
+
expect(@modifier.to_sql).to eq 'ALTER TABLE `people` MODIFY COLUMN `name` VARCHAR(200)'
|
156
|
+
end
|
157
|
+
when :postgres
|
158
|
+
it 'alters the column' do
|
159
|
+
expect(@modifier.to_sql).to eq 'ALTER TABLE "people" ALTER COLUMN "name" VARCHAR(200)'
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
describe '#rename_column' do
|
165
|
+
case DataMapper::Spec.adapter_name.to_sym
|
166
|
+
when :postgres
|
167
|
+
before do
|
168
|
+
@modifier = DataMapper::Migration::TableModifier.new(@adapter, :people) do
|
169
|
+
rename_column :name, :first_name
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
it 'renames the column' do
|
174
|
+
expect(@modifier.to_sql).to eq 'ALTER TABLE "people" RENAME COLUMN "name" TO "first_name"'
|
175
|
+
end
|
176
|
+
when :mysql
|
177
|
+
before do
|
178
|
+
# create the table so the existing column schema can be introspected
|
179
|
+
@adapter.execute("CREATE TABLE `people` (name VARCHAR(50) DEFAULT 'John' NOT NULL)")
|
180
|
+
|
181
|
+
@modifier = DataMapper::Migration::TableModifier.new(@adapter, :people) do
|
182
|
+
rename_column :name, :first_name
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
after do
|
187
|
+
@adapter.execute('DROP TABLE `people`')
|
188
|
+
end
|
189
|
+
|
190
|
+
it 'changes the column' do
|
191
|
+
expect(@modifier.to_sql).to eq "ALTER TABLE `people` CHANGE `name` `first_name` varchar(50) DEFAULT 'John' NOT NULL"
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
describe DataMapper::Migration, 'other helpers' do
|
198
|
+
before do
|
199
|
+
@migration = DataMapper::Migration.new(1, :create_people_table, verbose: false) { nil }
|
200
|
+
end
|
201
|
+
|
202
|
+
it 'has a #drop_table helper' do
|
203
|
+
expect(@migration).to respond_to(:drop_table)
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
describe DataMapper::Migration, 'version tracking' do
|
208
|
+
before(:each) do
|
209
|
+
@migration = DataMapper::Migration.new(1, :create_people_table, verbose: false) do
|
210
|
+
up { :ran_up }
|
211
|
+
down { :ran_down }
|
212
|
+
end
|
213
|
+
|
214
|
+
@migration.send(:create_migration_info_table_if_needed)
|
215
|
+
end
|
216
|
+
|
217
|
+
after(:each) { DataMapper::Spec.adapter.execute('DROP TABLE migration_info') rescue nil }
|
218
|
+
|
219
|
+
def insert_migration_record
|
220
|
+
DataMapper::Spec.adapter.execute("INSERT INTO migration_info (migration_name) VALUES ('create_people_table')")
|
221
|
+
end
|
222
|
+
|
223
|
+
it 'knows if the migration_info table exists' do
|
224
|
+
expect(@migration.send(:migration_info_table_exists?)).to be(true)
|
225
|
+
end
|
226
|
+
|
227
|
+
it 'knows if the migration_info table does not exist' do
|
228
|
+
DataMapper::Spec.adapter.execute('DROP TABLE migration_info') rescue nil
|
229
|
+
expect(@migration.send(:migration_info_table_exists?)).to be(false)
|
230
|
+
end
|
231
|
+
|
232
|
+
it 'is able to find the migration_info record for itself' do
|
233
|
+
insert_migration_record
|
234
|
+
expect(@migration.send(:migration_record)).not_to be_empty
|
235
|
+
end
|
236
|
+
|
237
|
+
it 'knows if a migration needs_up?' do
|
238
|
+
expect(@migration.send(:needs_up?)).to be(true)
|
239
|
+
insert_migration_record
|
240
|
+
expect(@migration.send(:needs_up?)).to be(false)
|
241
|
+
end
|
242
|
+
|
243
|
+
it 'knows if a migration needs_down?' do
|
244
|
+
expect(@migration.send(:needs_down?)).to be(false)
|
245
|
+
insert_migration_record
|
246
|
+
expect(@migration.send(:needs_down?)).to be(true)
|
247
|
+
end
|
248
|
+
|
249
|
+
it 'properly quotes the migration_info table via the adapter for use in queries' do
|
250
|
+
expect(@migration.send(:migration_info_table)).to eq @migration.quote_table_name('migration_info')
|
251
|
+
end
|
252
|
+
|
253
|
+
it 'properly quotes the migration_info.migration_name column via the adapter for use in queries' do
|
254
|
+
expect(@migration.send(:migration_name_column)).to eq @migration.quote_column_name('migration_name')
|
255
|
+
end
|
256
|
+
|
257
|
+
it "properly quotes the migration's name for use in queries"
|
258
|
+
# TODO: how to i call the adapter's #escape_sql method?
|
259
|
+
|
260
|
+
it "creates the migration_info table if it doesn't exist" do
|
261
|
+
DataMapper::Spec.adapter.execute('DROP TABLE migration_info')
|
262
|
+
expect(@migration.send(:migration_info_table_exists?)).to be(false)
|
263
|
+
@migration.send(:create_migration_info_table_if_needed)
|
264
|
+
expect(@migration.send(:migration_info_table_exists?)).to be(true)
|
265
|
+
end
|
266
|
+
|
267
|
+
it 'inserts a record into the migration_info table on up' do
|
268
|
+
expect(@migration.send(:migration_record)).to be_empty
|
269
|
+
expect(@migration.perform_up).to eq :ran_up
|
270
|
+
expect(@migration.send(:migration_record)).not_to be_empty
|
271
|
+
end
|
272
|
+
|
273
|
+
it 'removes a record from the migration_info table on down' do
|
274
|
+
insert_migration_record
|
275
|
+
expect(@migration.send(:migration_record)).not_to be_empty
|
276
|
+
expect(@migration.perform_down).to eq :ran_down
|
277
|
+
expect(@migration.send(:migration_record)).to be_empty
|
278
|
+
end
|
279
|
+
|
280
|
+
it 'does not run the up action if the record exists in the table' do
|
281
|
+
insert_migration_record
|
282
|
+
expect(@migration.perform_up).not_to eq :ran_up
|
283
|
+
end
|
284
|
+
|
285
|
+
it 'does not run the down action if the record does not exist in the table' do
|
286
|
+
expect(@migration.perform_down).not_to eq :ran_down
|
287
|
+
end
|
288
|
+
end
|
289
|
+
end
|
290
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
|
3
|
+
require_relative 'require_spec'
|
4
|
+
require 'dm-core/spec/setup'
|
5
|
+
|
6
|
+
# To really test this behavior, this spec needs to be run in isolation and not
|
7
|
+
# as part of the typical rake spec run, which requires dm-transactions upfront
|
8
|
+
class ::Person
|
9
|
+
include DataMapper::Resource
|
10
|
+
property :id, Serial
|
11
|
+
end
|
12
|
+
|
13
|
+
if %w(postgres mysql sqlite oracle sqlserver).include?(ENV['ADAPTER'])
|
14
|
+
describe "require 'dm-migrations' after calling DataMapper.setup" do
|
15
|
+
before(:all) do
|
16
|
+
@adapter = DataMapper::Spec.adapter
|
17
|
+
require 'dm-migrations'
|
18
|
+
|
19
|
+
@model = Person
|
20
|
+
end
|
21
|
+
|
22
|
+
it_behaves_like "require 'dm-migrations'"
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
|
3
|
+
require_relative 'require_spec'
|
4
|
+
require 'dm-core/spec/setup'
|
5
|
+
|
6
|
+
# To really test this behavior, this spec needs to be run in isolation and not
|
7
|
+
# as part of the typical rake spec run, which requires dm-transactions upfront
|
8
|
+
class ::Person
|
9
|
+
include DataMapper::Resource
|
10
|
+
property :id, Serial
|
11
|
+
end
|
12
|
+
|
13
|
+
if %w(postgres mysql sqlite oracle sqlserver).include?(ENV['ADAPTER'])
|
14
|
+
describe "require 'dm-migrations' before calling DataMapper.setup" do
|
15
|
+
before(:all) do
|
16
|
+
require 'dm-migrations'
|
17
|
+
@adapter = DataMapper::Spec.adapter
|
18
|
+
|
19
|
+
@model = Person
|
20
|
+
end
|
21
|
+
|
22
|
+
it_behaves_like "require 'dm-migrations'"
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
shared_examples "require 'dm-migrations'" do
|
2
|
+
it 'includes the migration api in the DataMapper namespace' do
|
3
|
+
expect(DataMapper.respond_to?(:migrate!)).to be(true)
|
4
|
+
expect(DataMapper.respond_to?(:auto_migrate!)).to be(true)
|
5
|
+
expect(DataMapper.respond_to?(:auto_upgrade!)).to be(true)
|
6
|
+
expect(DataMapper.respond_to?(:auto_migrate_up!, true)).to be(true)
|
7
|
+
expect(DataMapper.respond_to?(:auto_migrate_down!, true)).to be(true)
|
8
|
+
end
|
9
|
+
|
10
|
+
%w(Repository Model).each do |name|
|
11
|
+
it "includes the migration api in DataMapper::#{name}" do
|
12
|
+
expect(DataMapper.const_get(name) < DataMapper::Migrations.const_get(name)).to be(true)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'includes the migration api into the adapter' do
|
17
|
+
expect(@adapter.respond_to?(:storage_exists?)).to be(true)
|
18
|
+
expect(@adapter.respond_to?(:field_exists?)).to be(true)
|
19
|
+
expect(@adapter.respond_to?(:upgrade_model_storage)).to be(true)
|
20
|
+
expect(@adapter.respond_to?(:create_model_storage)).to be(true)
|
21
|
+
expect(@adapter.respond_to?(:destroy_model_storage)).to be(true)
|
22
|
+
end
|
23
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'dm-migrations'
|
2
|
+
require 'dm-migrations/migration_runner'
|
3
|
+
|
4
|
+
require 'dm-core/spec/setup'
|
5
|
+
require 'dm-core/spec/lib/adapter_helpers'
|
6
|
+
require 'dm-core/spec/lib/spec_helper'
|
7
|
+
require 'dm-core/spec/lib/pending_helpers'
|
8
|
+
|
9
|
+
RSpec.configure do |config|
|
10
|
+
config.extend(DataMapper::Spec::Adapters::Helpers)
|
11
|
+
config.include(DataMapper::Spec::PendingHelpers)
|
12
|
+
|
13
|
+
config.after :all do
|
14
|
+
DataMapper::Spec.cleanup_models
|
15
|
+
end
|
16
|
+
end
|