db2 2.5.6 → 2.5.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. data/CHANGES +17 -0
  2. data/README +79 -141
  3. data/ext/extconf.rb +75 -14
  4. metadata +32 -68
  5. data/.gitignore +0 -1
  6. data/LICENSE +0 -18
  7. data/ParameterizedQueries README +0 -39
  8. data/ext/Makefile.nt32 +0 -181
  9. data/ext/ibm_db.c +0 -11166
  10. data/ext/ruby_ibm_db.h +0 -236
  11. data/ext/ruby_ibm_db_cli.c +0 -738
  12. data/ext/ruby_ibm_db_cli.h +0 -431
  13. data/init.rb +0 -42
  14. data/lib/IBM_DB.rb +0 -2
  15. data/lib/active_record/connection_adapters/ibm_db_adapter.rb +0 -2558
  16. data/lib/active_record/connection_adapters/ibm_db_pstmt.rb +0 -1965
  17. data/lib/active_record/vendor/db2-i5-zOS.yaml +0 -328
  18. data/test/cases/adapter_test.rb +0 -202
  19. data/test/cases/associations/belongs_to_associations_test.rb +0 -486
  20. data/test/cases/associations/cascaded_eager_loading_test.rb +0 -183
  21. data/test/cases/associations/eager_test.rb +0 -862
  22. data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +0 -917
  23. data/test/cases/associations/has_many_through_associations_test.rb +0 -461
  24. data/test/cases/associations/join_model_test.rb +0 -793
  25. data/test/cases/attribute_methods_test.rb +0 -621
  26. data/test/cases/base_test.rb +0 -1486
  27. data/test/cases/calculations_test.rb +0 -362
  28. data/test/cases/finder_test.rb +0 -1088
  29. data/test/cases/fixtures_test.rb +0 -684
  30. data/test/cases/migration_test.rb +0 -2014
  31. data/test/cases/schema_dumper_test.rb +0 -232
  32. data/test/cases/validations/uniqueness_validation_test.rb +0 -283
  33. data/test/connections/native_ibm_db/connection.rb +0 -42
  34. data/test/ibm_db_test.rb +0 -25
  35. data/test/models/warehouse_thing.rb +0 -5
  36. data/test/schema/i5/ibm_db_specific_schema.rb +0 -135
  37. data/test/schema/ids/ibm_db_specific_schema.rb +0 -138
  38. data/test/schema/luw/ibm_db_specific_schema.rb +0 -135
  39. data/test/schema/schema.rb +0 -647
  40. data/test/schema/zOS/ibm_db_specific_schema.rb +0 -206
@@ -1,2014 +0,0 @@
1
- require "cases/helper"
2
- require 'bigdecimal/util'
3
-
4
- require 'models/person'
5
- require 'models/topic'
6
- require 'models/developer'
7
-
8
- require MIGRATIONS_ROOT + "/valid/1_people_have_last_names"
9
- require MIGRATIONS_ROOT + "/valid/2_we_need_reminders"
10
- require MIGRATIONS_ROOT + "/decimal/1_give_me_big_numbers"
11
- require MIGRATIONS_ROOT + "/interleaved/pass_3/2_i_raise_on_down"
12
-
13
- if ActiveRecord::Base.connection.supports_migrations?
14
- class BigNumber < ActiveRecord::Base; end
15
-
16
- class Reminder < ActiveRecord::Base; end
17
-
18
- class ActiveRecord::Migration
19
- class <<self
20
- attr_accessor :message_count
21
- def puts(text="")
22
- self.message_count ||= 0
23
- self.message_count += 1
24
- end
25
- end
26
- end
27
-
28
- class MigrationTableAndIndexTest < ActiveRecord::TestCase
29
- def test_add_schema_info_respects_prefix_and_suffix
30
- conn = ActiveRecord::Base.connection
31
-
32
- conn.drop_table(ActiveRecord::Migrator.schema_migrations_table_name) if conn.table_exists?(ActiveRecord::Migrator.schema_migrations_table_name)
33
- # Use shorter prefix and suffix as in Oracle database identifier cannot be larger than 30 characters
34
- ActiveRecord::Base.table_name_prefix = 'p_'
35
- ActiveRecord::Base.table_name_suffix = '_s'
36
- conn.drop_table(ActiveRecord::Migrator.schema_migrations_table_name) if conn.table_exists?(ActiveRecord::Migrator.schema_migrations_table_name)
37
-
38
- conn.initialize_schema_migrations_table
39
-
40
- assert_equal "p_unique_schema_migrations_s", conn.indexes(ActiveRecord::Migrator.schema_migrations_table_name)[0][:name]
41
- ensure
42
- ActiveRecord::Base.table_name_prefix = ""
43
- ActiveRecord::Base.table_name_suffix = ""
44
- end
45
- end
46
-
47
- class MigrationTest < ActiveRecord::TestCase
48
- self.use_transactional_fixtures = false
49
- if (current_adapter?(:IBM_DBAdapter))
50
- #Rename is supported only for server zOS 9 , DB2 COBRA and Informix
51
- server_type = ActiveRecord::Base.connection.servertype.class.name
52
- @ibm_db_rename_supported = server_type.include?('::IBM_DB2_LUW_COBRA') ||
53
- server_type.class.name.include?('::IBM_IDS') ||
54
- (server_type.include?('IBM_DB2_ZOS') && !server_type.include?('IBM_DB2_ZOS_8'))
55
- end
56
-
57
- fixtures :people
58
-
59
- def setup
60
- ActiveRecord::Migration.verbose = true
61
- PeopleHaveLastNames.message_count = 0
62
- end
63
-
64
- def teardown
65
- ActiveRecord::Base.connection.initialize_schema_migrations_table
66
- ActiveRecord::Base.connection.execute "DELETE FROM #{ActiveRecord::Migrator.schema_migrations_table_name}"
67
-
68
- %w(reminders people_reminders prefix_reminders_suffix).each do |table|
69
- Reminder.connection.drop_table(table) rescue nil
70
- end
71
- Reminder.reset_column_information
72
-
73
- %w(last_name key bio age height wealth birthday favorite_day
74
- moment_of_truth male administrator funny).each do |column|
75
- Person.connection.remove_column('people', column) rescue nil
76
- end
77
- Person.connection.remove_column("people", "first_name") rescue nil
78
- Person.connection.remove_column("people", "middle_name") rescue nil
79
- Person.connection.add_column("people", "first_name", :string, :limit => 40)
80
- Person.reset_column_information
81
- end
82
-
83
- def test_add_index
84
- # Limit size of last_name and key columns to support Firebird index limitations
85
- Person.connection.add_column "people", "last_name", :string, :limit => 100
86
- Person.connection.add_column "people", "key", :string, :limit => 100
87
- Person.connection.add_column "people", "administrator", :boolean
88
-
89
- assert_nothing_raised { Person.connection.add_index("people", "last_name") }
90
- assert_nothing_raised { Person.connection.remove_index("people", "last_name") }
91
-
92
- # Orcl nds shrt indx nms. Sybs 2.
93
- # OpenBase does not have named indexes. You must specify a single column name
94
- unless current_adapter?(:SybaseAdapter, :OpenBaseAdapter)
95
- assert_nothing_raised { Person.connection.add_index("people", ["last_name", "first_name"]) }
96
- assert_nothing_raised { Person.connection.remove_index("people", :column => ["last_name", "first_name"]) }
97
- # Oracle adapter cannot have specified index name larger than 30 characters
98
- # Oracle adapter is shortening index name when just column list is given
99
- unless current_adapter?(:OracleAdapter)
100
- assert_nothing_raised { Person.connection.add_index("people", ["last_name", "first_name"]) }
101
- assert_nothing_raised { Person.connection.remove_index("people", :name => :index_people_on_last_name_and_first_name) }
102
- assert_nothing_raised { Person.connection.add_index("people", ["last_name", "first_name"]) }
103
- assert_nothing_raised { Person.connection.remove_index("people", "last_name_and_first_name") }
104
- end
105
- assert_nothing_raised { Person.connection.add_index("people", ["last_name", "first_name"]) }
106
- assert_nothing_raised { Person.connection.remove_index("people", ["last_name", "first_name"]) }
107
- assert_nothing_raised { Person.connection.add_index("people", ["last_name"], :length => 10) }
108
- assert_nothing_raised { Person.connection.remove_index("people", "last_name") }
109
- assert_nothing_raised { Person.connection.add_index("people", ["last_name"], :length => {:last_name => 10}) }
110
- assert_nothing_raised { Person.connection.remove_index("people", ["last_name"]) }
111
- assert_nothing_raised { Person.connection.add_index("people", ["last_name", "first_name"], :length => 10) }
112
- assert_nothing_raised { Person.connection.remove_index("people", ["last_name", "first_name"]) }
113
- assert_nothing_raised { Person.connection.add_index("people", ["last_name", "first_name"], :length => {:last_name => 10, :first_name => 20}) }
114
- assert_nothing_raised { Person.connection.remove_index("people", ["last_name", "first_name"]) }
115
- end
116
-
117
- # quoting
118
- # Note: changed index name from "key" to "key_idx" since "key" is a Firebird reserved word
119
- # OpenBase does not have named indexes. You must specify a single column name
120
- unless current_adapter?(:OpenBaseAdapter)
121
- unless current_adapter?(:IBM_DBAdapter) #cannot assign a integer value to string column
122
- Person.update_all "#{Person.connection.quote_column_name 'key'}=#{Person.connection.quote_column_name 'id'}" #some databases (including sqlite2 won't add a unique index if existing data non unique)
123
- else
124
- Person.update_all "#{Person.connection.quote_column_name 'key'}=#{Person.connection.quote_column_name 'first_name'}"
125
- end
126
- assert_nothing_raised { Person.connection.add_index("people", ["key"], :name => "key_idx", :unique => true) }
127
- assert_nothing_raised { Person.connection.remove_index("people", :name => "key_idx", :unique => true) }
128
- end
129
-
130
- # Sybase adapter does not support indexes on :boolean columns
131
- # OpenBase does not have named indexes. You must specify a single column
132
- unless current_adapter?(:SybaseAdapter, :OpenBaseAdapter)
133
- assert_nothing_raised { Person.connection.add_index("people", %w(last_name first_name administrator), :name => "named_admin") }
134
- assert_nothing_raised { Person.connection.remove_index("people", :name => "named_admin") }
135
- end
136
- end
137
-
138
- def test_index_symbol_names
139
- assert_nothing_raised { Person.connection.add_index :people, :primary_contact_id, :name => :symbol_index_name }
140
- assert Person.connection.index_exists?(:people, :primary_contact_id, :name => :symbol_index_name)
141
- assert_nothing_raised { Person.connection.remove_index :people, :name => :symbol_index_name }
142
- assert !Person.connection.index_exists?(:people, :primary_contact_id, :name => :symbol_index_name)
143
- end
144
-
145
- def test_add_index_length_limit
146
- good_index_name = 'x' * Person.connection.index_name_length
147
- too_long_index_name = good_index_name + 'x'
148
- assert_raise(ArgumentError) { Person.connection.add_index("people", "first_name", :name => too_long_index_name) }
149
- assert !Person.connection.index_name_exists?("people", too_long_index_name, false)
150
- assert_nothing_raised { Person.connection.add_index("people", "first_name", :name => good_index_name) }
151
- assert Person.connection.index_name_exists?("people", good_index_name, false)
152
- Person.connection.remove_index("people", :name => good_index_name)
153
- end
154
-
155
- def test_remove_nonexistent_index
156
- # we do this by name, so OpenBase is a wash as noted above
157
- unless current_adapter?(:OpenBaseAdapter)
158
- assert_raise(ArgumentError) { Person.connection.remove_index("people", "no_such_index") }
159
- end
160
- end
161
-
162
- def test_rename_index
163
- unless current_adapter?(:OpenBaseAdapter)
164
- # keep the names short to make Oracle and similar behave
165
- Person.connection.add_index('people', [:first_name], :name => 'old_idx')
166
- assert_nothing_raised { Person.connection.rename_index('people', 'old_idx', 'new_idx') }
167
- # if the adapter doesn't support the indexes call, pick defaults that let the test pass
168
- assert !Person.connection.index_name_exists?('people', 'old_idx', false)
169
- assert Person.connection.index_name_exists?('people', 'new_idx', true)
170
- end
171
- end
172
-
173
- def test_double_add_index
174
- unless current_adapter?(:OpenBaseAdapter)
175
- Person.connection.add_index('people', [:first_name], :name => 'some_idx')
176
- assert_raise(ArgumentError) { Person.connection.add_index('people', [:first_name], :name => 'some_idx') }
177
- end
178
- end
179
-
180
- def test_index_exists
181
- Person.connection.create_table :testings do |t|
182
- t.column :foo, :string, :limit => 100
183
- t.column :bar, :string, :limit => 100
184
- end
185
- Person.connection.add_index :testings, :foo
186
-
187
- assert Person.connection.index_exists?(:testings, :foo)
188
- assert !Person.connection.index_exists?(:testings, :bar)
189
- ensure
190
- Person.connection.drop_table :testings rescue nil
191
- end
192
-
193
- def test_index_exists_on_multiple_columns
194
- Person.connection.create_table :testings do |t|
195
- t.column :foo, :string, :limit => 100
196
- t.column :bar, :string, :limit => 100
197
- end
198
- Person.connection.add_index :testings, [:foo, :bar]
199
-
200
- assert Person.connection.index_exists?(:testings, [:foo, :bar])
201
- ensure
202
- Person.connection.drop_table :testings rescue nil
203
- end
204
-
205
- def test_unique_index_exists
206
- Person.connection.create_table :testings do |t|
207
- t.column :foo, :string, :limit => 100
208
- end
209
- Person.connection.add_index :testings, :foo, :unique => true
210
-
211
- assert Person.connection.index_exists?(:testings, :foo, :unique => true)
212
- ensure
213
- Person.connection.drop_table :testings rescue nil
214
- end
215
-
216
- def test_named_index_exists
217
- Person.connection.create_table :testings do |t|
218
- t.column :foo, :string, :limit => 100
219
- end
220
- Person.connection.add_index :testings, :foo, :name => "custom_index_name"
221
-
222
- assert Person.connection.index_exists?(:testings, :foo, :name => "custom_index_name")
223
- ensure
224
- Person.connection.drop_table :testings rescue nil
225
- end
226
-
227
- def testing_table_with_only_foo_attribute
228
- Person.connection.create_table :testings, :id => false do |t|
229
- t.column :foo, :string
230
- end
231
-
232
- yield Person.connection
233
- ensure
234
- Person.connection.drop_table :testings rescue nil
235
- end
236
- protected :testing_table_with_only_foo_attribute
237
-
238
- def test_create_table_without_id
239
- testing_table_with_only_foo_attribute do |connection|
240
- assert_equal connection.columns(:testings).size, 1
241
- end
242
- end
243
-
244
- unless current_adapter?(:IBM_DBAdapter)
245
- # Cannot add a primary key to a table with some rows already in it as it violates the unique constraint
246
- # Secondly GENERATED BY DEFAULT AS IDENTITY cannot be applied in a alter table command.
247
- # as this will be wrong sql syntax for DB2
248
- def test_add_column_with_primary_key_attribute
249
- testing_table_with_only_foo_attribute do |connection|
250
- assert_nothing_raised { connection.add_column :testings, :id, :primary_key }
251
- assert_equal connection.columns(:testings).size, 2
252
- end
253
- end
254
- end
255
-
256
- def test_create_table_adds_id
257
- Person.connection.create_table :testings do |t|
258
- t.column :foo, :string
259
- end
260
-
261
- assert_equal %w(foo id),
262
- Person.connection.columns(:testings).map { |c| c.name }.sort
263
- ensure
264
- Person.connection.drop_table :testings rescue nil
265
- end
266
-
267
- def test_create_table_with_not_null_column
268
- assert_nothing_raised do
269
- Person.connection.create_table :testings do |t|
270
- t.column :foo, :string, :null => false
271
- end
272
- end
273
-
274
- assert_raise(ActiveRecord::StatementInvalid) do
275
- Person.connection.execute "insert into testings (foo) values (NULL)"
276
- end
277
- ensure
278
- Person.connection.drop_table :testings rescue nil
279
- end
280
-
281
- def test_create_table_with_defaults
282
- # MySQL doesn't allow defaults on TEXT or BLOB columns.
283
- mysql = current_adapter?(:MysqlAdapter)
284
- ibm_ids_zOS = ActiveRecord::Base.connection.servertype.class.name.include?('::IBM_IDS')||
285
- ActiveRecord::Base.connection.servertype.class.name.include?('::IBM_DB2_ZOS')
286
-
287
- Person.connection.create_table :testings do |t|
288
- t.column :one, :string, :default => "hello"
289
- t.column :two, :boolean, :default => true
290
- t.column :three, :boolean, :default => false
291
- t.column :four, :integer, :default => 1
292
- t.column :five, :text, :default => "hello" unless mysql || ibm_ids_zOS
293
- end
294
-
295
- columns = Person.connection.columns(:testings)
296
- one = columns.detect { |c| c.name == "one" }
297
- two = columns.detect { |c| c.name == "two" }
298
- three = columns.detect { |c| c.name == "three" }
299
- four = columns.detect { |c| c.name == "four" }
300
- five = columns.detect { |c| c.name == "five" } unless mysql || ibm_ids_zOS
301
-
302
- assert_equal "hello", one.default
303
- assert_equal true, two.default
304
- assert_equal false, three.default
305
- assert_equal 1, four.default
306
- assert_equal "hello", five.default unless mysql || ibm_ids_zOS
307
-
308
- ensure
309
- Person.connection.drop_table :testings rescue nil
310
- end
311
-
312
- if current_adapter?(:IBM_DBAdapter)
313
- def test_no_limits_datatypes_IBM_DB
314
- ibm_ids = ActiveRecord::Base.connection.servertype.class.name.include?('::IBM_IDS')
315
- clasz = Class.new(ActiveRecord::Base)
316
- clasz.table_name = 'test_no_limits_datatypes_IBM_DB'
317
- assert_nothing_raised do
318
- clasz.connection.create_table clasz.table_name do |t|
319
- t.column "test_varchar", :string, :limit => 10
320
- t.column "test_integer", :integer, :limit => 5
321
- t.column "test_boolean", :boolean, :limit => 5
322
- t.column "test_double", :double, :limit => 10
323
- t.column "test_date", :date, :limit => 10
324
- t.column "test_time", :time, :limit => 10
325
- t.column "test_tstamp", :timestamp, :limit => 10
326
- t.column "test_xml", :xml, :limit => 10 unless ibm_ids
327
- t.column "test_clob", :text, :limit => 10000
328
- t.column "test_decfloat", :decfloat, :limit => 100
329
- end
330
- end
331
- ensure
332
- clasz.connection.drop_table(clasz.table_name) rescue nil
333
- end
334
-
335
- #Sexy migration test for column of type xml and char
336
- def test_short_hand_migrations_for_ibm_db_datatypes
337
- ibm_ids = ActiveRecord::Base.connection.servertype.class.name.include?('::IBM_IDS')
338
- clasz = Class.new(ActiveRecord::Base)
339
- clasz.table_name = 'test_short_hand_migrations'
340
- assert_nothing_raised do
341
- clasz.connection.create_table clasz.table_name do |t|
342
- t.xml :xml_col unless ibm_ids
343
- t.char :char_col, :limit=>10
344
- t.decfloat :dec_col, :precision=>16
345
- end
346
- end
347
- assert_nothing_raised do
348
- clasz.connection.change_table clasz.table_name do |t|
349
- t.xml :xml_col1 unless ibm_ids
350
- t.char :char_col1, :limit=>50
351
- t.decfloat :dec_col1, :precision=>34
352
- end
353
- end
354
- ensure
355
- clasz.connection.drop_table(clasz.table_name) rescue nil
356
- end
357
- end
358
-
359
- def test_create_table_with_limits
360
- assert_nothing_raised do
361
- Person.connection.create_table :testings do |t|
362
- t.column :foo, :string, :limit => 255
363
-
364
- t.column :default_int, :integer
365
-
366
- t.column :one_int, :integer, :limit => 1
367
- t.column :four_int, :integer, :limit => 4
368
- t.column :eight_int, :integer, :limit => 8
369
- t.column :eleven_int, :integer, :limit => 11
370
- end
371
- end
372
-
373
- columns = Person.connection.columns(:testings)
374
- foo = columns.detect { |c| c.name == "foo" }
375
- assert_equal 255, foo.limit
376
-
377
- default = columns.detect { |c| c.name == "default_int" }
378
- one = columns.detect { |c| c.name == "one_int" }
379
- four = columns.detect { |c| c.name == "four_int" }
380
- eight = columns.detect { |c| c.name == "eight_int" }
381
- eleven = columns.detect { |c| c.name == "eleven_int" }
382
-
383
- if current_adapter?(:PostgreSQLAdapter)
384
- assert_equal 'integer', default.sql_type
385
- assert_equal 'smallint', one.sql_type
386
- assert_equal 'integer', four.sql_type
387
- assert_equal 'bigint', eight.sql_type
388
- assert_equal 'integer', eleven.sql_type
389
- elsif current_adapter?(:MysqlAdapter) or current_adapter?(:Mysql2Adapter)
390
- assert_match 'int(11)', default.sql_type
391
- assert_match 'tinyint', one.sql_type
392
- assert_match 'int', four.sql_type
393
- assert_match 'bigint', eight.sql_type
394
- assert_match 'int(11)', eleven.sql_type
395
- elsif current_adapter?(:OracleAdapter)
396
- assert_equal 'NUMBER(38)', default.sql_type
397
- assert_equal 'NUMBER(1)', one.sql_type
398
- assert_equal 'NUMBER(4)', four.sql_type
399
- assert_equal 'NUMBER(8)', eight.sql_type
400
- end
401
- ensure
402
- Person.connection.drop_table :testings rescue nil
403
- end
404
-
405
- def test_create_table_with_primary_key_prefix_as_table_name_with_underscore
406
- ActiveRecord::Base.primary_key_prefix_type = :table_name_with_underscore
407
-
408
- Person.connection.create_table :testings do |t|
409
- t.column :foo, :string
410
- end
411
-
412
- assert_equal %w(foo testing_id), Person.connection.columns(:testings).map { |c| c.name }.sort
413
- ensure
414
- Person.connection.drop_table :testings rescue nil
415
- ActiveRecord::Base.primary_key_prefix_type = nil
416
- end
417
-
418
- def test_create_table_with_primary_key_prefix_as_table_name
419
- ActiveRecord::Base.primary_key_prefix_type = :table_name
420
-
421
- Person.connection.create_table :testings do |t|
422
- t.column :foo, :string
423
- end
424
-
425
- assert_equal %w(foo testingid), Person.connection.columns(:testings).map { |c| c.name }.sort
426
- ensure
427
- Person.connection.drop_table :testings rescue nil
428
- ActiveRecord::Base.primary_key_prefix_type = nil
429
- end
430
-
431
- def test_create_table_with_force_true_does_not_drop_nonexisting_table
432
- if Person.connection.table_exists?(:testings2)
433
- Person.connection.drop_table :testings2
434
- end
435
-
436
- # using a copy as we need the drop_table method to
437
- # continue to work for the ensure block of the test
438
- temp_conn = Person.connection.dup
439
- temp_conn.expects(:drop_table).never
440
- temp_conn.create_table :testings2, :force => true do |t|
441
- t.column :foo, :string
442
- end
443
- ensure
444
- Person.connection.drop_table :testings2 rescue nil
445
- end
446
-
447
- def test_create_table_with_timestamps_should_create_datetime_columns
448
- table_name = :testings
449
-
450
- Person.connection.create_table table_name do |t|
451
- t.timestamps
452
- end
453
- created_columns = Person.connection.columns(table_name)
454
-
455
- created_at_column = created_columns.detect {|c| c.name == 'created_at' }
456
- updated_at_column = created_columns.detect {|c| c.name == 'updated_at' }
457
-
458
- assert created_at_column.null
459
- assert updated_at_column.null
460
- ensure
461
- Person.connection.drop_table table_name rescue nil
462
- end
463
-
464
- def test_create_table_with_timestamps_should_create_datetime_columns_with_options
465
- table_name = :testings
466
-
467
- Person.connection.create_table table_name do |t|
468
- t.timestamps :null => false
469
- end
470
- created_columns = Person.connection.columns(table_name)
471
-
472
- created_at_column = created_columns.detect {|c| c.name == 'created_at' }
473
- updated_at_column = created_columns.detect {|c| c.name == 'updated_at' }
474
-
475
- assert !created_at_column.null
476
- assert !updated_at_column.null
477
- ensure
478
- Person.connection.drop_table table_name rescue nil
479
- end
480
-
481
- def test_create_table_without_a_block
482
- table_name = :testings
483
- Person.connection.create_table table_name
484
- ensure
485
- Person.connection.drop_table table_name rescue nil
486
- end
487
-
488
- # Sybase, and SQLite3 will not allow you to add a NOT NULL
489
- # column to a table without a default value.
490
- unless current_adapter?(:SybaseAdapter, :SQLiteAdapter, :IBM_DBAdapter)
491
- def test_add_column_not_null_without_default
492
- Person.connection.create_table :testings do |t|
493
- t.column :foo, :string
494
- end
495
- Person.connection.add_column :testings, :bar, :string, :null => false
496
-
497
- assert_raise(ActiveRecord::StatementInvalid) do
498
- Person.connection.execute "insert into testings (foo, bar) values ('hello', NULL)"
499
- end
500
- ensure
501
- Person.connection.drop_table :testings rescue nil
502
- end
503
- end
504
-
505
- def test_add_column_not_null_with_default
506
- Person.connection.create_table :testings do |t|
507
- t.column :foo, :string
508
- end
509
-
510
- con = Person.connection
511
- Person.connection.enable_identity_insert("testings", true) if current_adapter?(:SybaseAdapter)
512
- Person.connection.execute "insert into testings (#{con.quote_column_name('id')}, #{con.quote_column_name('foo')}) values (1, 'hello')"
513
- Person.connection.enable_identity_insert("testings", false) if current_adapter?(:SybaseAdapter)
514
- assert_nothing_raised {Person.connection.add_column :testings, :bar, :string, :null => false, :default => "default" }
515
-
516
- assert_raise(ActiveRecord::StatementInvalid) do
517
- unless current_adapter?(:OpenBaseAdapter)
518
- Person.connection.execute "insert into testings (#{con.quote_column_name('id')}, #{con.quote_column_name('foo')}, #{con.quote_column_name('bar')}) values (2, 'hello', NULL)"
519
- else
520
- Person.connection.insert("INSERT INTO testings (#{con.quote_column_name('id')}, #{con.quote_column_name('foo')}, #{con.quote_column_name('bar')}) VALUES (2, 'hello', NULL)",
521
- "Testing Insert","id",2)
522
- end
523
- end
524
- ensure
525
- Person.connection.drop_table :testings rescue nil
526
- end
527
-
528
- # We specifically do a manual INSERT here, and then test only the SELECT
529
- # functionality. This allows us to more easily catch INSERT being broken,
530
- # but SELECT actually working fine.
531
- def test_native_decimal_insert_manual_vs_automatic
532
- correct_value = '0012345678901234567890.0123456789'.to_d
533
-
534
- Person.delete_all
535
- Person.connection.add_column "people", "wealth", :decimal, :precision => '30', :scale => '10'
536
- Person.reset_column_information
537
-
538
- # Do a manual insertion
539
- if current_adapter?(:OracleAdapter)
540
- Person.connection.execute "insert into people (id, wealth) values (people_seq.nextval, 12345678901234567890.0123456789)"
541
- elsif current_adapter?(:OpenBaseAdapter) || (current_adapter?(:MysqlAdapter) && Mysql.client_version < 50003) #before mysql 5.0.3 decimals stored as strings
542
- Person.connection.execute "insert into people (wealth) values ('12345678901234567890.0123456789')"
543
- else
544
- Person.connection.execute "insert into people (wealth) values (12345678901234567890.0123456789)"
545
- end
546
-
547
- # SELECT
548
- row = Person.find(:first)
549
- assert_kind_of BigDecimal, row.wealth
550
-
551
- # If this assert fails, that means the SELECT is broken!
552
- unless current_adapter?(:SQLite3Adapter)
553
- assert_equal correct_value, row.wealth
554
- end
555
-
556
- # Reset to old state
557
- Person.delete_all
558
-
559
- # Now use the Rails insertion
560
- assert_nothing_raised { Person.create :wealth => BigDecimal.new("12345678901234567890.0123456789") }
561
-
562
- # SELECT
563
- row = Person.find(:first)
564
- assert_kind_of BigDecimal, row.wealth
565
-
566
- # If these asserts fail, that means the INSERT (create function, or cast to SQL) is broken!
567
- unless current_adapter?(:SQLite3Adapter)
568
- assert_equal correct_value, row.wealth
569
- end
570
-
571
- # Reset to old state
572
- Person.connection.del_column "people", "wealth" rescue nil
573
- Person.reset_column_information
574
- end
575
-
576
- def test_add_column_with_precision_and_scale
577
- Person.connection.add_column 'people', 'wealth', :decimal, :precision => 9, :scale => 7
578
- Person.reset_column_information
579
-
580
- wealth_column = Person.columns_hash['wealth']
581
- assert_equal 9, wealth_column.precision
582
- assert_equal 7, wealth_column.scale
583
- end
584
-
585
- def test_native_types
586
- Person.delete_all
587
- Person.connection.add_column "people", "last_name", :string
588
- Person.connection.add_column "people", "bio", :text
589
- Person.connection.add_column "people", "age", :integer
590
- Person.connection.add_column "people", "height", :float
591
- Person.connection.add_column "people", "wealth", :decimal, :precision => '30', :scale => '10'
592
- Person.connection.add_column "people", "birthday", :datetime
593
- Person.connection.add_column "people", "favorite_day", :date
594
- Person.connection.add_column "people", "moment_of_truth", :datetime
595
- Person.connection.add_column "people", "male", :boolean
596
- Person.reset_column_information
597
-
598
- assert_nothing_raised do
599
- Person.create :first_name => 'bob', :last_name => 'bobsen',
600
- :bio => "I was born ....", :age => 18, :height => 1.78,
601
- :wealth => BigDecimal.new("12345678901234567890.0123456789"),
602
- :birthday => 18.years.ago, :favorite_day => 10.days.ago,
603
- :moment_of_truth => "1782-10-10 21:40:18", :male => true
604
- end
605
-
606
- bob = Person.find(:first)
607
- assert_equal 'bob', bob.first_name
608
- assert_equal 'bobsen', bob.last_name
609
- assert_equal "I was born ....", bob.bio
610
- assert_equal 18, bob.age
611
-
612
- # Test for 30 significent digits (beyond the 16 of float), 10 of them
613
- # after the decimal place.
614
-
615
- unless current_adapter?(:SQLite3Adapter)
616
- assert_equal BigDecimal.new("0012345678901234567890.0123456789"), bob.wealth
617
- end
618
-
619
- assert_equal true, bob.male?
620
-
621
- assert_equal String, bob.first_name.class
622
- assert_equal String, bob.last_name.class
623
- assert_equal String, bob.bio.class
624
- assert_equal Fixnum, bob.age.class
625
- assert_equal Time, bob.birthday.class
626
-
627
- if current_adapter?(:OracleAdapter, :SybaseAdapter)
628
- # Sybase, and Oracle don't differentiate between date/time
629
- assert_equal Time, bob.favorite_day.class
630
- else
631
- assert_equal Date, bob.favorite_day.class
632
- end
633
-
634
- # Oracle adapter stores Time or DateTime with timezone value already in _before_type_cast column
635
- # therefore no timezone change is done afterwards when default timezone is changed
636
- unless current_adapter?(:OracleAdapter)
637
- # Test DateTime column and defaults, including timezone.
638
- # FIXME: moment of truth may be Time on 64-bit platforms.
639
- if bob.moment_of_truth.is_a?(DateTime)
640
-
641
- with_env_tz 'US/Eastern' do
642
- bob.reload
643
- assert_equal DateTime.local_offset, bob.moment_of_truth.offset
644
- assert_not_equal 0, bob.moment_of_truth.offset
645
- assert_not_equal "Z", bob.moment_of_truth.zone
646
- # US/Eastern is -5 hours from GMT
647
- assert_equal Rational(-5, 24), bob.moment_of_truth.offset
648
- assert_match(/\A-05:?00\Z/, bob.moment_of_truth.zone) #ruby 1.8.6 uses HH:MM, prior versions use HHMM
649
- assert_equal DateTime::ITALY, bob.moment_of_truth.start
650
- end
651
- end
652
- end
653
-
654
- assert_instance_of TrueClass, bob.male?
655
- assert_kind_of BigDecimal, bob.wealth
656
- end
657
-
658
- if current_adapter?(:MysqlAdapter) or current_adapter?(:Mysql2Adapter)
659
- def test_unabstracted_database_dependent_types
660
- Person.delete_all
661
-
662
- ActiveRecord::Migration.add_column :people, :intelligence_quotient, :tinyint
663
- Person.reset_column_information
664
- assert_match(/tinyint/, Person.columns_hash['intelligence_quotient'].sql_type)
665
- ensure
666
- ActiveRecord::Migration.remove_column :people, :intelligence_quotient rescue nil
667
- end
668
- end
669
-
670
- def test_add_remove_single_field_using_string_arguments
671
- assert !Person.column_methods_hash.include?(:last_name)
672
-
673
- ActiveRecord::Migration.add_column 'people', 'last_name', :string
674
-
675
- Person.reset_column_information
676
- assert Person.column_methods_hash.include?(:last_name)
677
-
678
- ActiveRecord::Migration.remove_column 'people', 'last_name'
679
-
680
- Person.reset_column_information
681
- assert !Person.column_methods_hash.include?(:last_name)
682
- end
683
-
684
- def test_add_remove_single_field_using_symbol_arguments
685
- assert !Person.column_methods_hash.include?(:last_name)
686
-
687
- ActiveRecord::Migration.add_column :people, :last_name, :string
688
-
689
- Person.reset_column_information
690
- assert Person.column_methods_hash.include?(:last_name)
691
-
692
- ActiveRecord::Migration.remove_column :people, :last_name
693
-
694
- Person.reset_column_information
695
- assert !Person.column_methods_hash.include?(:last_name)
696
- end
697
-
698
- if current_adapter?(:MysqlAdapter) or current_adapter?(:Mysql2Adapter)
699
- def testing_table_for_positioning
700
- Person.connection.create_table :testings, :id => false do |t|
701
- t.column :first, :integer
702
- t.column :second, :integer
703
- t.column :third, :integer
704
- end
705
-
706
- yield Person.connection
707
- ensure
708
- Person.connection.drop_table :testings rescue nil
709
- end
710
- protected :testing_table_for_positioning
711
-
712
- def test_column_positioning
713
- testing_table_for_positioning do |conn|
714
- assert_equal %w(first second third), conn.columns(:testings).map {|c| c.name }
715
- end
716
- end
717
-
718
- def test_add_column_with_positioning
719
- testing_table_for_positioning do |conn|
720
- conn.add_column :testings, :new_col, :integer
721
- assert_equal %w(first second third new_col), conn.columns(:testings).map {|c| c.name }
722
- end
723
- testing_table_for_positioning do |conn|
724
- conn.add_column :testings, :new_col, :integer, :first => true
725
- assert_equal %w(new_col first second third), conn.columns(:testings).map {|c| c.name }
726
- end
727
- testing_table_for_positioning do |conn|
728
- conn.add_column :testings, :new_col, :integer, :after => :first
729
- assert_equal %w(first new_col second third), conn.columns(:testings).map {|c| c.name }
730
- end
731
- end
732
-
733
- def test_change_column_with_positioning
734
- testing_table_for_positioning do |conn|
735
- conn.change_column :testings, :second, :integer, :first => true
736
- assert_equal %w(second first third), conn.columns(:testings).map {|c| c.name }
737
- end
738
- testing_table_for_positioning do |conn|
739
- conn.change_column :testings, :second, :integer, :after => :third
740
- assert_equal %w(first third second), conn.columns(:testings).map {|c| c.name }
741
- end
742
- end
743
- end
744
-
745
- if (!current_adapter?(:IBM_DBAdapter) || @ibm_db_rename_supported)
746
- def test_add_rename
747
- Person.delete_all
748
-
749
- begin
750
- Person.connection.add_column "people", "girlfriend", :string
751
- Person.reset_column_information
752
- Person.create :girlfriend => 'bobette'
753
-
754
- Person.connection.rename_column "people", "girlfriend", "exgirlfriend"
755
-
756
- Person.reset_column_information
757
- bob = Person.find(:first)
758
-
759
- assert_equal "bobette", bob.exgirlfriend
760
- ensure
761
- Person.connection.remove_column("people", "girlfriend") rescue nil
762
- Person.connection.remove_column("people", "exgirlfriend") rescue nil
763
- end
764
-
765
- end
766
-
767
- def test_rename_column_using_symbol_arguments
768
- begin
769
- names_before = Person.find(:all).map(&:first_name)
770
- Person.connection.rename_column :people, :first_name, :nick_name
771
- Person.reset_column_information
772
- assert Person.column_names.include?("nick_name")
773
- assert_equal names_before, Person.find(:all).map(&:nick_name)
774
- ensure
775
- Person.connection.remove_column("people","nick_name")
776
- Person.connection.add_column("people","first_name", :string)
777
- end
778
- end
779
-
780
- def test_rename_column
781
- begin
782
- names_before = Person.find(:all).map(&:first_name)
783
- Person.connection.rename_column "people", "first_name", "nick_name"
784
- Person.reset_column_information
785
- assert Person.column_names.include?("nick_name")
786
- assert_equal names_before, Person.find(:all).map(&:nick_name)
787
- ensure
788
- Person.connection.remove_column("people","nick_name")
789
- Person.connection.add_column("people","first_name", :string)
790
- end
791
- end
792
-
793
- def test_rename_column_preserves_default_value_not_null
794
- begin
795
- default_before = Developer.connection.columns("developers").find { |c| c.name == "salary" }.default
796
- assert_equal 70000, default_before
797
- Developer.connection.rename_column "developers", "salary", "anual_salary"
798
- Developer.reset_column_information
799
- assert Developer.column_names.include?("anual_salary")
800
- default_after = Developer.connection.columns("developers").find { |c| c.name == "anual_salary" }.default
801
- assert_equal 70000, default_after
802
- ensure
803
- Developer.connection.rename_column "developers", "anual_salary", "salary"
804
- Developer.reset_column_information
805
- end
806
- end
807
-
808
- def test_rename_nonexistent_column
809
- ActiveRecord::Base.connection.create_table(:hats) do |table|
810
- table.column :hat_name, :string, :default => nil
811
- end
812
- exception = if current_adapter?(:PostgreSQLAdapter)
813
- ActiveRecord::StatementInvalid
814
- else
815
- ActiveRecord::ActiveRecordError
816
- end
817
- assert_raise(exception) do
818
- Person.connection.rename_column "hats", "nonexistent", "should_fail"
819
- end
820
- ensure
821
- ActiveRecord::Base.connection.drop_table(:hats)
822
- end
823
-
824
- def test_rename_column_with_sql_reserved_word
825
- begin
826
- assert_nothing_raised { Person.connection.rename_column "people", "first_name", "group" }
827
- Person.reset_column_information
828
- assert Person.column_names.include?("group")
829
- ensure
830
- Person.connection.remove_column("people", "group") rescue nil
831
- Person.connection.add_column("people", "first_name", :string) rescue nil
832
- end
833
- end
834
- end
835
-
836
- unless (current_adapter?(:IBM_DBAdapter)) #Cannot alter a object when there is another object depending on it
837
- def test_rename_column_with_an_index
838
- ActiveRecord::Base.connection.create_table(:hats) do |table|
839
- table.column :hat_name, :string, :limit => 100
840
- table.column :hat_size, :integer
841
- end
842
- Person.connection.add_index :hats, :hat_name
843
- assert_nothing_raised do
844
- Person.connection.rename_column "hats", "hat_name", "name"
845
- end
846
- ensure
847
- ActiveRecord::Base.connection.drop_table(:hats)
848
- end
849
- end
850
-
851
- def test_rename_column_with_an_index
852
- ActiveRecord::Base.connection.create_table(:hats) do |table|
853
- table.column :hat_name, :string, :limit => 100
854
- table.column :hat_size, :integer
855
- end
856
- Person.connection.add_index :hats, :hat_name
857
- assert_nothing_raised do
858
- Person.connection.rename_column "hats", "hat_name", "name"
859
- end
860
- ensure
861
- ActiveRecord::Base.connection.drop_table(:hats)
862
- end
863
-
864
- def test_remove_column_with_index
865
- ActiveRecord::Base.connection.create_table(:hats) do |table|
866
- table.column :hat_name, :string, :limit => 100
867
- table.column :hat_size, :integer
868
- end
869
- ActiveRecord::Base.connection.add_index "hats", "hat_size"
870
-
871
- assert_nothing_raised { Person.connection.remove_column("hats", "hat_size") }
872
- ensure
873
- ActiveRecord::Base.connection.drop_table(:hats)
874
- end
875
-
876
- unless (current_adapter?(:IBM_DBAdapter)) #Cannot alter a object when there is another object depending on it
877
- def test_remove_column_with_multi_column_index
878
- ActiveRecord::Base.connection.create_table(:hats) do |table|
879
- table.column :hat_name, :string, :limit => 100
880
- table.column :hat_size, :integer
881
- table.column :hat_style, :string, :limit => 100
882
- end
883
- ActiveRecord::Base.connection.add_index "hats", ["hat_style", "hat_size"], :unique => true
884
-
885
- assert_nothing_raised { Person.connection.remove_column("hats", "hat_size") }
886
- ensure
887
- ActiveRecord::Base.connection.drop_table(:hats)
888
- end
889
- end
890
-
891
- unless current_adapter?(:IBM_DBAdapter) #incompatible types changes
892
- def test_change_type_of_not_null_column
893
- assert_nothing_raised do
894
- Topic.connection.change_column "topics", "written_on", :datetime, :null => false
895
- Topic.reset_column_information
896
-
897
- Topic.connection.change_column "topics", "written_on", :datetime, :null => false
898
- Topic.reset_column_information
899
- end
900
- end
901
- end
902
-
903
- if current_adapter?(:SQLiteAdapter)
904
- def test_rename_table_for_sqlite_should_work_with_reserved_words
905
- begin
906
- assert_nothing_raised do
907
- ActiveRecord::Base.connection.rename_table :references, :old_references
908
- ActiveRecord::Base.connection.create_table :octopuses do |t|
909
- t.column :url, :string
910
- end
911
- end
912
-
913
- assert_nothing_raised { ActiveRecord::Base.connection.rename_table :octopuses, :references }
914
-
915
- # Using explicit id in insert for compatibility across all databases
916
- con = ActiveRecord::Base.connection
917
- assert_nothing_raised do
918
- con.execute "INSERT INTO 'references' (#{con.quote_column_name('id')}, #{con.quote_column_name('url')}) VALUES (1, 'http://rubyonrails.com')"
919
- end
920
- assert_equal 'http://rubyonrails.com', ActiveRecord::Base.connection.select_value("SELECT url FROM 'references' WHERE id=1")
921
-
922
- ensure
923
- ActiveRecord::Base.connection.drop_table :references
924
- ActiveRecord::Base.connection.rename_table :old_references, :references
925
- end
926
- end
927
- end
928
-
929
- def test_rename_table
930
- begin
931
- ActiveRecord::Base.connection.create_table :octopuses do |t|
932
- t.column :url, :string
933
- end
934
- ActiveRecord::Base.connection.rename_table :octopuses, :octopi
935
-
936
- # Using explicit id in insert for compatibility across all databases
937
- con = ActiveRecord::Base.connection
938
- con.enable_identity_insert("octopi", true) if current_adapter?(:SybaseAdapter)
939
- assert_nothing_raised { con.execute "INSERT INTO octopi (#{con.quote_column_name('id')}, #{con.quote_column_name('url')}) VALUES (1, 'http://www.foreverflying.com/octopus-black7.jpg')" }
940
- con.enable_identity_insert("octopi", false) if current_adapter?(:SybaseAdapter)
941
-
942
- assert_equal 'http://www.foreverflying.com/octopus-black7.jpg', ActiveRecord::Base.connection.select_value("SELECT url FROM octopi WHERE id=1")
943
-
944
- ensure
945
- ActiveRecord::Base.connection.drop_table :octopuses rescue nil
946
- ActiveRecord::Base.connection.drop_table :octopi rescue nil
947
- end
948
- end
949
-
950
- def test_change_column_nullability
951
- Person.delete_all
952
- Person.connection.add_column "people", "funny", :boolean
953
- Person.reset_column_information
954
- assert Person.columns_hash["funny"].null, "Column 'funny' must initially allow nulls"
955
- unless current_adapter?(:IBM_DBAdapter) # incompatible types changes
956
- Person.connection.change_column "people", "funny", :boolean, :null => false, :default => true
957
- Person.reset_column_information
958
- assert !Person.columns_hash["funny"].null, "Column 'funny' must *not* allow nulls at this point"
959
- Person.connection.change_column "people", "funny", :boolean, :null => true
960
- Person.reset_column_information
961
- assert Person.columns_hash["funny"].null, "Column 'funny' must allow nulls again at this point"
962
- end
963
- end
964
-
965
- def test_rename_table_with_an_index
966
- begin
967
- ActiveRecord::Base.connection.create_table :octopuses do |t|
968
- t.column :url, :string
969
- end
970
- ActiveRecord::Base.connection.add_index :octopuses, :url
971
-
972
- ActiveRecord::Base.connection.rename_table :octopuses, :octopi
973
-
974
- # Using explicit id in insert for compatibility across all databases
975
- con = ActiveRecord::Base.connection
976
- con.enable_identity_insert("octopi", true) if current_adapter?(:SybaseAdapter)
977
- assert_nothing_raised { con.execute "INSERT INTO octopi (#{con.quote_column_name('id')}, #{con.quote_column_name('url')}) VALUES (1, 'http://www.foreverflying.com/octopus-black7.jpg')" }
978
- con.enable_identity_insert("octopi", false) if current_adapter?(:SybaseAdapter)
979
-
980
- assert_equal 'http://www.foreverflying.com/octopus-black7.jpg', ActiveRecord::Base.connection.select_value("SELECT url FROM octopi WHERE id=1")
981
- assert ActiveRecord::Base.connection.indexes(:octopi).first.columns.include?("url")
982
- ensure
983
- ActiveRecord::Base.connection.drop_table :octopuses rescue nil
984
- ActiveRecord::Base.connection.drop_table :octopi rescue nil
985
- end
986
- end
987
-
988
- unless current_adapter?(:IBM_DBAdapter) # incompatible types changes
989
- def test_change_column
990
- Person.connection.add_column 'people', 'age', :integer
991
- label = "test_change_column Columns"
992
- old_columns = Person.connection.columns(Person.table_name, label)
993
- assert old_columns.find { |c| c.name == 'age' and c.type == :integer }
994
-
995
- assert_nothing_raised { Person.connection.change_column "people", "age", :string }
996
-
997
- new_columns = Person.connection.columns(Person.table_name, label)
998
- assert_nil new_columns.find { |c| c.name == 'age' and c.type == :integer }
999
- assert new_columns.find { |c| c.name == 'age' and c.type == :string }
1000
-
1001
- old_columns = Topic.connection.columns(Topic.table_name, label)
1002
- assert old_columns.find { |c| c.name == 'approved' and c.type == :boolean and c.default == true }
1003
- assert_nothing_raised { Topic.connection.change_column :topics, :approved, :boolean, :default => false }
1004
- new_columns = Topic.connection.columns(Topic.table_name, label)
1005
- assert_nil new_columns.find { |c| c.name == 'approved' and c.type == :boolean and c.default == true }
1006
- assert new_columns.find { |c| c.name == 'approved' and c.type == :boolean and c.default == false }
1007
- assert_nothing_raised { Topic.connection.change_column :topics, :approved, :boolean, :default => true }
1008
- end
1009
- end
1010
-
1011
- def test_change_column_with_nil_default
1012
- Person.connection.add_column "people", "contributor", :boolean, :default => true
1013
- Person.reset_column_information
1014
- assert Person.new.contributor?
1015
- unless current_adapter?(:IBM_DBAdapter) # incompatible types changes
1016
- assert_nothing_raised { Person.connection.change_column "people", "contributor", :boolean, :default => nil }
1017
- Person.reset_column_information
1018
- assert !Person.new.contributor?
1019
- assert_nil Person.new.contributor
1020
- end
1021
- ensure
1022
- Person.connection.remove_column("people", "contributor") rescue nil
1023
- end
1024
-
1025
- def test_change_column_with_new_default
1026
- Person.connection.add_column "people", "administrator", :boolean, :default => true
1027
- Person.reset_column_information
1028
- assert Person.new.administrator?
1029
- unless current_adapter?(:IBM_DBAdapter) # incompatible types changes
1030
- assert_nothing_raised { Person.connection.change_column "people", "administrator", :boolean, :default => false }
1031
- Person.reset_column_information
1032
- assert !Person.new.administrator?
1033
- end
1034
- ensure
1035
- Person.connection.remove_column("people", "administrator") rescue nil
1036
- end
1037
-
1038
- def test_change_column_default
1039
- Person.connection.change_column_default "people", "first_name", "Tester"
1040
- Person.reset_column_information
1041
- assert_equal "Tester", Person.new.first_name
1042
- end
1043
-
1044
- def test_change_column_quotes_column_names
1045
- Person.connection.create_table :testings do |t|
1046
- if current_adapter?(:IBM_DBAdapter)
1047
- t.column :select, :string, :limit => 5
1048
- else
1049
- t.column :select, :string
1050
- end
1051
- end
1052
-
1053
- assert_nothing_raised { Person.connection.change_column :testings, :select, :string, :limit => 10 }
1054
-
1055
- # Oracle needs primary key value from sequence
1056
- if current_adapter?(:OracleAdapter)
1057
- assert_nothing_raised { Person.connection.execute "insert into testings (id, #{Person.connection.quote_column_name('select')}) values (testings_seq.nextval, '7 chars')" }
1058
- else
1059
- assert_nothing_raised { Person.connection.execute "insert into testings (#{Person.connection.quote_column_name('select')}) values ('7 chars')" }
1060
- end
1061
- ensure
1062
- Person.connection.drop_table :testings rescue nil
1063
- end
1064
-
1065
- def test_keeping_default_and_notnull_constaint_on_change
1066
- Person.connection.create_table :testings do |t|
1067
- t.column :title, :string
1068
- end
1069
- person_klass = Class.new(Person)
1070
- person_klass.set_table_name 'testings'
1071
-
1072
- person_klass.connection.add_column "testings", "wealth", :integer, :null => false, :default => 99
1073
- person_klass.reset_column_information
1074
- assert_equal 99, person_klass.columns_hash["wealth"].default
1075
- assert_equal false, person_klass.columns_hash["wealth"].null
1076
- # Oracle needs primary key value from sequence
1077
- if current_adapter?(:OracleAdapter)
1078
- assert_nothing_raised {person_klass.connection.execute("insert into testings (id, title) values (testings_seq.nextval, 'tester')")}
1079
- else
1080
- assert_nothing_raised {person_klass.connection.execute("insert into testings (title) values ('tester')")}
1081
- end
1082
-
1083
- # change column default to see that column doesn't lose its not null definition
1084
- person_klass.connection.change_column_default "testings", "wealth", 100
1085
- person_klass.reset_column_information
1086
- assert_equal 100, person_klass.columns_hash["wealth"].default
1087
- assert_equal false, person_klass.columns_hash["wealth"].null
1088
-
1089
- # rename column to see that column doesn't lose its not null and/or default definition
1090
- if (!current_adapter?(:IBM_DBAdapter) || @ibm_db_rename_supported)
1091
- person_klass.connection.rename_column "testings", "wealth", "money"
1092
- person_klass.reset_column_information
1093
- assert_nil person_klass.columns_hash["wealth"]
1094
- assert_equal 100, person_klass.columns_hash["money"].default
1095
- assert_equal false, person_klass.columns_hash["money"].null
1096
- end
1097
-
1098
- # change column
1099
- unless (current_adapter?(:IBM_DBAdapter) && !@ibm_db_rename_supported)
1100
- person_klass.connection.change_column "testings", "money", :integer, :null => false, :default => 1000
1101
- person_klass.reset_column_information
1102
- assert_equal 1000, person_klass.columns_hash["money"].default
1103
- assert_equal false, person_klass.columns_hash["money"].null
1104
- else
1105
- person_klass.connection.change_column "testings", "wealth", :decimal, :precision => 15, :scale => 1,:null => false, :default => 1000
1106
- person_klass.reset_column_information
1107
- assert_equal 1000, person_klass.columns_hash["wealth"].default
1108
- assert_equal false, person_klass.columns_hash["wealth"].null
1109
- end
1110
-
1111
- # change column, make it nullable and clear default
1112
- unless (current_adapter?(:IBM_DBAdapter) && !@ibm_db_rename_supported)
1113
- person_klass.connection.change_column "testings", "money", :integer, :null => true, :default => nil
1114
- person_klass.reset_column_information
1115
- assert_nil person_klass.columns_hash["money"].default
1116
- assert_equal true, person_klass.columns_hash["money"].null
1117
- else
1118
- person_klass.connection.change_column "testings", "wealth", :decimal, :precision => 20, :scale => 2, :null => true, :default => nil
1119
- person_klass.reset_column_information
1120
- assert_nil person_klass.columns_hash["wealth"].default
1121
- assert_equal true, person_klass.columns_hash["wealth"].null
1122
- end
1123
-
1124
- # change_column_null, make it not nullable and set null values to a default value
1125
- unless (current_adapter?(:IBM_DBAdapter) && !@ibm_db_rename_supported)
1126
- person_klass.connection.execute('UPDATE testings SET money = NULL')
1127
- person_klass.connection.change_column_null "testings", "money", false, 2000
1128
- person_klass.reset_column_information
1129
- assert_nil person_klass.columns_hash["money"].default
1130
- assert_equal false, person_klass.columns_hash["money"].null
1131
- assert_equal [2000], Person.connection.select_values("SELECT money FROM testings").map { |s| s.to_i }.sort
1132
- else
1133
- # Trying to set the value of the column wealth to NULL and
1134
- # in the next statement a not null constraint is being applied which is wrong.
1135
- #person_klass.connection.execute('UPDATE testings SET wealth = NULL')
1136
- person_klass.connection.change_column_null "testings", "wealth", false, 2000
1137
- person_klass.reset_column_information
1138
- assert_equal false, person_klass.columns_hash["wealth"].null
1139
- assert_equal 2000, person_klass.columns_hash["wealth"].default
1140
- end
1141
- ensure
1142
- Person.connection.drop_table :testings rescue nil
1143
- end
1144
-
1145
- def test_change_column_default_to_null
1146
- Person.connection.change_column_default "people", "first_name", nil
1147
- Person.reset_column_information
1148
- assert_nil Person.new.first_name
1149
- end
1150
-
1151
- def test_column_exists
1152
- Person.connection.create_table :testings do |t|
1153
- t.column :foo, :string
1154
- end
1155
-
1156
- assert Person.connection.column_exists?(:testings, :foo)
1157
- assert !Person.connection.column_exists?(:testings, :bar)
1158
- ensure
1159
- Person.connection.drop_table :testings rescue nil
1160
- end
1161
-
1162
- def test_column_exists_with_type
1163
- Person.connection.create_table :testings do |t|
1164
- t.column :foo, :string
1165
- t.column :bar, :decimal, :precision => 8, :scale => 2
1166
- end
1167
-
1168
- assert Person.connection.column_exists?(:testings, :foo, :string)
1169
- assert !Person.connection.column_exists?(:testings, :foo, :integer)
1170
- assert Person.connection.column_exists?(:testings, :bar, :decimal)
1171
- assert !Person.connection.column_exists?(:testings, :bar, :integer)
1172
- ensure
1173
- Person.connection.drop_table :testings rescue nil
1174
- end
1175
-
1176
- def test_column_exists_with_definition
1177
- Person.connection.create_table :testings do |t|
1178
- t.column :foo, :string, :limit => 100
1179
- t.column :bar, :decimal, :precision => 8, :scale => 2
1180
- end
1181
-
1182
- assert Person.connection.column_exists?(:testings, :foo, :string, :limit => 100)
1183
- assert !Person.connection.column_exists?(:testings, :foo, :string, :limit => 50)
1184
- assert Person.connection.column_exists?(:testings, :bar, :decimal, :precision => 8, :scale => 2)
1185
- assert !Person.connection.column_exists?(:testings, :bar, :decimal, :precision => 10, :scale => 2)
1186
- ensure
1187
- Person.connection.drop_table :testings rescue nil
1188
- end
1189
-
1190
- def test_add_table
1191
- assert !Reminder.table_exists?
1192
-
1193
- WeNeedReminders.up
1194
-
1195
- assert Reminder.create("content" => "hello world", "remind_at" => Time.now)
1196
- assert_equal "hello world", Reminder.find(:first).content
1197
-
1198
- WeNeedReminders.down
1199
- assert_raise(ActiveRecord::StatementInvalid) { Reminder.find(:first) }
1200
- end
1201
-
1202
- def test_add_table_with_decimals
1203
- Person.connection.drop_table :big_numbers rescue nil
1204
-
1205
- assert !BigNumber.table_exists?
1206
- GiveMeBigNumbers.up
1207
-
1208
- assert BigNumber.create(
1209
- :bank_balance => 1586.43,
1210
- :big_bank_balance => BigDecimal("1000234000567.95"),
1211
- :world_population => 6000000000,
1212
- :my_house_population => 3,
1213
- :value_of_e => BigDecimal("2.7182818284590452353602875")
1214
- )
1215
-
1216
- b = BigNumber.find(:first)
1217
- assert_not_nil b
1218
-
1219
- assert_not_nil b.bank_balance
1220
- assert_not_nil b.big_bank_balance
1221
- assert_not_nil b.world_population
1222
- assert_not_nil b.my_house_population
1223
- assert_not_nil b.value_of_e
1224
-
1225
- # TODO: set world_population >= 2**62 to cover 64-bit platforms and test
1226
- # is_a?(Bignum)
1227
- unless current_adapter?(:IBM_DBAdapter) # incompatible types retrieved
1228
- assert_kind_of Integer, b.world_population
1229
- else
1230
- assert_kind_of BigDecimal, b.world_population
1231
- end
1232
- assert_equal 6000000000, b.world_population
1233
- unless current_adapter?(:IBM_DBAdapter) # incompatible types retrieved
1234
- assert_kind_of Fixnum, b.my_house_population
1235
- else
1236
- assert_kind_of BigDecimal, b.my_house_population
1237
- end
1238
- assert_equal 3, b.my_house_population
1239
- assert_kind_of BigDecimal, b.bank_balance
1240
- assert_equal BigDecimal("1586.43"), b.bank_balance
1241
- assert_kind_of BigDecimal, b.big_bank_balance
1242
- assert_equal BigDecimal("1000234000567.95"), b.big_bank_balance
1243
-
1244
- # This one is fun. The 'value_of_e' field is defined as 'DECIMAL' with
1245
- # precision/scale explicitly left out. By the SQL standard, numbers
1246
- # assigned to this field should be truncated but that's seldom respected.
1247
- if current_adapter?(:PostgreSQLAdapter)
1248
- # - PostgreSQL changes the SQL spec on columns declared simply as
1249
- # "decimal" to something more useful: instead of being given a scale
1250
- # of 0, they take on the compile-time limit for precision and scale,
1251
- # so the following should succeed unless you have used really wacky
1252
- # compilation options
1253
- # - SQLite2 has the default behavior of preserving all data sent in,
1254
- # so this happens there too
1255
- assert_kind_of BigDecimal, b.value_of_e
1256
- assert_equal BigDecimal("2.7182818284590452353602875"), b.value_of_e
1257
- elsif current_adapter?(:SQLiteAdapter)
1258
- # - SQLite3 stores a float, in violation of SQL
1259
- assert_kind_of BigDecimal, b.value_of_e
1260
- assert_in_delta BigDecimal("2.71828182845905"), b.value_of_e, 0.00000000000001
1261
- else
1262
- # - SQL standard is an integer
1263
- unless current_adapter?(:IBM_DBAdapter) # incompatible types retrieved
1264
- assert_kind_of Fixnum, b.value_of_e
1265
- else
1266
- assert_kind_of BigDecimal, b.value_of_e
1267
- end
1268
- assert_equal 2, b.value_of_e
1269
- end
1270
-
1271
- GiveMeBigNumbers.down
1272
- assert_raise(ActiveRecord::StatementInvalid) { BigNumber.find(:first) }
1273
- end
1274
-
1275
- def test_migrator
1276
- assert !Person.column_methods_hash.include?(:last_name)
1277
- assert !Reminder.table_exists?
1278
-
1279
- ActiveRecord::Migrator.up(MIGRATIONS_ROOT + "/valid")
1280
-
1281
- assert_equal 3, ActiveRecord::Migrator.current_version
1282
- Person.reset_column_information
1283
- assert Person.column_methods_hash.include?(:last_name)
1284
- assert Reminder.create("content" => "hello world", "remind_at" => Time.now)
1285
- assert_equal "hello world", Reminder.find(:first).content
1286
-
1287
- ActiveRecord::Migrator.down(MIGRATIONS_ROOT + "/valid")
1288
-
1289
- assert_equal 0, ActiveRecord::Migrator.current_version
1290
- Person.reset_column_information
1291
- assert !Person.column_methods_hash.include?(:last_name)
1292
- assert_raise(ActiveRecord::StatementInvalid) { Reminder.find(:first) }
1293
- end
1294
-
1295
- def test_migrator_one_up
1296
- assert !Person.column_methods_hash.include?(:last_name)
1297
- assert !Reminder.table_exists?
1298
-
1299
- ActiveRecord::Migrator.up(MIGRATIONS_ROOT + "/valid", 1)
1300
-
1301
- Person.reset_column_information
1302
- assert Person.column_methods_hash.include?(:last_name)
1303
- assert !Reminder.table_exists?
1304
-
1305
- ActiveRecord::Migrator.up(MIGRATIONS_ROOT + "/valid", 2)
1306
-
1307
- assert Reminder.create("content" => "hello world", "remind_at" => Time.now)
1308
- assert_equal "hello world", Reminder.find(:first).content
1309
- end
1310
-
1311
- def test_migrator_one_down
1312
- ActiveRecord::Migrator.up(MIGRATIONS_ROOT + "/valid")
1313
-
1314
- ActiveRecord::Migrator.down(MIGRATIONS_ROOT + "/valid", 1)
1315
-
1316
- Person.reset_column_information
1317
- assert Person.column_methods_hash.include?(:last_name)
1318
- assert !Reminder.table_exists?
1319
- end
1320
-
1321
- def test_migrator_one_up_one_down
1322
- ActiveRecord::Migrator.up(MIGRATIONS_ROOT + "/valid", 1)
1323
- ActiveRecord::Migrator.down(MIGRATIONS_ROOT + "/valid", 0)
1324
-
1325
- assert !Person.column_methods_hash.include?(:last_name)
1326
- assert !Reminder.table_exists?
1327
- end
1328
-
1329
- def test_migrator_double_up
1330
- assert_equal(0, ActiveRecord::Migrator.current_version)
1331
- ActiveRecord::Migrator.run(:up, MIGRATIONS_ROOT + "/valid", 1)
1332
- assert_nothing_raised { ActiveRecord::Migrator.run(:up, MIGRATIONS_ROOT + "/valid", 1) }
1333
- assert_equal(1, ActiveRecord::Migrator.current_version)
1334
- end
1335
-
1336
- def test_migrator_double_down
1337
- assert_equal(0, ActiveRecord::Migrator.current_version)
1338
- ActiveRecord::Migrator.run(:up, MIGRATIONS_ROOT + "/valid", 1)
1339
- ActiveRecord::Migrator.run(:down, MIGRATIONS_ROOT + "/valid", 1)
1340
- assert_nothing_raised { ActiveRecord::Migrator.run(:down, MIGRATIONS_ROOT + "/valid", 1) }
1341
- assert_equal(0, ActiveRecord::Migrator.current_version)
1342
- end
1343
-
1344
- if ActiveRecord::Base.connection.supports_ddl_transactions?
1345
- def test_migrator_one_up_with_exception_and_rollback
1346
- assert !Person.column_methods_hash.include?(:last_name)
1347
-
1348
- e = assert_raise(StandardError) do
1349
- ActiveRecord::Migrator.up(MIGRATIONS_ROOT + "/broken", 100)
1350
- end
1351
-
1352
- assert_equal "An error has occurred, this and all later migrations canceled:\n\nSomething broke", e.message
1353
-
1354
- Person.reset_column_information
1355
- assert !Person.column_methods_hash.include?(:last_name)
1356
- end
1357
- end
1358
-
1359
- def test_finds_migrations
1360
- migrations = ActiveRecord::Migrator.new(:up, MIGRATIONS_ROOT + "/valid").migrations
1361
-
1362
- [[1, 'PeopleHaveLastNames'], [2, 'WeNeedReminders'], [3, 'InnocentJointable']].each_with_index do |pair, i|
1363
- assert_equal migrations[i].version, pair.first
1364
- assert_equal migrations[i].name, pair.last
1365
- end
1366
- end
1367
-
1368
- def test_finds_pending_migrations
1369
- ActiveRecord::Migrator.up(MIGRATIONS_ROOT + "/interleaved/pass_2", 1)
1370
- migrations = ActiveRecord::Migrator.new(:up, MIGRATIONS_ROOT + "/interleaved/pass_2").pending_migrations
1371
-
1372
- assert_equal 1, migrations.size
1373
- assert_equal migrations[0].version, 3
1374
- assert_equal migrations[0].name, 'InnocentJointable'
1375
- end
1376
-
1377
- def test_relative_migrations
1378
- $".delete_if do |fname|
1379
- fname == (MIGRATIONS_ROOT + "/valid/1_people_have_last_names.rb")
1380
- end
1381
- Object.send(:remove_const, :PeopleHaveLastNames)
1382
-
1383
- Dir.chdir(MIGRATIONS_ROOT) do
1384
- ActiveRecord::Migrator.up("valid/", 1)
1385
- end
1386
-
1387
- assert defined?(PeopleHaveLastNames)
1388
- end
1389
-
1390
- def test_only_loads_pending_migrations
1391
- # migrate up to 1
1392
- ActiveRecord::Migrator.up(MIGRATIONS_ROOT + "/valid", 1)
1393
-
1394
- # now unload the migrations that have been defined
1395
- Object.send(:remove_const, :PeopleHaveLastNames)
1396
-
1397
- ActiveRecord::Migrator.migrate(MIGRATIONS_ROOT + "/valid", nil)
1398
-
1399
- assert !defined? PeopleHaveLastNames
1400
-
1401
- %w(WeNeedReminders, InnocentJointable).each do |migration|
1402
- assert defined? migration
1403
- end
1404
-
1405
- ensure
1406
- load(MIGRATIONS_ROOT + "/valid/1_people_have_last_names.rb")
1407
- end
1408
-
1409
- def test_target_version_zero_should_run_only_once
1410
- # migrate up to 1
1411
- ActiveRecord::Migrator.migrate(MIGRATIONS_ROOT + "/valid", 1)
1412
-
1413
- # migrate down to 0
1414
- ActiveRecord::Migrator.migrate(MIGRATIONS_ROOT + "/valid", 0)
1415
-
1416
- # now unload the migrations that have been defined
1417
- PeopleHaveLastNames.unloadable
1418
- ActiveSupport::Dependencies.remove_unloadable_constants!
1419
-
1420
- # migrate down to 0 again
1421
- ActiveRecord::Migrator.migrate(MIGRATIONS_ROOT + "/valid", 0)
1422
-
1423
- assert !defined? PeopleHaveLastNames
1424
- ensure
1425
- load(MIGRATIONS_ROOT + "/valid/1_people_have_last_names.rb")
1426
- end
1427
-
1428
- def test_migrator_db_has_no_schema_migrations_table
1429
- # Oracle adapter raises error if semicolon is present as last character
1430
- if current_adapter?(:OracleAdapter)
1431
- ActiveRecord::Base.connection.execute("DROP TABLE schema_migrations")
1432
- else
1433
- ActiveRecord::Base.connection.execute("DROP TABLE schema_migrations;")
1434
- end
1435
- assert_nothing_raised do
1436
- ActiveRecord::Migrator.migrate(MIGRATIONS_ROOT + "/valid", 1)
1437
- end
1438
- end
1439
-
1440
- def test_migrator_verbosity
1441
- ActiveRecord::Migrator.up(MIGRATIONS_ROOT + "/valid", 1)
1442
- assert PeopleHaveLastNames.message_count > 0
1443
- PeopleHaveLastNames.message_count = 0
1444
-
1445
- ActiveRecord::Migrator.down(MIGRATIONS_ROOT + "/valid", 0)
1446
- assert PeopleHaveLastNames.message_count > 0
1447
- PeopleHaveLastNames.message_count = 0
1448
- end
1449
-
1450
- def test_migrator_verbosity_off
1451
- PeopleHaveLastNames.verbose = false
1452
- ActiveRecord::Migrator.up(MIGRATIONS_ROOT + "/valid", 1)
1453
- assert PeopleHaveLastNames.message_count.zero?
1454
- ActiveRecord::Migrator.down(MIGRATIONS_ROOT + "/valid", 0)
1455
- assert PeopleHaveLastNames.message_count.zero?
1456
- end
1457
-
1458
- def test_migrator_going_down_due_to_version_target
1459
- ActiveRecord::Migrator.up(MIGRATIONS_ROOT + "/valid", 1)
1460
- ActiveRecord::Migrator.migrate(MIGRATIONS_ROOT + "/valid", 0)
1461
-
1462
- assert !Person.column_methods_hash.include?(:last_name)
1463
- assert !Reminder.table_exists?
1464
-
1465
- ActiveRecord::Migrator.migrate(MIGRATIONS_ROOT + "/valid")
1466
-
1467
- Person.reset_column_information
1468
- assert Person.column_methods_hash.include?(:last_name)
1469
- assert Reminder.create("content" => "hello world", "remind_at" => Time.now)
1470
- assert_equal "hello world", Reminder.find(:first).content
1471
- end
1472
-
1473
- def test_migrator_rollback
1474
- ActiveRecord::Migrator.migrate(MIGRATIONS_ROOT + "/valid")
1475
- assert_equal(3, ActiveRecord::Migrator.current_version)
1476
-
1477
- ActiveRecord::Migrator.rollback(MIGRATIONS_ROOT + "/valid")
1478
- assert_equal(2, ActiveRecord::Migrator.current_version)
1479
-
1480
- ActiveRecord::Migrator.rollback(MIGRATIONS_ROOT + "/valid")
1481
- assert_equal(1, ActiveRecord::Migrator.current_version)
1482
-
1483
- ActiveRecord::Migrator.rollback(MIGRATIONS_ROOT + "/valid")
1484
- assert_equal(0, ActiveRecord::Migrator.current_version)
1485
-
1486
- ActiveRecord::Migrator.rollback(MIGRATIONS_ROOT + "/valid")
1487
- assert_equal(0, ActiveRecord::Migrator.current_version)
1488
- end
1489
-
1490
- def test_migrator_forward
1491
- ActiveRecord::Migrator.migrate(MIGRATIONS_ROOT + "/valid", 1)
1492
- assert_equal(1, ActiveRecord::Migrator.current_version)
1493
-
1494
- ActiveRecord::Migrator.forward(MIGRATIONS_ROOT + "/valid", 2)
1495
- assert_equal(3, ActiveRecord::Migrator.current_version)
1496
-
1497
- ActiveRecord::Migrator.forward(MIGRATIONS_ROOT + "/valid")
1498
- assert_equal(3, ActiveRecord::Migrator.current_version)
1499
- end
1500
-
1501
- def test_get_all_versions
1502
- ActiveRecord::Migrator.migrate(MIGRATIONS_ROOT + "/valid")
1503
- assert_equal([1,2,3], ActiveRecord::Migrator.get_all_versions)
1504
-
1505
- ActiveRecord::Migrator.rollback(MIGRATIONS_ROOT + "/valid")
1506
- assert_equal([1,2], ActiveRecord::Migrator.get_all_versions)
1507
-
1508
- ActiveRecord::Migrator.rollback(MIGRATIONS_ROOT + "/valid")
1509
- assert_equal([1], ActiveRecord::Migrator.get_all_versions)
1510
-
1511
- ActiveRecord::Migrator.rollback(MIGRATIONS_ROOT + "/valid")
1512
- assert_equal([], ActiveRecord::Migrator.get_all_versions)
1513
- end
1514
-
1515
- def test_schema_migrations_table_name
1516
- ActiveRecord::Base.table_name_prefix = "prefix_"
1517
- ActiveRecord::Base.table_name_suffix = "_suffix"
1518
- Reminder.reset_table_name
1519
- assert_equal "prefix_schema_migrations_suffix", ActiveRecord::Migrator.schema_migrations_table_name
1520
- ActiveRecord::Base.table_name_prefix = ""
1521
- ActiveRecord::Base.table_name_suffix = ""
1522
- Reminder.reset_table_name
1523
- assert_equal "schema_migrations", ActiveRecord::Migrator.schema_migrations_table_name
1524
- ensure
1525
- ActiveRecord::Base.table_name_prefix = ""
1526
- ActiveRecord::Base.table_name_suffix = ""
1527
- end
1528
-
1529
- def test_proper_table_name
1530
- assert_equal "table", ActiveRecord::Migrator.proper_table_name('table')
1531
- assert_equal "table", ActiveRecord::Migrator.proper_table_name(:table)
1532
- assert_equal "reminders", ActiveRecord::Migrator.proper_table_name(Reminder)
1533
- Reminder.reset_table_name
1534
- assert_equal Reminder.table_name, ActiveRecord::Migrator.proper_table_name(Reminder)
1535
-
1536
- # Use the model's own prefix/suffix if a model is given
1537
- ActiveRecord::Base.table_name_prefix = "ARprefix_"
1538
- ActiveRecord::Base.table_name_suffix = "_ARsuffix"
1539
- Reminder.table_name_prefix = 'prefix_'
1540
- Reminder.table_name_suffix = '_suffix'
1541
- Reminder.reset_table_name
1542
- assert_equal "prefix_reminders_suffix", ActiveRecord::Migrator.proper_table_name(Reminder)
1543
- Reminder.table_name_prefix = ''
1544
- Reminder.table_name_suffix = ''
1545
- Reminder.reset_table_name
1546
-
1547
- # Use AR::Base's prefix/suffix if string or symbol is given
1548
- ActiveRecord::Base.table_name_prefix = "prefix_"
1549
- ActiveRecord::Base.table_name_suffix = "_suffix"
1550
- Reminder.reset_table_name
1551
- assert_equal "prefix_table_suffix", ActiveRecord::Migrator.proper_table_name('table')
1552
- assert_equal "prefix_table_suffix", ActiveRecord::Migrator.proper_table_name(:table)
1553
- ActiveRecord::Base.table_name_prefix = ""
1554
- ActiveRecord::Base.table_name_suffix = ""
1555
- Reminder.reset_table_name
1556
- end
1557
-
1558
- def test_add_drop_table_with_prefix_and_suffix
1559
- assert !Reminder.table_exists?
1560
- ActiveRecord::Base.table_name_prefix = 'prefix_'
1561
- ActiveRecord::Base.table_name_suffix = '_suffix'
1562
- Reminder.reset_table_name
1563
- Reminder.reset_sequence_name
1564
- WeNeedReminders.up
1565
- assert Reminder.create("content" => "hello world", "remind_at" => Time.now)
1566
- assert_equal "hello world", Reminder.find(:first).content
1567
-
1568
- WeNeedReminders.down
1569
- assert_raise(ActiveRecord::StatementInvalid) { Reminder.find(:first) }
1570
- ensure
1571
- ActiveRecord::Base.table_name_prefix = ''
1572
- ActiveRecord::Base.table_name_suffix = ''
1573
- Reminder.reset_table_name
1574
- Reminder.reset_sequence_name
1575
- end
1576
-
1577
- def test_create_table_with_binary_column
1578
- Person.connection.drop_table :binary_testings rescue nil
1579
-
1580
- assert_nothing_raised {
1581
- Person.connection.create_table :binary_testings do |t|
1582
- t.column "data", :binary, :null => false
1583
- end
1584
- }
1585
-
1586
- columns = Person.connection.columns(:binary_testings)
1587
- data_column = columns.detect { |c| c.name == "data" }
1588
-
1589
- if current_adapter?(:MysqlAdapter) or current_adapter?(:Mysql2Adapter)
1590
- assert_equal '', data_column.default
1591
- else
1592
- assert_nil data_column.default
1593
- end
1594
-
1595
- Person.connection.drop_table :binary_testings rescue nil
1596
- end
1597
-
1598
- def test_migrator_with_duplicates
1599
- assert_raise(ActiveRecord::DuplicateMigrationVersionError) do
1600
- ActiveRecord::Migrator.migrate(MIGRATIONS_ROOT + "/duplicate", nil)
1601
- end
1602
- end
1603
-
1604
- def test_migrator_with_duplicate_names
1605
- assert_raise(ActiveRecord::DuplicateMigrationNameError, "Multiple migrations have the name Chunky") do
1606
- ActiveRecord::Migrator.migrate(MIGRATIONS_ROOT + "/duplicate_names", nil)
1607
- end
1608
- end
1609
-
1610
- def test_migrator_with_missing_version_numbers
1611
- assert_raise(ActiveRecord::UnknownMigrationVersionError) do
1612
- ActiveRecord::Migrator.migrate(MIGRATIONS_ROOT + "/missing", 500)
1613
- end
1614
- end
1615
-
1616
- def test_create_table_with_custom_sequence_name
1617
- return unless current_adapter? :OracleAdapter
1618
-
1619
- # table name is 29 chars, the standard sequence name will
1620
- # be 33 chars and should be shortened
1621
- assert_nothing_raised do
1622
- begin
1623
- Person.connection.create_table :table_with_name_thats_just_ok do |t|
1624
- t.column :foo, :string, :null => false
1625
- end
1626
- ensure
1627
- Person.connection.drop_table :table_with_name_thats_just_ok rescue nil
1628
- end
1629
- end
1630
-
1631
- # should be all good w/ a custom sequence name
1632
- assert_nothing_raised do
1633
- begin
1634
- Person.connection.create_table :table_with_name_thats_just_ok,
1635
- :sequence_name => 'suitably_short_seq' do |t|
1636
- t.column :foo, :string, :null => false
1637
- end
1638
-
1639
- Person.connection.execute("select suitably_short_seq.nextval from dual")
1640
-
1641
- ensure
1642
- Person.connection.drop_table :table_with_name_thats_just_ok,
1643
- :sequence_name => 'suitably_short_seq' rescue nil
1644
- end
1645
- end
1646
-
1647
- # confirm the custom sequence got dropped
1648
- assert_raise(ActiveRecord::StatementInvalid) do
1649
- Person.connection.execute("select suitably_short_seq.nextval from dual")
1650
- end
1651
- end
1652
-
1653
- protected
1654
- def with_env_tz(new_tz = 'US/Eastern')
1655
- old_tz, ENV['TZ'] = ENV['TZ'], new_tz
1656
- yield
1657
- ensure
1658
- old_tz ? ENV['TZ'] = old_tz : ENV.delete('TZ')
1659
- end
1660
-
1661
- end
1662
-
1663
- class SexyMigrationsTest < ActiveRecord::TestCase
1664
- def test_references_column_type_adds_id
1665
- with_new_table do |t|
1666
- t.expects(:column).with('customer_id', :integer, {})
1667
- t.references :customer
1668
- end
1669
- end
1670
-
1671
- def test_references_column_type_with_polymorphic_adds_type
1672
- with_new_table do |t|
1673
- t.expects(:column).with('taggable_type', :string, {})
1674
- t.expects(:column).with('taggable_id', :integer, {})
1675
- t.references :taggable, :polymorphic => true
1676
- end
1677
- end
1678
-
1679
- def test_references_column_type_with_polymorphic_and_options_null_is_false_adds_table_flag
1680
- with_new_table do |t|
1681
- t.expects(:column).with('taggable_type', :string, {:null => false})
1682
- t.expects(:column).with('taggable_id', :integer, {:null => false})
1683
- t.references :taggable, :polymorphic => true, :null => false
1684
- end
1685
- end
1686
-
1687
- def test_belongs_to_works_like_references
1688
- with_new_table do |t|
1689
- t.expects(:column).with('customer_id', :integer, {})
1690
- t.belongs_to :customer
1691
- end
1692
- end
1693
-
1694
- def test_timestamps_creates_updated_at_and_created_at
1695
- with_new_table do |t|
1696
- t.expects(:column).with(:created_at, :datetime, kind_of(Hash))
1697
- t.expects(:column).with(:updated_at, :datetime, kind_of(Hash))
1698
- t.timestamps
1699
- end
1700
- end
1701
-
1702
- def test_integer_creates_integer_column
1703
- with_new_table do |t|
1704
- t.expects(:column).with(:foo, 'integer', {})
1705
- t.expects(:column).with(:bar, 'integer', {})
1706
- t.integer :foo, :bar
1707
- end
1708
- end
1709
-
1710
- def test_string_creates_string_column
1711
- with_new_table do |t|
1712
- t.expects(:column).with(:foo, 'string', {})
1713
- t.expects(:column).with(:bar, 'string', {})
1714
- t.string :foo, :bar
1715
- end
1716
- end
1717
-
1718
- if current_adapter?(:PostgreSQLAdapter)
1719
- def test_xml_creates_xml_column
1720
- with_new_table do |t|
1721
- t.expects(:column).with(:data, 'xml', {})
1722
- t.xml :data
1723
- end
1724
- end
1725
- end
1726
-
1727
- protected
1728
- def with_new_table
1729
- Person.connection.create_table :delete_me, :force => true do |t|
1730
- yield t
1731
- end
1732
- ensure
1733
- Person.connection.drop_table :delete_me rescue nil
1734
- end
1735
-
1736
- end # SexyMigrationsTest
1737
-
1738
- class MigrationLoggerTest < ActiveRecord::TestCase
1739
- def setup
1740
- Object.send(:remove_const, :InnocentJointable)
1741
- end
1742
-
1743
- def test_migration_should_be_run_without_logger
1744
- previous_logger = ActiveRecord::Base.logger
1745
- ActiveRecord::Base.logger = nil
1746
- assert_nothing_raised do
1747
- ActiveRecord::Migrator.migrate(MIGRATIONS_ROOT + "/valid")
1748
- end
1749
- ensure
1750
- ActiveRecord::Base.logger = previous_logger
1751
- end
1752
- end
1753
-
1754
- class InterleavedMigrationsTest < ActiveRecord::TestCase
1755
- def setup
1756
- Object.send(:remove_const, :PeopleHaveLastNames)
1757
- end
1758
-
1759
- def test_migrator_interleaved_migrations
1760
- ActiveRecord::Migrator.up(MIGRATIONS_ROOT + "/interleaved/pass_1")
1761
-
1762
- assert_nothing_raised do
1763
- ActiveRecord::Migrator.up(MIGRATIONS_ROOT + "/interleaved/pass_2")
1764
- end
1765
-
1766
- Person.reset_column_information
1767
- assert Person.column_methods_hash.include?(:last_name)
1768
-
1769
- Object.send(:remove_const, :PeopleHaveLastNames)
1770
- Object.send(:remove_const, :InnocentJointable)
1771
- assert_nothing_raised do
1772
- ActiveRecord::Migrator.down(MIGRATIONS_ROOT + "/interleaved/pass_3")
1773
- end
1774
- end
1775
- end
1776
-
1777
- class ReservedWordsMigrationTest < ActiveRecord::TestCase
1778
- def test_drop_index_from_table_named_values
1779
- connection = Person.connection
1780
- connection.create_table :values, :force => true do |t|
1781
- t.integer :value
1782
- end
1783
-
1784
- assert_nothing_raised do
1785
- connection.add_index :values, :value
1786
- connection.remove_index :values, :column => :value
1787
- end
1788
-
1789
- connection.drop_table :values rescue nil
1790
- end
1791
- end
1792
-
1793
-
1794
- class ChangeTableMigrationsTest < ActiveRecord::TestCase
1795
- def setup
1796
- @connection = Person.connection
1797
- @connection.create_table :delete_me, :force => true do |t|
1798
- end
1799
- end
1800
-
1801
- def teardown
1802
- Person.connection.drop_table :delete_me rescue nil
1803
- end
1804
-
1805
- def test_references_column_type_adds_id
1806
- with_change_table do |t|
1807
- @connection.expects(:add_column).with(:delete_me, 'customer_id', :integer, {})
1808
- t.references :customer
1809
- end
1810
- end
1811
-
1812
- def test_remove_references_column_type_removes_id
1813
- with_change_table do |t|
1814
- @connection.expects(:remove_column).with(:delete_me, 'customer_id')
1815
- t.remove_references :customer
1816
- end
1817
- end
1818
-
1819
- def test_add_belongs_to_works_like_add_references
1820
- with_change_table do |t|
1821
- @connection.expects(:add_column).with(:delete_me, 'customer_id', :integer, {})
1822
- t.belongs_to :customer
1823
- end
1824
- end
1825
-
1826
- def test_remove_belongs_to_works_like_remove_references
1827
- with_change_table do |t|
1828
- @connection.expects(:remove_column).with(:delete_me, 'customer_id')
1829
- t.remove_belongs_to :customer
1830
- end
1831
- end
1832
-
1833
- def test_references_column_type_with_polymorphic_adds_type
1834
- with_change_table do |t|
1835
- @connection.expects(:add_column).with(:delete_me, 'taggable_type', :string, {})
1836
- @connection.expects(:add_column).with(:delete_me, 'taggable_id', :integer, {})
1837
- t.references :taggable, :polymorphic => true
1838
- end
1839
- end
1840
-
1841
- def test_remove_references_column_type_with_polymorphic_removes_type
1842
- with_change_table do |t|
1843
- @connection.expects(:remove_column).with(:delete_me, 'taggable_type')
1844
- @connection.expects(:remove_column).with(:delete_me, 'taggable_id')
1845
- t.remove_references :taggable, :polymorphic => true
1846
- end
1847
- end
1848
-
1849
- def test_references_column_type_with_polymorphic_and_options_null_is_false_adds_table_flag
1850
- with_change_table do |t|
1851
- @connection.expects(:add_column).with(:delete_me, 'taggable_type', :string, {:null => false})
1852
- @connection.expects(:add_column).with(:delete_me, 'taggable_id', :integer, {:null => false})
1853
- t.references :taggable, :polymorphic => true, :null => false
1854
- end
1855
- end
1856
-
1857
- def test_remove_references_column_type_with_polymorphic_and_options_null_is_false_removes_table_flag
1858
- with_change_table do |t|
1859
- @connection.expects(:remove_column).with(:delete_me, 'taggable_type')
1860
- @connection.expects(:remove_column).with(:delete_me, 'taggable_id')
1861
- t.remove_references :taggable, :polymorphic => true, :null => false
1862
- end
1863
- end
1864
-
1865
- def test_timestamps_creates_updated_at_and_created_at
1866
- with_change_table do |t|
1867
- @connection.expects(:add_timestamps).with(:delete_me)
1868
- t.timestamps
1869
- end
1870
- end
1871
-
1872
- def test_remove_timestamps_creates_updated_at_and_created_at
1873
- with_change_table do |t|
1874
- @connection.expects(:remove_timestamps).with(:delete_me)
1875
- t.remove_timestamps
1876
- end
1877
- end
1878
-
1879
- def string_column
1880
- if current_adapter?(:PostgreSQLAdapter)
1881
- "character varying(255)"
1882
- elsif current_adapter?(:OracleAdapter)
1883
- 'VARCHAR2(255)'
1884
- else
1885
- 'varchar(255)'
1886
- end
1887
- end
1888
-
1889
- def integer_column
1890
- if current_adapter?(:MysqlAdapter) or current_adapter?(:Mysql2Adapter)
1891
- 'int(11)'
1892
- elsif current_adapter?(:OracleAdapter)
1893
- 'NUMBER(38)'
1894
- else
1895
- 'integer'
1896
- end
1897
- end
1898
-
1899
- def test_integer_creates_integer_column
1900
- with_change_table do |t|
1901
- @connection.expects(:add_column).with(:delete_me, :foo, integer_column, {})
1902
- @connection.expects(:add_column).with(:delete_me, :bar, integer_column, {})
1903
- t.integer :foo, :bar
1904
- end
1905
- end
1906
-
1907
- def test_string_creates_string_column
1908
- with_change_table do |t|
1909
- @connection.expects(:add_column).with(:delete_me, :foo, string_column, {})
1910
- @connection.expects(:add_column).with(:delete_me, :bar, string_column, {})
1911
- t.string :foo, :bar
1912
- end
1913
- end
1914
-
1915
- def test_column_creates_column
1916
- with_change_table do |t|
1917
- @connection.expects(:add_column).with(:delete_me, :bar, :integer, {})
1918
- t.column :bar, :integer
1919
- end
1920
- end
1921
-
1922
- def test_column_creates_column_with_options
1923
- with_change_table do |t|
1924
- @connection.expects(:add_column).with(:delete_me, :bar, :integer, {:null => false})
1925
- t.column :bar, :integer, :null => false
1926
- end
1927
- end
1928
-
1929
- def test_index_creates_index
1930
- with_change_table do |t|
1931
- @connection.expects(:add_index).with(:delete_me, :bar, {})
1932
- t.index :bar
1933
- end
1934
- end
1935
-
1936
- def test_index_creates_index_with_options
1937
- with_change_table do |t|
1938
- @connection.expects(:add_index).with(:delete_me, :bar, {:unique => true})
1939
- t.index :bar, :unique => true
1940
- end
1941
- end
1942
-
1943
- def test_index_exists
1944
- with_change_table do |t|
1945
- @connection.expects(:index_exists?).with(:delete_me, :bar, {})
1946
- t.index_exists?(:bar)
1947
- end
1948
- end
1949
-
1950
- def test_index_exists_with_options
1951
- with_change_table do |t|
1952
- @connection.expects(:index_exists?).with(:delete_me, :bar, {:unique => true})
1953
- t.index_exists?(:bar, :unique => true)
1954
- end
1955
- end
1956
-
1957
- def test_change_changes_column
1958
- with_change_table do |t|
1959
- @connection.expects(:change_column).with(:delete_me, :bar, :string, {})
1960
- t.change :bar, :string
1961
- end
1962
- end
1963
-
1964
- def test_change_changes_column_with_options
1965
- with_change_table do |t|
1966
- @connection.expects(:change_column).with(:delete_me, :bar, :string, {:null => true})
1967
- t.change :bar, :string, :null => true
1968
- end
1969
- end
1970
-
1971
- def test_change_default_changes_column
1972
- with_change_table do |t|
1973
- @connection.expects(:change_column_default).with(:delete_me, :bar, :string)
1974
- t.change_default :bar, :string
1975
- end
1976
- end
1977
-
1978
- def test_remove_drops_single_column
1979
- with_change_table do |t|
1980
- @connection.expects(:remove_column).with(:delete_me, [:bar])
1981
- t.remove :bar
1982
- end
1983
- end
1984
-
1985
- def test_remove_drops_multiple_columns
1986
- with_change_table do |t|
1987
- @connection.expects(:remove_column).with(:delete_me, [:bar, :baz])
1988
- t.remove :bar, :baz
1989
- end
1990
- end
1991
-
1992
- def test_remove_index_removes_index_with_options
1993
- with_change_table do |t|
1994
- @connection.expects(:remove_index).with(:delete_me, {:unique => true})
1995
- t.remove_index :unique => true
1996
- end
1997
- end
1998
-
1999
- def test_rename_renames_column
2000
- with_change_table do |t|
2001
- @connection.expects(:rename_column).with(:delete_me, :bar, :baz)
2002
- t.rename :bar, :baz
2003
- end
2004
- end
2005
-
2006
- protected
2007
- def with_change_table
2008
- Person.connection.change_table :delete_me do |t|
2009
- yield t
2010
- end
2011
- end
2012
- end
2013
- end
2014
-