ardm-migrations 1.2.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.
- checksums.yaml +7 -0
- data/.gitignore +35 -0
- data/.travis.yml +11 -0
- data/Gemfile +53 -0
- data/LICENSE +20 -0
- data/README.rdoc +39 -0
- data/Rakefile +4 -0
- data/ardm-migrations.gemspec +27 -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/examples/Rakefile +144 -0
- data/examples/sample_migration.rb +58 -0
- data/examples/sample_migration_spec.rb +50 -0
- data/lib/ardm-migrations.rb +1 -0
- data/lib/dm-migrations/adapters/dm-do-adapter.rb +295 -0
- data/lib/dm-migrations/adapters/dm-mysql-adapter.rb +299 -0
- data/lib/dm-migrations/adapters/dm-oracle-adapter.rb +332 -0
- data/lib/dm-migrations/adapters/dm-postgres-adapter.rb +159 -0
- data/lib/dm-migrations/adapters/dm-sqlite-adapter.rb +96 -0
- data/lib/dm-migrations/adapters/dm-sqlserver-adapter.rb +177 -0
- data/lib/dm-migrations/adapters/dm-yaml-adapter.rb +23 -0
- data/lib/dm-migrations/auto_migration.rb +239 -0
- data/lib/dm-migrations/exceptions/duplicate_migration.rb +6 -0
- data/lib/dm-migrations/migration.rb +300 -0
- data/lib/dm-migrations/migration_runner.rb +85 -0
- data/lib/dm-migrations/sql/column.rb +5 -0
- data/lib/dm-migrations/sql/mysql.rb +61 -0
- data/lib/dm-migrations/sql/postgres.rb +82 -0
- data/lib/dm-migrations/sql/sqlite.rb +51 -0
- data/lib/dm-migrations/sql/table.rb +15 -0
- data/lib/dm-migrations/sql/table_creator.rb +109 -0
- data/lib/dm-migrations/sql/table_modifier.rb +57 -0
- data/lib/dm-migrations/sql.rb +5 -0
- data/lib/dm-migrations/version.rb +5 -0
- data/lib/dm-migrations.rb +3 -0
- data/lib/spec/example/migration_example_group.rb +73 -0
- data/lib/spec/matchers/migration_matchers.rb +106 -0
- data/spec/integration/auto_migration_spec.rb +553 -0
- data/spec/integration/auto_upgrade_spec.rb +40 -0
- data/spec/integration/migration_runner_spec.rb +89 -0
- data/spec/integration/migration_spec.rb +157 -0
- data/spec/integration/sql_spec.rb +250 -0
- data/spec/isolated/require_after_setup_spec.rb +30 -0
- data/spec/isolated/require_before_setup_spec.rb +30 -0
- data/spec/isolated/require_spec.rb +25 -0
- data/spec/rcov.opts +6 -0
- data/spec/spec.opts +4 -0
- data/spec/spec_helper.rb +18 -0
- data/spec/unit/migration_spec.rb +453 -0
- data/spec/unit/sql/column_spec.rb +14 -0
- data/spec/unit/sql/postgres_spec.rb +97 -0
- data/spec/unit/sql/sqlite_extensions_spec.rb +108 -0
- data/spec/unit/sql/table_creator_spec.rb +94 -0
- data/spec/unit/sql/table_modifier_spec.rb +49 -0
- data/spec/unit/sql/table_spec.rb +28 -0
- data/spec/unit/sql_spec.rb +7 -0
- data/tasks/spec.rake +38 -0
- data/tasks/yard.rake +9 -0
- data/tasks/yardstick.rake +19 -0
- metadata +150 -0
@@ -0,0 +1,553 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'dm-migrations/auto_migration'
|
4
|
+
|
5
|
+
describe DataMapper::Migrations do
|
6
|
+
def capture_log(mod)
|
7
|
+
original, mod.logger = mod.logger, DataObjects::Logger.new(@log = StringIO.new, :debug)
|
8
|
+
yield
|
9
|
+
ensure
|
10
|
+
@log.rewind
|
11
|
+
@output = @log.readlines.map do |line|
|
12
|
+
line.chomp.gsub(/\A.+?~ \(\d+\.?\d*\)\s+/, '')
|
13
|
+
end
|
14
|
+
|
15
|
+
mod.logger = original
|
16
|
+
end
|
17
|
+
|
18
|
+
before :all do
|
19
|
+
class DataMapper::Property::NumericString < DataMapper::Property::String
|
20
|
+
default 0
|
21
|
+
|
22
|
+
def dump(value)
|
23
|
+
return if value.nil?
|
24
|
+
value.to_s
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
supported_by :mysql do
|
30
|
+
before :all do
|
31
|
+
module ::Blog
|
32
|
+
class Article
|
33
|
+
include DataMapper::Resource
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
@model = ::Blog::Article
|
38
|
+
end
|
39
|
+
|
40
|
+
describe '#auto_migrate' do
|
41
|
+
describe 'Integer property' do
|
42
|
+
[
|
43
|
+
[ 0, 1, 'TINYINT(1) UNSIGNED' ],
|
44
|
+
[ 0, 9, 'TINYINT(1) UNSIGNED' ],
|
45
|
+
[ 0, 10, 'TINYINT(2) UNSIGNED' ],
|
46
|
+
[ 0, 99, 'TINYINT(2) UNSIGNED' ],
|
47
|
+
[ 0, 100, 'TINYINT(3) UNSIGNED' ],
|
48
|
+
[ 0, 255, 'TINYINT(3) UNSIGNED' ],
|
49
|
+
[ 0, 256, 'SMALLINT(3) UNSIGNED' ],
|
50
|
+
[ 0, 999, 'SMALLINT(3) UNSIGNED' ],
|
51
|
+
[ 0, 1000, 'SMALLINT(4) UNSIGNED' ],
|
52
|
+
[ 0, 9999, 'SMALLINT(4) UNSIGNED' ],
|
53
|
+
[ 0, 10000, 'SMALLINT(5) UNSIGNED' ],
|
54
|
+
[ 0, 65535, 'SMALLINT(5) UNSIGNED' ],
|
55
|
+
[ 0, 65536, 'MEDIUMINT(5) UNSIGNED' ],
|
56
|
+
[ 0, 99999, 'MEDIUMINT(5) UNSIGNED' ],
|
57
|
+
[ 0, 100000, 'MEDIUMINT(6) UNSIGNED' ],
|
58
|
+
[ 0, 999999, 'MEDIUMINT(6) UNSIGNED' ],
|
59
|
+
[ 0, 1000000, 'MEDIUMINT(7) UNSIGNED' ],
|
60
|
+
[ 0, 9999999, 'MEDIUMINT(7) UNSIGNED' ],
|
61
|
+
[ 0, 10000000, 'MEDIUMINT(8) UNSIGNED' ],
|
62
|
+
[ 0, 16777215, 'MEDIUMINT(8) UNSIGNED' ],
|
63
|
+
[ 0, 16777216, 'INT(8) UNSIGNED' ],
|
64
|
+
[ 0, 99999999, 'INT(8) UNSIGNED' ],
|
65
|
+
[ 0, 100000000, 'INT(9) UNSIGNED' ],
|
66
|
+
[ 0, 999999999, 'INT(9) UNSIGNED' ],
|
67
|
+
[ 0, 1000000000, 'INT(10) UNSIGNED' ],
|
68
|
+
[ 0, 4294967295, 'INT(10) UNSIGNED' ],
|
69
|
+
[ 0, 4294967296, 'BIGINT(10) UNSIGNED' ],
|
70
|
+
[ 0, 9999999999, 'BIGINT(10) UNSIGNED' ],
|
71
|
+
[ 0, 10000000000, 'BIGINT(11) UNSIGNED' ],
|
72
|
+
[ 0, 99999999999, 'BIGINT(11) UNSIGNED' ],
|
73
|
+
[ 0, 100000000000, 'BIGINT(12) UNSIGNED' ],
|
74
|
+
[ 0, 999999999999, 'BIGINT(12) UNSIGNED' ],
|
75
|
+
[ 0, 1000000000000, 'BIGINT(13) UNSIGNED' ],
|
76
|
+
[ 0, 9999999999999, 'BIGINT(13) UNSIGNED' ],
|
77
|
+
[ 0, 10000000000000, 'BIGINT(14) UNSIGNED' ],
|
78
|
+
[ 0, 99999999999999, 'BIGINT(14) UNSIGNED' ],
|
79
|
+
[ 0, 100000000000000, 'BIGINT(15) UNSIGNED' ],
|
80
|
+
[ 0, 999999999999999, 'BIGINT(15) UNSIGNED' ],
|
81
|
+
[ 0, 1000000000000000, 'BIGINT(16) UNSIGNED' ],
|
82
|
+
[ 0, 9999999999999999, 'BIGINT(16) UNSIGNED' ],
|
83
|
+
[ 0, 10000000000000000, 'BIGINT(17) UNSIGNED' ],
|
84
|
+
[ 0, 99999999999999999, 'BIGINT(17) UNSIGNED' ],
|
85
|
+
[ 0, 100000000000000000, 'BIGINT(18) UNSIGNED' ],
|
86
|
+
[ 0, 999999999999999999, 'BIGINT(18) UNSIGNED' ],
|
87
|
+
[ 0, 1000000000000000000, 'BIGINT(19) UNSIGNED' ],
|
88
|
+
[ 0, 9999999999999999999, 'BIGINT(19) UNSIGNED' ],
|
89
|
+
[ 0, 10000000000000000000, 'BIGINT(20) UNSIGNED' ],
|
90
|
+
[ 0, 18446744073709551615, 'BIGINT(20) UNSIGNED' ],
|
91
|
+
|
92
|
+
[ -1, 0, 'TINYINT(2)' ],
|
93
|
+
[ -1, 9, 'TINYINT(2)' ],
|
94
|
+
[ -1, 10, 'TINYINT(2)' ],
|
95
|
+
[ -1, 99, 'TINYINT(2)' ],
|
96
|
+
[ -1, 100, 'TINYINT(3)' ],
|
97
|
+
[ -1, 127, 'TINYINT(3)' ],
|
98
|
+
[ -1, 128, 'SMALLINT(3)' ],
|
99
|
+
[ -1, 999, 'SMALLINT(3)' ],
|
100
|
+
[ -1, 1000, 'SMALLINT(4)' ],
|
101
|
+
[ -1, 9999, 'SMALLINT(4)' ],
|
102
|
+
[ -1, 10000, 'SMALLINT(5)' ],
|
103
|
+
[ -1, 32767, 'SMALLINT(5)' ],
|
104
|
+
[ -1, 32768, 'MEDIUMINT(5)' ],
|
105
|
+
[ -1, 99999, 'MEDIUMINT(5)' ],
|
106
|
+
[ -1, 100000, 'MEDIUMINT(6)' ],
|
107
|
+
[ -1, 999999, 'MEDIUMINT(6)' ],
|
108
|
+
[ -1, 1000000, 'MEDIUMINT(7)' ],
|
109
|
+
[ -1, 8388607, 'MEDIUMINT(7)' ],
|
110
|
+
[ -1, 8388608, 'INT(7)' ],
|
111
|
+
[ -1, 9999999, 'INT(7)' ],
|
112
|
+
[ -1, 10000000, 'INT(8)' ],
|
113
|
+
[ -1, 99999999, 'INT(8)' ],
|
114
|
+
[ -1, 100000000, 'INT(9)' ],
|
115
|
+
[ -1, 999999999, 'INT(9)' ],
|
116
|
+
[ -1, 1000000000, 'INT(10)' ],
|
117
|
+
[ -1, 2147483647, 'INT(10)' ],
|
118
|
+
[ -1, 2147483648, 'BIGINT(10)' ],
|
119
|
+
[ -1, 9999999999, 'BIGINT(10)' ],
|
120
|
+
[ -1, 10000000000, 'BIGINT(11)' ],
|
121
|
+
[ -1, 99999999999, 'BIGINT(11)' ],
|
122
|
+
[ -1, 100000000000, 'BIGINT(12)' ],
|
123
|
+
[ -1, 999999999999, 'BIGINT(12)' ],
|
124
|
+
[ -1, 1000000000000, 'BIGINT(13)' ],
|
125
|
+
[ -1, 9999999999999, 'BIGINT(13)' ],
|
126
|
+
[ -1, 10000000000000, 'BIGINT(14)' ],
|
127
|
+
[ -1, 99999999999999, 'BIGINT(14)' ],
|
128
|
+
[ -1, 100000000000000, 'BIGINT(15)' ],
|
129
|
+
[ -1, 999999999999999, 'BIGINT(15)' ],
|
130
|
+
[ -1, 1000000000000000, 'BIGINT(16)' ],
|
131
|
+
[ -1, 9999999999999999, 'BIGINT(16)' ],
|
132
|
+
[ -1, 10000000000000000, 'BIGINT(17)' ],
|
133
|
+
[ -1, 99999999999999999, 'BIGINT(17)' ],
|
134
|
+
[ -1, 100000000000000000, 'BIGINT(18)' ],
|
135
|
+
[ -1, 999999999999999999, 'BIGINT(18)' ],
|
136
|
+
[ -1, 1000000000000000000, 'BIGINT(19)' ],
|
137
|
+
[ -1, 9223372036854775807, 'BIGINT(19)' ],
|
138
|
+
|
139
|
+
[ -1, 0, 'TINYINT(2)' ],
|
140
|
+
[ -9, 0, 'TINYINT(2)' ],
|
141
|
+
[ -10, 0, 'TINYINT(3)' ],
|
142
|
+
[ -99, 0, 'TINYINT(3)' ],
|
143
|
+
[ -100, 0, 'TINYINT(4)' ],
|
144
|
+
[ -128, 0, 'TINYINT(4)' ],
|
145
|
+
[ -129, 0, 'SMALLINT(4)' ],
|
146
|
+
[ -999, 0, 'SMALLINT(4)' ],
|
147
|
+
[ -1000, 0, 'SMALLINT(5)' ],
|
148
|
+
[ -9999, 0, 'SMALLINT(5)' ],
|
149
|
+
[ -10000, 0, 'SMALLINT(6)' ],
|
150
|
+
[ -32768, 0, 'SMALLINT(6)' ],
|
151
|
+
[ -32769, 0, 'MEDIUMINT(6)' ],
|
152
|
+
[ -99999, 0, 'MEDIUMINT(6)' ],
|
153
|
+
[ -100000, 0, 'MEDIUMINT(7)' ],
|
154
|
+
[ -999999, 0, 'MEDIUMINT(7)' ],
|
155
|
+
[ -1000000, 0, 'MEDIUMINT(8)' ],
|
156
|
+
[ -8388608, 0, 'MEDIUMINT(8)' ],
|
157
|
+
[ -8388609, 0, 'INT(8)' ],
|
158
|
+
[ -9999999, 0, 'INT(8)' ],
|
159
|
+
[ -10000000, 0, 'INT(9)' ],
|
160
|
+
[ -99999999, 0, 'INT(9)' ],
|
161
|
+
[ -100000000, 0, 'INT(10)' ],
|
162
|
+
[ -999999999, 0, 'INT(10)' ],
|
163
|
+
[ -1000000000, 0, 'INT(11)' ],
|
164
|
+
[ -2147483648, 0, 'INT(11)' ],
|
165
|
+
[ -2147483649, 0, 'BIGINT(11)' ],
|
166
|
+
[ -9999999999, 0, 'BIGINT(11)' ],
|
167
|
+
[ -10000000000, 0, 'BIGINT(12)' ],
|
168
|
+
[ -99999999999, 0, 'BIGINT(12)' ],
|
169
|
+
[ -100000000000, 0, 'BIGINT(13)' ],
|
170
|
+
[ -999999999999, 0, 'BIGINT(13)' ],
|
171
|
+
[ -1000000000000, 0, 'BIGINT(14)' ],
|
172
|
+
[ -9999999999999, 0, 'BIGINT(14)' ],
|
173
|
+
[ -10000000000000, 0, 'BIGINT(15)' ],
|
174
|
+
[ -99999999999999, 0, 'BIGINT(15)' ],
|
175
|
+
[ -100000000000000, 0, 'BIGINT(16)' ],
|
176
|
+
[ -999999999999999, 0, 'BIGINT(16)' ],
|
177
|
+
[ -1000000000000000, 0, 'BIGINT(17)' ],
|
178
|
+
[ -9999999999999999, 0, 'BIGINT(17)' ],
|
179
|
+
[ -10000000000000000, 0, 'BIGINT(18)' ],
|
180
|
+
[ -99999999999999999, 0, 'BIGINT(18)' ],
|
181
|
+
[ -100000000000000000, 0, 'BIGINT(19)' ],
|
182
|
+
[ -999999999999999999, 0, 'BIGINT(19)' ],
|
183
|
+
[ -1000000000000000000, 0, 'BIGINT(20)' ],
|
184
|
+
[ -9223372036854775808, 0, 'BIGINT(20)' ],
|
185
|
+
|
186
|
+
[ nil, 2147483647, 'INT(10) UNSIGNED' ],
|
187
|
+
[ 0, nil, 'INT(10) UNSIGNED' ],
|
188
|
+
[ nil, nil, 'INTEGER' ],
|
189
|
+
].each do |min, max, statement|
|
190
|
+
options = { :key => true }
|
191
|
+
options[:min] = min if min
|
192
|
+
options[:max] = max if max
|
193
|
+
|
194
|
+
describe "with a min of #{min} and a max of #{max}" do
|
195
|
+
before :all do
|
196
|
+
@property = @model.property(:id, Integer, options)
|
197
|
+
|
198
|
+
@response = capture_log(DataObjects::Mysql) { @model.auto_migrate! }
|
199
|
+
end
|
200
|
+
|
201
|
+
it 'should return true' do
|
202
|
+
@response.should be(true)
|
203
|
+
end
|
204
|
+
|
205
|
+
it "should create a #{statement} column" do
|
206
|
+
@output.last.should =~ %r{\ACREATE TABLE `blog_articles` \(`id` #{Regexp.escape(statement)} NOT NULL, PRIMARY KEY\(`id`\)\) ENGINE = InnoDB CHARACTER SET [a-z\d]+ COLLATE (?:[a-z\d](?:_?[a-z\d]+)*)\z}
|
207
|
+
end
|
208
|
+
|
209
|
+
[ :min, :max ].each do |key|
|
210
|
+
next unless value = options[key]
|
211
|
+
it "should allow the #{key} value #{value} to be stored" do
|
212
|
+
pending_if "#{value} causes problem with JRuby 1.5.2 parser", RUBY_PLATFORM[/java/] && JRUBY_VERSION < '1.5.6' && value == -9223372036854775808 do
|
213
|
+
lambda {
|
214
|
+
resource = @model.create(@property => value)
|
215
|
+
@model.first(@property => value).should == resource
|
216
|
+
}.should_not raise_error
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
describe 'Text property' do
|
225
|
+
before :all do
|
226
|
+
@model.property(:id, DataMapper::Property::Serial)
|
227
|
+
end
|
228
|
+
|
229
|
+
[
|
230
|
+
[ 0, 'TINYTEXT' ],
|
231
|
+
[ 1, 'TINYTEXT' ],
|
232
|
+
[ 255, 'TINYTEXT' ],
|
233
|
+
[ 256, 'TEXT' ],
|
234
|
+
[ 65535, 'TEXT' ],
|
235
|
+
[ 65536, 'MEDIUMTEXT' ],
|
236
|
+
[ 16777215, 'MEDIUMTEXT' ],
|
237
|
+
[ 16777216, 'LONGTEXT' ],
|
238
|
+
[ 4294967295, 'LONGTEXT' ],
|
239
|
+
|
240
|
+
[ nil, 'TEXT' ],
|
241
|
+
].each do |length, statement|
|
242
|
+
options = {}
|
243
|
+
options[:length] = length if length
|
244
|
+
|
245
|
+
describe "with a length of #{length}" do
|
246
|
+
before :all do
|
247
|
+
@property = @model.property(:body, DataMapper::Property::Text, options)
|
248
|
+
|
249
|
+
@response = capture_log(DataObjects::Mysql) { @model.auto_migrate! }
|
250
|
+
end
|
251
|
+
|
252
|
+
it 'should return true' do
|
253
|
+
@response.should be(true)
|
254
|
+
end
|
255
|
+
|
256
|
+
it "should create a #{statement} column" do
|
257
|
+
@output.last.should =~ %r{\ACREATE TABLE `blog_articles` \(`id` INT\(10\) UNSIGNED NOT NULL AUTO_INCREMENT, `body` #{Regexp.escape(statement)}, PRIMARY KEY\(`id`\)\) ENGINE = InnoDB CHARACTER SET [a-z\d]+ COLLATE (?:[a-z\d](?:_?[a-z\d]+)*)\z}
|
258
|
+
end
|
259
|
+
end
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
describe 'String property' do
|
264
|
+
before :all do
|
265
|
+
@model.property(:id, DataMapper::Property::Serial)
|
266
|
+
end
|
267
|
+
|
268
|
+
[
|
269
|
+
[ 1, 'VARCHAR(1)' ],
|
270
|
+
[ 50, 'VARCHAR(50)' ],
|
271
|
+
[ 255, 'VARCHAR(255)' ],
|
272
|
+
[ nil, 'VARCHAR(50)' ],
|
273
|
+
].each do |length, statement|
|
274
|
+
options = {}
|
275
|
+
options[:length] = length if length
|
276
|
+
|
277
|
+
describe "with a length of #{length}" do
|
278
|
+
before :all do
|
279
|
+
@property = @model.property(:title, String, options)
|
280
|
+
|
281
|
+
@response = capture_log(DataObjects::Mysql) { @model.auto_migrate! }
|
282
|
+
end
|
283
|
+
|
284
|
+
it 'should return true' do
|
285
|
+
@response.should be(true)
|
286
|
+
end
|
287
|
+
|
288
|
+
it "should create a #{statement} column" do
|
289
|
+
@output.last.should =~ %r{\ACREATE TABLE `blog_articles` \(`id` INT\(10\) UNSIGNED NOT NULL AUTO_INCREMENT, `title` #{Regexp.escape(statement)}, PRIMARY KEY\(`id`\)\) ENGINE = InnoDB CHARACTER SET [a-z\d]+ COLLATE (?:[a-z\d](?:_?[a-z\d]+)*)\z}
|
290
|
+
end
|
291
|
+
end
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
295
|
+
describe 'NumericString property' do
|
296
|
+
before :all do
|
297
|
+
@model.property(:id, DataMapper::Property::Serial)
|
298
|
+
@model.property(:number, DataMapper::Property::NumericString)
|
299
|
+
|
300
|
+
@response = capture_log(DataObjects::Mysql) { @model.auto_migrate! }
|
301
|
+
end
|
302
|
+
|
303
|
+
it "should create a VARCHAR(50) column with a default of '0'" do
|
304
|
+
@output.last.should =~ %r{\ACREATE TABLE `blog_articles` \(`id` INT\(10\) UNSIGNED NOT NULL AUTO_INCREMENT, `number` VARCHAR\(50\) DEFAULT '0', PRIMARY KEY\(`id`\)\) ENGINE = InnoDB CHARACTER SET [a-z\d]+ COLLATE (?:[a-z\d](?:_?[a-z\d]+)*)\z}
|
305
|
+
end
|
306
|
+
end
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
supported_by :postgres do
|
311
|
+
before :all do
|
312
|
+
module ::Blog
|
313
|
+
class Article
|
314
|
+
include DataMapper::Resource
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
318
|
+
@model = ::Blog::Article
|
319
|
+
end
|
320
|
+
|
321
|
+
describe '#auto_migrate' do
|
322
|
+
describe 'Integer property' do
|
323
|
+
[
|
324
|
+
[ 0, 1, 'SMALLINT' ],
|
325
|
+
[ 0, 32767, 'SMALLINT' ],
|
326
|
+
[ 0, 32768, 'INTEGER' ],
|
327
|
+
[ 0, 2147483647, 'INTEGER' ],
|
328
|
+
[ 0, 2147483648, 'BIGINT' ],
|
329
|
+
[ 0, 9223372036854775807, 'BIGINT' ],
|
330
|
+
|
331
|
+
[ -1, 1, 'SMALLINT' ],
|
332
|
+
[ -1, 32767, 'SMALLINT' ],
|
333
|
+
[ -1, 32768, 'INTEGER' ],
|
334
|
+
[ -1, 2147483647, 'INTEGER' ],
|
335
|
+
[ -1, 2147483648, 'BIGINT' ],
|
336
|
+
[ -1, 9223372036854775807, 'BIGINT' ],
|
337
|
+
|
338
|
+
[ -1, 0, 'SMALLINT' ],
|
339
|
+
[ -32768, 0, 'SMALLINT' ],
|
340
|
+
[ -32769, 0, 'INTEGER' ],
|
341
|
+
[ -2147483648, 0, 'INTEGER' ],
|
342
|
+
[ -2147483649, 0, 'BIGINT' ],
|
343
|
+
[ -9223372036854775808, 0, 'BIGINT' ],
|
344
|
+
|
345
|
+
[ nil, 2147483647, 'INTEGER' ],
|
346
|
+
[ 0, nil, 'INTEGER' ],
|
347
|
+
[ nil, nil, 'INTEGER' ],
|
348
|
+
].each do |min, max, statement|
|
349
|
+
options = { :key => true }
|
350
|
+
options[:min] = min if min
|
351
|
+
options[:max] = max if max
|
352
|
+
|
353
|
+
describe "with a min of #{min} and a max of #{max}" do
|
354
|
+
before :all do
|
355
|
+
@property = @model.property(:id, Integer, options)
|
356
|
+
|
357
|
+
@response = capture_log(DataObjects::Postgres) { @model.auto_migrate! }
|
358
|
+
end
|
359
|
+
|
360
|
+
it 'should return true' do
|
361
|
+
@response.should be(true)
|
362
|
+
end
|
363
|
+
|
364
|
+
it "should create a #{statement} column" do
|
365
|
+
@output[-2].should == "CREATE TABLE \"blog_articles\" (\"id\" #{statement} NOT NULL, PRIMARY KEY(\"id\"))"
|
366
|
+
end
|
367
|
+
|
368
|
+
[ :min, :max ].each do |key|
|
369
|
+
next unless value = options[key]
|
370
|
+
it "should allow the #{key} value #{value} to be stored" do
|
371
|
+
pending_if "#{value} causes problem with the JRuby < 1.6 parser", RUBY_PLATFORM =~ /java/ && JRUBY_VERSION < '1.6' && value == -9223372036854775808 do
|
372
|
+
lambda {
|
373
|
+
resource = @model.create(@property => value)
|
374
|
+
@model.first(@property => value).should eql(resource)
|
375
|
+
}.should_not raise_error
|
376
|
+
end
|
377
|
+
end
|
378
|
+
end
|
379
|
+
end
|
380
|
+
end
|
381
|
+
end
|
382
|
+
|
383
|
+
describe 'Serial property' do
|
384
|
+
[
|
385
|
+
[ 1, 'SERIAL' ],
|
386
|
+
[ 2147483647, 'SERIAL' ],
|
387
|
+
[ 2147483648, 'BIGSERIAL' ],
|
388
|
+
[ 9223372036854775807, 'BIGSERIAL' ],
|
389
|
+
|
390
|
+
[ nil, 'SERIAL' ],
|
391
|
+
].each do |max, statement|
|
392
|
+
options = {}
|
393
|
+
options[:max] = max if max
|
394
|
+
|
395
|
+
describe "with a max of #{max}" do
|
396
|
+
before :all do
|
397
|
+
@property = @model.property(:id, DataMapper::Property::Serial, options)
|
398
|
+
|
399
|
+
@response = capture_log(DataObjects::Postgres) { @model.auto_migrate! }
|
400
|
+
end
|
401
|
+
|
402
|
+
it 'should return true' do
|
403
|
+
@response.should be(true)
|
404
|
+
end
|
405
|
+
|
406
|
+
it "should create a #{statement} column" do
|
407
|
+
@output[-2].should == "CREATE TABLE \"blog_articles\" (\"id\" #{statement} NOT NULL, PRIMARY KEY(\"id\"))"
|
408
|
+
end
|
409
|
+
|
410
|
+
[ :min, :max ].each do |key|
|
411
|
+
next unless value = options[key]
|
412
|
+
it "should allow the #{key} value #{value} to be stored" do
|
413
|
+
lambda {
|
414
|
+
resource = @model.create(@property => value)
|
415
|
+
@model.first(@property => value).should eql(resource)
|
416
|
+
}.should_not raise_error
|
417
|
+
end
|
418
|
+
end
|
419
|
+
end
|
420
|
+
end
|
421
|
+
end
|
422
|
+
|
423
|
+
describe 'String property' do
|
424
|
+
before :all do
|
425
|
+
@model.property(:id, DataMapper::Property::Serial)
|
426
|
+
end
|
427
|
+
|
428
|
+
[
|
429
|
+
[ 1, 'VARCHAR(1)' ],
|
430
|
+
[ 50, 'VARCHAR(50)' ],
|
431
|
+
[ 255, 'VARCHAR(255)' ],
|
432
|
+
[ nil, 'VARCHAR(50)' ],
|
433
|
+
].each do |length, statement|
|
434
|
+
options = {}
|
435
|
+
options[:length] = length if length
|
436
|
+
|
437
|
+
describe "with a length of #{length}" do
|
438
|
+
before :all do
|
439
|
+
@property = @model.property(:title, String, options)
|
440
|
+
|
441
|
+
@response = capture_log(DataObjects::Postgres) { @model.auto_migrate! }
|
442
|
+
end
|
443
|
+
|
444
|
+
it 'should return true' do
|
445
|
+
@response.should be(true)
|
446
|
+
end
|
447
|
+
|
448
|
+
it "should create a #{statement} column" do
|
449
|
+
@output[-2].should == "CREATE TABLE \"blog_articles\" (\"id\" SERIAL NOT NULL, \"title\" #{statement}, PRIMARY KEY(\"id\"))"
|
450
|
+
end
|
451
|
+
end
|
452
|
+
end
|
453
|
+
end
|
454
|
+
|
455
|
+
describe 'NumericString property' do
|
456
|
+
before :all do
|
457
|
+
@model.property(:id, DataMapper::Property::Serial)
|
458
|
+
@model.property(:number, DataMapper::Property::NumericString)
|
459
|
+
|
460
|
+
@response = capture_log(DataObjects::Postgres) { @model.auto_migrate! }
|
461
|
+
end
|
462
|
+
|
463
|
+
it "should create a VARCHAR(50) column with a default of '0'" do
|
464
|
+
@output[-2].should == "CREATE TABLE \"blog_articles\" (\"id\" SERIAL NOT NULL, \"number\" VARCHAR(50) DEFAULT '0', PRIMARY KEY(\"id\"))"
|
465
|
+
end
|
466
|
+
end
|
467
|
+
end
|
468
|
+
end
|
469
|
+
|
470
|
+
supported_by :sqlserver do
|
471
|
+
before :all do
|
472
|
+
module ::Blog
|
473
|
+
class Article
|
474
|
+
include DataMapper::Resource
|
475
|
+
end
|
476
|
+
end
|
477
|
+
|
478
|
+
@model = ::Blog::Article
|
479
|
+
end
|
480
|
+
|
481
|
+
describe '#auto_migrate' do
|
482
|
+
describe 'Integer property' do
|
483
|
+
[
|
484
|
+
[ 0, 1, 'TINYINT' ],
|
485
|
+
[ 0, 255, 'TINYINT' ],
|
486
|
+
[ 0, 256, 'SMALLINT' ],
|
487
|
+
[ 0, 32767, 'SMALLINT' ],
|
488
|
+
[ 0, 32768, 'INT' ],
|
489
|
+
[ 0, 2147483647, 'INT' ],
|
490
|
+
[ 0, 2147483648, 'BIGINT' ],
|
491
|
+
[ 0, 9223372036854775807, 'BIGINT' ],
|
492
|
+
|
493
|
+
[ -1, 1, 'SMALLINT' ],
|
494
|
+
[ -1, 255, 'SMALLINT' ],
|
495
|
+
[ -1, 256, 'SMALLINT' ],
|
496
|
+
[ -1, 32767, 'SMALLINT' ],
|
497
|
+
[ -1, 32768, 'INT' ],
|
498
|
+
[ -1, 2147483647, 'INT' ],
|
499
|
+
[ -1, 2147483648, 'BIGINT' ],
|
500
|
+
[ -1, 9223372036854775807, 'BIGINT' ],
|
501
|
+
|
502
|
+
[ -1, 0, 'SMALLINT' ],
|
503
|
+
[ -32768, 0, 'SMALLINT' ],
|
504
|
+
[ -32769, 0, 'INT' ],
|
505
|
+
[ -2147483648, 0, 'INT' ],
|
506
|
+
[ -2147483649, 0, 'BIGINT' ],
|
507
|
+
[ -9223372036854775808, 0, 'BIGINT' ],
|
508
|
+
|
509
|
+
[ nil, 2147483647, 'INT' ],
|
510
|
+
[ 0, nil, 'INT' ],
|
511
|
+
[ nil, nil, 'INTEGER' ],
|
512
|
+
].each do |min, max, statement|
|
513
|
+
options = { :key => true }
|
514
|
+
options[:min] = min if min
|
515
|
+
options[:max] = max if max
|
516
|
+
|
517
|
+
describe "with a min of #{min} and a max of #{max}" do
|
518
|
+
before :all do
|
519
|
+
@property = @model.property(:id, Integer, options)
|
520
|
+
|
521
|
+
@response = capture_log(DataObjects::Sqlserver) { @model.auto_migrate! }
|
522
|
+
end
|
523
|
+
|
524
|
+
it 'should return true' do
|
525
|
+
@response.should be(true)
|
526
|
+
end
|
527
|
+
|
528
|
+
it "should create a #{statement} column" do
|
529
|
+
@output.last.should == "CREATE TABLE \"blog_articles\" (\"id\" #{statement} NOT NULL, PRIMARY KEY(\"id\"))"
|
530
|
+
end
|
531
|
+
|
532
|
+
[ :min, :max ].each do |key|
|
533
|
+
next unless value = options[key]
|
534
|
+
it "should allow the #{key} value #{value} to be stored" do
|
535
|
+
pending_if "#{value} causes problem with JRuby 1.5.2 parser", RUBY_PLATFORM =~ /java/ && value == -9223372036854775808 do
|
536
|
+
lambda {
|
537
|
+
resource = @model.create(@property => value)
|
538
|
+
@model.first(@property => value).should eql(resource)
|
539
|
+
}.should_not raise_error
|
540
|
+
end
|
541
|
+
end
|
542
|
+
end
|
543
|
+
end
|
544
|
+
end
|
545
|
+
end
|
546
|
+
|
547
|
+
describe 'String property' do
|
548
|
+
it 'needs specs'
|
549
|
+
end
|
550
|
+
end
|
551
|
+
end
|
552
|
+
|
553
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'dm-migrations/auto_migration'
|
4
|
+
|
5
|
+
describe DataMapper::Migrations do
|
6
|
+
def capture_log(mod)
|
7
|
+
original, mod.logger = mod.logger, DataObjects::Logger.new(@log = StringIO.new, :debug)
|
8
|
+
yield
|
9
|
+
ensure
|
10
|
+
@log.rewind
|
11
|
+
@output = @log.readlines.map do |line|
|
12
|
+
line.chomp.gsub(/\A.+?~ \(\d+\.?\d*\)\s+/, '')
|
13
|
+
end
|
14
|
+
|
15
|
+
mod.logger = original
|
16
|
+
end
|
17
|
+
|
18
|
+
supported_by :postgres do
|
19
|
+
before :all do
|
20
|
+
module ::Blog
|
21
|
+
class Article
|
22
|
+
include DataMapper::Resource
|
23
|
+
|
24
|
+
property :id, Serial
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
@model = ::Blog::Article
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '#auto_upgrade' do
|
32
|
+
it 'should create an index' do
|
33
|
+
@model.auto_migrate!
|
34
|
+
@property = @model.property(:name, String, :index => true)
|
35
|
+
@response = capture_log(DataObjects::Postgres) { @model.auto_upgrade! }
|
36
|
+
@output[-2].should == "CREATE INDEX \"index_blog_articles_name\" ON \"blog_articles\" (\"name\")"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'The migration runner' do
|
4
|
+
|
5
|
+
supported_by :postgres, :mysql, :sqlite, :oracle, :sqlserver do
|
6
|
+
|
7
|
+
before(:all) do
|
8
|
+
@adapter = DataMapper::Spec.adapter
|
9
|
+
@repository = DataMapper.repository(@adapter.name)
|
10
|
+
end
|
11
|
+
|
12
|
+
describe 'empty migration runner' do
|
13
|
+
it "should return an empty array if no migrations have been defined" do
|
14
|
+
migrations.should be_kind_of(Array)
|
15
|
+
migrations.size.should == 0
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe 'migration runnner' do
|
20
|
+
# set up some 'global' setup and teardown tasks
|
21
|
+
before(:each) do
|
22
|
+
# FIXME workaround because dm-migrations can only handle the :default repo
|
23
|
+
#DataMapper::Repository.adapters[:default] = DataMapper::Repository.adapters[adapter.to_sym]
|
24
|
+
migration( 1, :create_people_table) { }
|
25
|
+
end
|
26
|
+
|
27
|
+
after(:each) do
|
28
|
+
migrations.clear
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '#migration' do
|
32
|
+
|
33
|
+
it 'should create a new migration object, and add it to the list of migrations' do
|
34
|
+
migrations.should be_kind_of(Array)
|
35
|
+
migrations.size.should == 1
|
36
|
+
migrations.first.name.should == "create_people_table"
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should allow multiple migrations to be added' do
|
40
|
+
migration( 2, :add_dob_to_people) { }
|
41
|
+
migration( 2, :add_favorite_pet_to_people) { }
|
42
|
+
migration( 3, :add_something_else_to_people) { }
|
43
|
+
migrations.size.should == 4
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'should raise an error on adding with a duplicated name' do
|
47
|
+
lambda { migration( 1, :create_people_table) { } }.should raise_error(RuntimeError, /Migration name conflict/)
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
describe '#migrate_up! and #migrate_down!' do
|
53
|
+
before(:each) do
|
54
|
+
migration( 2, :add_dob_to_people) { }
|
55
|
+
migration( 2, :add_favorite_pet_to_people) { }
|
56
|
+
migration( 3, :add_something_else_to_people) { }
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'calling migrate_up! should migrate up all the migrations' do
|
60
|
+
# add our expectation that migrate_up should be called
|
61
|
+
migrations.each do |m|
|
62
|
+
m.should_receive(:perform_up)
|
63
|
+
end
|
64
|
+
migrate_up!
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'calling migrate_up! with an arguement should only migrate to that level' do
|
68
|
+
migrations.each do |m|
|
69
|
+
if m.position <= 2
|
70
|
+
m.should_receive(:perform_up)
|
71
|
+
else
|
72
|
+
m.should_not_receive(:perform_up)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
migrate_up!(2)
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'calling migrate_down! should migrate down all the migrations' do
|
79
|
+
# add our expectation that migrate_up should be called
|
80
|
+
migrations.each do |m|
|
81
|
+
m.should_receive(:perform_down)
|
82
|
+
end
|
83
|
+
migrate_down!
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|