ibm_db 2.5.6-x86-mingw32 → 2.5.7-x86-mingw32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGES +6 -0
- data/README +1 -1
- data/ext/Makefile.nt32 +3 -3
- data/ext/Makefile.nt32.191 +212 -0
- data/ext/ibm_db.c +30 -5
- data/lib/active_record/connection_adapters/ibm_db_adapter.rb +300 -108
- data/lib/active_record/connection_adapters/ibm_db_pstmt.rb +1 -1
- data/lib/mswin32/rb18x/ibm_db.so +0 -0
- data/lib/mswin32/rb19x/ibm_db.so +0 -0
- data/test/cases/adapter_test.rb +25 -22
- data/test/cases/associations/belongs_to_associations_test.rb +245 -43
- data/test/cases/associations/cascaded_eager_loading_test.rb +28 -26
- data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +60 -156
- data/test/cases/associations/join_model_test.rb +96 -146
- data/test/cases/attribute_methods_test.rb +98 -33
- data/test/cases/base_test.rb +525 -103
- data/test/cases/calculations_test.rb +92 -8
- data/test/cases/migration_test.rb +533 -207
- data/test/cases/persistence_test.rb +636 -0
- data/test/cases/query_cache_test.rb +242 -0
- data/test/cases/relations_test.rb +1019 -0
- data/test/cases/schema_dumper_test.rb +37 -17
- data/test/cases/transaction_callbacks_test.rb +300 -0
- data/test/cases/validations/uniqueness_validation_test.rb +38 -22
- data/test/cases/xml_serialization_test.rb +276 -0
- data/test/config.yml +154 -0
- data/test/connections/native_ibm_db/connection.rb +2 -0
- data/test/models/warehouse_thing.rb +4 -4
- data/test/schema/i5/ibm_db_specific_schema.rb +3 -1
- data/test/schema/ids/ibm_db_specific_schema.rb +3 -1
- data/test/schema/luw/ibm_db_specific_schema.rb +2 -0
- data/test/schema/schema.rb +174 -89
- data/test/schema/zOS/ibm_db_specific_schema.rb +3 -1
- metadata +10 -7
- data/test/cases/associations/eager_test.rb +0 -862
- data/test/cases/associations/has_many_through_associations_test.rb +0 -461
- data/test/cases/finder_test.rb +0 -1088
- data/test/cases/fixtures_test.rb +0 -684
@@ -23,6 +23,18 @@ class CalculationsTest < ActiveRecord::TestCase
|
|
23
23
|
assert_equal 53.0, value
|
24
24
|
end
|
25
25
|
|
26
|
+
def test_should_return_decimal_average_of_integer_field
|
27
|
+
return if current_adapter?(:IBM_DBAdapter) #average cannot be a decimal value when applied on integer field
|
28
|
+
value = Account.average(:id)
|
29
|
+
assert_equal 3.5, value
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_should_return_integer_average_if_db_returns_such
|
33
|
+
Account.connection.stubs :select_value => 3
|
34
|
+
value = Account.average(:id)
|
35
|
+
assert_equal 3, value
|
36
|
+
end
|
37
|
+
|
26
38
|
def test_should_return_nil_as_average
|
27
39
|
assert_nil NumericData.average(:bank_balance)
|
28
40
|
end
|
@@ -55,6 +67,19 @@ class CalculationsTest < ActiveRecord::TestCase
|
|
55
67
|
[1,6,2].each { |firm_id| assert c.keys.include?(firm_id) }
|
56
68
|
end
|
57
69
|
|
70
|
+
def test_should_group_by_multiple_fields
|
71
|
+
c = Account.count(:all, :group => ['firm_id', :credit_limit])
|
72
|
+
[ [nil, 50], [1, 50], [6, 50], [6, 55], [9, 53], [2, 60] ].each { |firm_and_limit| assert c.keys.include?(firm_and_limit) }
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_should_group_by_multiple_fields_having_functions
|
76
|
+
c = Topic.group(:author_name, 'COALESCE(type, title)').count(:all)
|
77
|
+
assert_equal 1, c[["Carl", "The Third Topic of the day"]]
|
78
|
+
assert_equal 1, c[["Mary", "Reply"]]
|
79
|
+
assert_equal 1, c[["David", "The First Topic"]]
|
80
|
+
assert_equal 1, c[["Carl", "Reply"]]
|
81
|
+
end
|
82
|
+
|
58
83
|
def test_should_group_by_summed_field
|
59
84
|
c = Account.sum(:credit_limit, :group => :firm_id)
|
60
85
|
assert_equal 50, c[1]
|
@@ -85,6 +110,51 @@ class CalculationsTest < ActiveRecord::TestCase
|
|
85
110
|
assert_equal [2, 6], c.keys.compact
|
86
111
|
end
|
87
112
|
|
113
|
+
def test_limit_should_apply_before_count
|
114
|
+
accounts = Account.limit(3).where('firm_id IS NOT NULL')
|
115
|
+
|
116
|
+
assert_equal 3, accounts.count(:firm_id)
|
117
|
+
assert_equal 3, accounts.select(:firm_id).count
|
118
|
+
end
|
119
|
+
|
120
|
+
def test_count_should_shortcut_with_limit_zero
|
121
|
+
accounts = Account.limit(0)
|
122
|
+
|
123
|
+
assert_no_queries { assert_equal 0, accounts.count }
|
124
|
+
end
|
125
|
+
|
126
|
+
def test_limit_is_kept
|
127
|
+
return if current_adapter?(:OracleAdapter, :IBM_DBAdapter)
|
128
|
+
|
129
|
+
queries = assert_sql { Account.limit(1).count }
|
130
|
+
assert_equal 1, queries.length
|
131
|
+
assert_match(/LIMIT/, queries.first)
|
132
|
+
end
|
133
|
+
|
134
|
+
def test_offset_is_kept
|
135
|
+
return if current_adapter?(:OracleAdapter,:IBM_DBAdapter)
|
136
|
+
|
137
|
+
queries = assert_sql { Account.offset(1).count }
|
138
|
+
assert_equal 1, queries.length
|
139
|
+
assert_match(/OFFSET/, queries.first)
|
140
|
+
end
|
141
|
+
|
142
|
+
def test_limit_with_offset_is_kept
|
143
|
+
return if current_adapter?(:OracleAdapter,:IBM_DBAdapter)
|
144
|
+
|
145
|
+
queries = assert_sql { Account.limit(1).offset(1).count }
|
146
|
+
assert_equal 1, queries.length
|
147
|
+
assert_match(/LIMIT/, queries.first)
|
148
|
+
assert_match(/OFFSET/, queries.first)
|
149
|
+
end
|
150
|
+
|
151
|
+
def test_no_limit_no_offset
|
152
|
+
queries = assert_sql { Account.count }
|
153
|
+
assert_equal 1, queries.length
|
154
|
+
assert_no_match(/LIMIT/, queries.first)
|
155
|
+
assert_no_match(/OFFSET/, queries.first)
|
156
|
+
end
|
157
|
+
|
88
158
|
def test_should_group_by_summed_field_having_condition
|
89
159
|
c = Account.sum(:credit_limit, :group => :firm_id,
|
90
160
|
:having => 'sum(credit_limit) > 50')
|
@@ -101,6 +171,13 @@ class CalculationsTest < ActiveRecord::TestCase
|
|
101
171
|
assert_equal 60, c[2]
|
102
172
|
end
|
103
173
|
|
174
|
+
def test_should_group_by_summed_field_having_condition_from_select
|
175
|
+
c = Account.select("MIN(credit_limit) AS min_credit_limit").group(:firm_id).having("min_credit_limit > 50").sum(:credit_limit)
|
176
|
+
assert_nil c[1]
|
177
|
+
assert_equal 60, c[2]
|
178
|
+
assert_equal 53, c[9]
|
179
|
+
end
|
180
|
+
|
104
181
|
def test_should_group_by_summed_association
|
105
182
|
c = Account.sum(:credit_limit, :group => :firm)
|
106
183
|
assert_equal 50, c[companies(:first_firm)]
|
@@ -166,11 +243,7 @@ class CalculationsTest < ActiveRecord::TestCase
|
|
166
243
|
end
|
167
244
|
|
168
245
|
def test_should_group_by_association_with_non_numeric_foreign_key
|
169
|
-
|
170
|
-
ActiveRecord::Base.connection.expects(:prepared_select).returns([{"count_all" => 1, "firm_id" => "ABC"}])
|
171
|
-
else
|
172
|
-
ActiveRecord::Base.connection.expects(:select_all).returns([{"count_all" => 1, "firm_id" => "ABC"}])
|
173
|
-
end
|
246
|
+
ActiveRecord::Base.connection.expects(:select_all).returns([{"count_all" => 1, "firm_id" => "ABC"}])
|
174
247
|
|
175
248
|
firm = mock()
|
176
249
|
firm.expects(:id).returns("ABC")
|
@@ -254,6 +327,17 @@ class CalculationsTest < ActiveRecord::TestCase
|
|
254
327
|
assert_equal 4, Account.count(:distinct => true, :include => :firm, :select => :credit_limit)
|
255
328
|
end
|
256
329
|
|
330
|
+
def test_should_not_perform_joined_include_by_default
|
331
|
+
assert_equal Account.count, Account.includes(:firm).count
|
332
|
+
queries = assert_sql { Account.includes(:firm).count }
|
333
|
+
assert_no_match(/join/i, queries.last)
|
334
|
+
end
|
335
|
+
|
336
|
+
def test_should_perform_joined_include_when_referencing_included_tables
|
337
|
+
joined_count = Account.includes(:firm).where(:companies => {:name => '37signals'}).count
|
338
|
+
assert_equal 1, joined_count
|
339
|
+
end
|
340
|
+
|
257
341
|
def test_should_count_scoped_select
|
258
342
|
Account.update_all("credit_limit = NULL")
|
259
343
|
assert_equal 0, Account.scoped(:select => "credit_limit").count
|
@@ -261,8 +345,8 @@ class CalculationsTest < ActiveRecord::TestCase
|
|
261
345
|
|
262
346
|
def test_should_count_scoped_select_with_options
|
263
347
|
Account.update_all("credit_limit = NULL")
|
264
|
-
Account.last.
|
265
|
-
Account.first.
|
348
|
+
Account.last.update_column('credit_limit', 49)
|
349
|
+
Account.first.update_column('credit_limit', 51)
|
266
350
|
|
267
351
|
assert_equal 1, Account.scoped(:select => "credit_limit").count(:conditions => ['credit_limit >= 50'])
|
268
352
|
end
|
@@ -340,7 +424,7 @@ class CalculationsTest < ActiveRecord::TestCase
|
|
340
424
|
end
|
341
425
|
|
342
426
|
def test_from_option_with_specified_index
|
343
|
-
if Edge.connection.adapter_name == 'MySQL'
|
427
|
+
if Edge.connection.adapter_name == 'MySQL' or Edge.connection.adapter_name == 'Mysql2'
|
344
428
|
assert_equal Edge.count(:all), Edge.count(:all, :from => 'edges USE INDEX(unique_edge_index)')
|
345
429
|
assert_equal Edge.count(:all, :conditions => 'sink_id < 5'),
|
346
430
|
Edge.count(:all, :from => 'edges USE INDEX(unique_edge_index)', :conditions => 'sink_id < 5')
|
@@ -5,10 +5,8 @@ require 'models/person'
|
|
5
5
|
require 'models/topic'
|
6
6
|
require 'models/developer'
|
7
7
|
|
8
|
-
require MIGRATIONS_ROOT + "/valid/1_people_have_last_names"
|
9
8
|
require MIGRATIONS_ROOT + "/valid/2_we_need_reminders"
|
10
9
|
require MIGRATIONS_ROOT + "/decimal/1_give_me_big_numbers"
|
11
|
-
require MIGRATIONS_ROOT + "/interleaved/pass_3/2_i_raise_on_down"
|
12
10
|
|
13
11
|
if ActiveRecord::Base.connection.supports_migrations?
|
14
12
|
class BigNumber < ActiveRecord::Base; end
|
@@ -16,12 +14,13 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
16
14
|
class Reminder < ActiveRecord::Base; end
|
17
15
|
|
18
16
|
class ActiveRecord::Migration
|
19
|
-
class <<self
|
17
|
+
class << self
|
20
18
|
attr_accessor :message_count
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
19
|
+
end
|
20
|
+
|
21
|
+
def puts(text="")
|
22
|
+
ActiveRecord::Migration.message_count ||= 0
|
23
|
+
ActiveRecord::Migration.message_count += 1
|
25
24
|
end
|
26
25
|
end
|
27
26
|
|
@@ -46,6 +45,7 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
46
45
|
|
47
46
|
class MigrationTest < ActiveRecord::TestCase
|
48
47
|
self.use_transactional_fixtures = false
|
48
|
+
|
49
49
|
if (current_adapter?(:IBM_DBAdapter))
|
50
50
|
#Rename is supported only for server zOS 9 , DB2 COBRA and Informix
|
51
51
|
server_type = ActiveRecord::Base.connection.servertype.class.name
|
@@ -58,7 +58,7 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
58
58
|
|
59
59
|
def setup
|
60
60
|
ActiveRecord::Migration.verbose = true
|
61
|
-
|
61
|
+
ActiveRecord::Migration.message_count = 0
|
62
62
|
end
|
63
63
|
|
64
64
|
def teardown
|
@@ -118,7 +118,7 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
118
118
|
# Note: changed index name from "key" to "key_idx" since "key" is a Firebird reserved word
|
119
119
|
# OpenBase does not have named indexes. You must specify a single column name
|
120
120
|
unless current_adapter?(:OpenBaseAdapter)
|
121
|
-
|
121
|
+
unless current_adapter?(:IBM_DBAdapter)
|
122
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
123
|
else
|
124
124
|
Person.update_all "#{Person.connection.quote_column_name 'key'}=#{Person.connection.quote_column_name 'first_name'}"
|
@@ -242,9 +242,9 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
242
242
|
end
|
243
243
|
|
244
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
|
245
|
+
# For DB2: Cannot add a primary key to a table with some rows already in it as it violates the unique constraint
|
246
246
|
# Secondly GENERATED BY DEFAULT AS IDENTITY cannot be applied in a alter table command.
|
247
|
-
# as this will be wrong sql syntax for
|
247
|
+
# as this will be wrong sql syntax for DB
|
248
248
|
def test_add_column_with_primary_key_attribute
|
249
249
|
testing_table_with_only_foo_attribute do |connection|
|
250
250
|
assert_nothing_raised { connection.add_column :testings, :id, :primary_key }
|
@@ -280,16 +280,14 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
280
280
|
|
281
281
|
def test_create_table_with_defaults
|
282
282
|
# MySQL doesn't allow defaults on TEXT or BLOB columns.
|
283
|
-
mysql = current_adapter?(:MysqlAdapter)
|
284
|
-
|
285
|
-
ActiveRecord::Base.connection.servertype.class.name.include?('::IBM_DB2_ZOS')
|
286
|
-
|
283
|
+
mysql = current_adapter?(:MysqlAdapter) || current_adapter?(:Mysql2Adapter)
|
284
|
+
|
287
285
|
Person.connection.create_table :testings do |t|
|
288
286
|
t.column :one, :string, :default => "hello"
|
289
287
|
t.column :two, :boolean, :default => true
|
290
288
|
t.column :three, :boolean, :default => false
|
291
289
|
t.column :four, :integer, :default => 1
|
292
|
-
t.column :five, :text, :default => "hello" unless mysql
|
290
|
+
t.column :five, :text, :default => "hello" unless mysql
|
293
291
|
end
|
294
292
|
|
295
293
|
columns = Person.connection.columns(:testings)
|
@@ -297,65 +295,18 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
297
295
|
two = columns.detect { |c| c.name == "two" }
|
298
296
|
three = columns.detect { |c| c.name == "three" }
|
299
297
|
four = columns.detect { |c| c.name == "four" }
|
300
|
-
five = columns.detect { |c| c.name == "five" } unless mysql
|
298
|
+
five = columns.detect { |c| c.name == "five" } unless mysql
|
301
299
|
|
302
300
|
assert_equal "hello", one.default
|
303
301
|
assert_equal true, two.default
|
304
302
|
assert_equal false, three.default
|
305
303
|
assert_equal 1, four.default
|
306
|
-
assert_equal "hello", five.default unless mysql
|
304
|
+
assert_equal "hello", five.default unless mysql
|
307
305
|
|
308
306
|
ensure
|
309
307
|
Person.connection.drop_table :testings rescue nil
|
310
308
|
end
|
311
309
|
|
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
310
|
def test_create_table_with_limits
|
360
311
|
assert_nothing_raised do
|
361
312
|
Person.connection.create_table :testings do |t|
|
@@ -487,7 +438,7 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
487
438
|
|
488
439
|
# Sybase, and SQLite3 will not allow you to add a NOT NULL
|
489
440
|
# column to a table without a default value.
|
490
|
-
unless current_adapter?(:SybaseAdapter, :
|
441
|
+
unless current_adapter?(:SybaseAdapter, :SQLite3Adapter, :IBM_DBAdapter)
|
491
442
|
def test_add_column_not_null_without_default
|
492
443
|
Person.connection.create_table :testings do |t|
|
493
444
|
t.column :foo, :string
|
@@ -609,7 +560,7 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
609
560
|
assert_equal "I was born ....", bob.bio
|
610
561
|
assert_equal 18, bob.age
|
611
562
|
|
612
|
-
# Test for 30
|
563
|
+
# Test for 30 significant digits (beyond the 16 of float), 10 of them
|
613
564
|
# after the decimal place.
|
614
565
|
|
615
566
|
unless current_adapter?(:SQLite3Adapter)
|
@@ -742,17 +693,17 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
742
693
|
end
|
743
694
|
end
|
744
695
|
|
745
|
-
if
|
696
|
+
if(!current_adapter?(:IBM_DBAdapter) || @ibm_db_rename_supported)
|
746
697
|
def test_add_rename
|
747
698
|
Person.delete_all
|
748
|
-
|
699
|
+
|
749
700
|
begin
|
750
701
|
Person.connection.add_column "people", "girlfriend", :string
|
751
702
|
Person.reset_column_information
|
752
703
|
Person.create :girlfriend => 'bobette'
|
753
|
-
|
704
|
+
|
754
705
|
Person.connection.rename_column "people", "girlfriend", "exgirlfriend"
|
755
|
-
|
706
|
+
|
756
707
|
Person.reset_column_information
|
757
708
|
bob = Person.find(:first)
|
758
709
|
|
@@ -763,7 +714,7 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
763
714
|
end
|
764
715
|
|
765
716
|
end
|
766
|
-
|
717
|
+
|
767
718
|
def test_rename_column_using_symbol_arguments
|
768
719
|
begin
|
769
720
|
names_before = Person.find(:all).map(&:first_name)
|
@@ -809,7 +760,7 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
809
760
|
ActiveRecord::Base.connection.create_table(:hats) do |table|
|
810
761
|
table.column :hat_name, :string, :default => nil
|
811
762
|
end
|
812
|
-
exception = if current_adapter?(:PostgreSQLAdapter)
|
763
|
+
exception = if current_adapter?(:PostgreSQLAdapter, :OracleAdapter)
|
813
764
|
ActiveRecord::StatementInvalid
|
814
765
|
else
|
815
766
|
ActiveRecord::ActiveRecordError
|
@@ -833,7 +784,7 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
833
784
|
end
|
834
785
|
end
|
835
786
|
|
836
|
-
unless
|
787
|
+
unless current_adapter?(:IBM_DBAdapter)
|
837
788
|
def test_rename_column_with_an_index
|
838
789
|
ActiveRecord::Base.connection.create_table(:hats) do |table|
|
839
790
|
table.column :hat_name, :string, :limit => 100
|
@@ -848,59 +799,62 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
848
799
|
end
|
849
800
|
end
|
850
801
|
|
851
|
-
def
|
802
|
+
def test_remove_column_with_index
|
852
803
|
ActiveRecord::Base.connection.create_table(:hats) do |table|
|
853
804
|
table.column :hat_name, :string, :limit => 100
|
854
805
|
table.column :hat_size, :integer
|
855
806
|
end
|
856
|
-
|
857
|
-
|
858
|
-
|
859
|
-
end
|
807
|
+
ActiveRecord::Base.connection.add_index "hats", "hat_size"
|
808
|
+
|
809
|
+
assert_nothing_raised { Person.connection.remove_column("hats", "hat_size") }
|
860
810
|
ensure
|
861
811
|
ActiveRecord::Base.connection.drop_table(:hats)
|
862
812
|
end
|
863
813
|
|
864
|
-
def
|
814
|
+
def test_remove_column_with_multi_column_index
|
865
815
|
ActiveRecord::Base.connection.create_table(:hats) do |table|
|
866
816
|
table.column :hat_name, :string, :limit => 100
|
867
817
|
table.column :hat_size, :integer
|
818
|
+
table.column :hat_style, :string, :limit => 100
|
868
819
|
end
|
869
|
-
ActiveRecord::Base.connection.add_index "hats", "hat_size"
|
820
|
+
ActiveRecord::Base.connection.add_index "hats", ["hat_style", "hat_size"], :unique => true
|
870
821
|
|
871
822
|
assert_nothing_raised { Person.connection.remove_column("hats", "hat_size") }
|
872
823
|
ensure
|
873
824
|
ActiveRecord::Base.connection.drop_table(:hats)
|
874
825
|
end
|
875
826
|
|
876
|
-
|
877
|
-
|
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
|
827
|
+
def test_remove_column_no_second_parameter_raises_exception
|
828
|
+
assert_raise(ArgumentError) { Person.connection.remove_column("funny") }
|
889
829
|
end
|
890
830
|
|
891
|
-
|
892
|
-
|
893
|
-
|
831
|
+
def test_change_type_of_not_null_column
|
832
|
+
assert_nothing_raised do
|
833
|
+
unless current_adapter?(:IBM_DBAdapter)
|
894
834
|
Topic.connection.change_column "topics", "written_on", :datetime, :null => false
|
895
|
-
|
835
|
+
else
|
836
|
+
Topic.connection.change_column_null "topics", "written_on", false
|
837
|
+
end
|
838
|
+
Topic.reset_column_information
|
896
839
|
|
840
|
+
unless current_adapter?(:IBM_DBAdapter)
|
897
841
|
Topic.connection.change_column "topics", "written_on", :datetime, :null => false
|
898
|
-
|
842
|
+
else
|
843
|
+
Topic.connection.change_column_null "topics", "written_on", false
|
899
844
|
end
|
845
|
+
Topic.reset_column_information
|
846
|
+
|
847
|
+
unless current_adapter?(:IBM_DBAdapter)
|
848
|
+
Topic.connection.change_column "topics", "written_on", :datetime, :null => true
|
849
|
+
else
|
850
|
+
Topic.connection.change_column_null "topics", "written_on", true
|
851
|
+
end
|
852
|
+
|
853
|
+
Topic.reset_column_information
|
900
854
|
end
|
901
|
-
end
|
855
|
+
end
|
902
856
|
|
903
|
-
if current_adapter?(:
|
857
|
+
if current_adapter?(:SQLite3Adapter)
|
904
858
|
def test_rename_table_for_sqlite_should_work_with_reserved_words
|
905
859
|
begin
|
906
860
|
assert_nothing_raised do
|
@@ -952,14 +906,20 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
952
906
|
Person.connection.add_column "people", "funny", :boolean
|
953
907
|
Person.reset_column_information
|
954
908
|
assert Person.columns_hash["funny"].null, "Column 'funny' must initially allow nulls"
|
955
|
-
|
909
|
+
unless current_adapter?(:IBM_DBAdapter)
|
956
910
|
Person.connection.change_column "people", "funny", :boolean, :null => false, :default => true
|
911
|
+
else
|
912
|
+
Person.connection.change_column_null "people", "funny",false
|
913
|
+
end
|
957
914
|
Person.reset_column_information
|
958
915
|
assert !Person.columns_hash["funny"].null, "Column 'funny' must *not* allow nulls at this point"
|
916
|
+
unless current_adapter?(:IBM_DBAdapter)
|
959
917
|
Person.connection.change_column "people", "funny", :boolean, :null => true
|
960
|
-
|
961
|
-
|
962
|
-
end
|
918
|
+
else
|
919
|
+
Person.connection.change_column_null "people", "funny",true
|
920
|
+
end
|
921
|
+
Person.reset_column_information
|
922
|
+
assert Person.columns_hash["funny"].null, "Column 'funny' must allow nulls again at this point"
|
963
923
|
end
|
964
924
|
|
965
925
|
def test_rename_table_with_an_index
|
@@ -985,39 +945,44 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
985
945
|
end
|
986
946
|
end
|
987
947
|
|
988
|
-
|
989
|
-
|
990
|
-
|
991
|
-
|
992
|
-
|
993
|
-
|
948
|
+
unless current_adapter?(:IBM_DBAdapter)
|
949
|
+
# Cannot convert from type integer to varchar.
|
950
|
+
# Safe to not run this test as add_column will be covered in other test cases
|
951
|
+
def test_change_column
|
952
|
+
Person.connection.add_column 'people', 'age', :integer
|
953
|
+
label = "test_change_column Columns"
|
954
|
+
old_columns = Person.connection.columns(Person.table_name, label)
|
955
|
+
assert old_columns.find { |c| c.name == 'age' and c.type == :integer }
|
994
956
|
|
995
|
-
|
957
|
+
assert_nothing_raised { Person.connection.change_column "people", "age", :string }
|
996
958
|
|
997
|
-
|
998
|
-
|
999
|
-
|
959
|
+
new_columns = Person.connection.columns(Person.table_name, label)
|
960
|
+
assert_nil new_columns.find { |c| c.name == 'age' and c.type == :integer }
|
961
|
+
assert new_columns.find { |c| c.name == 'age' and c.type == :string }
|
1000
962
|
|
1001
|
-
|
1002
|
-
|
1003
|
-
|
1004
|
-
|
1005
|
-
|
1006
|
-
|
1007
|
-
|
963
|
+
old_columns = Topic.connection.columns(Topic.table_name, label)
|
964
|
+
assert old_columns.find { |c| c.name == 'approved' and c.type == :boolean and c.default == true }
|
965
|
+
assert_nothing_raised { Topic.connection.change_column :topics, :approved, :boolean, :default => false }
|
966
|
+
new_columns = Topic.connection.columns(Topic.table_name, label)
|
967
|
+
assert_nil new_columns.find { |c| c.name == 'approved' and c.type == :boolean and c.default == true }
|
968
|
+
assert new_columns.find { |c| c.name == 'approved' and c.type == :boolean and c.default == false }
|
969
|
+
assert_nothing_raised { Topic.connection.change_column :topics, :approved, :boolean, :default => true }
|
970
|
+
end
|
1008
971
|
end
|
1009
|
-
|
1010
|
-
|
972
|
+
|
1011
973
|
def test_change_column_with_nil_default
|
1012
974
|
Person.connection.add_column "people", "contributor", :boolean, :default => true
|
1013
975
|
Person.reset_column_information
|
1014
976
|
assert Person.new.contributor?
|
1015
|
-
|
977
|
+
|
978
|
+
unless current_adapter?(:IBM_DBAdapter)
|
1016
979
|
assert_nothing_raised { Person.connection.change_column "people", "contributor", :boolean, :default => nil }
|
1017
|
-
|
1018
|
-
|
1019
|
-
|
1020
|
-
|
980
|
+
else
|
981
|
+
assert_nothing_raised { Person.connection.change_column_default "people", "contributor", nil }
|
982
|
+
end
|
983
|
+
Person.reset_column_information
|
984
|
+
assert !Person.new.contributor?
|
985
|
+
assert_nil Person.new.contributor
|
1021
986
|
ensure
|
1022
987
|
Person.connection.remove_column("people", "contributor") rescue nil
|
1023
988
|
end
|
@@ -1026,11 +991,14 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
1026
991
|
Person.connection.add_column "people", "administrator", :boolean, :default => true
|
1027
992
|
Person.reset_column_information
|
1028
993
|
assert Person.new.administrator?
|
1029
|
-
|
994
|
+
|
995
|
+
unless current_adapter?(:IBM_DBAdapter)
|
1030
996
|
assert_nothing_raised { Person.connection.change_column "people", "administrator", :boolean, :default => false }
|
1031
|
-
|
1032
|
-
|
1033
|
-
end
|
997
|
+
else
|
998
|
+
assert_nothing_raised { Person.connection.change_column_default "people", "administrator", false }
|
999
|
+
end
|
1000
|
+
Person.reset_column_information
|
1001
|
+
assert !Person.new.administrator?
|
1034
1002
|
ensure
|
1035
1003
|
Person.connection.remove_column("people", "administrator") rescue nil
|
1036
1004
|
end
|
@@ -1043,10 +1011,11 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
1043
1011
|
|
1044
1012
|
def test_change_column_quotes_column_names
|
1045
1013
|
Person.connection.create_table :testings do |t|
|
1046
|
-
|
1047
|
-
t.column :select, :string, :limit => 5
|
1048
|
-
else
|
1014
|
+
unless current_adapter?(:IBM_DBAdapter)
|
1049
1015
|
t.column :select, :string
|
1016
|
+
else
|
1017
|
+
# If no limit specified by default column of length 255 is created, which later cannot be scaled down to 10
|
1018
|
+
t.column :select, :string, :limit => 5
|
1050
1019
|
end
|
1051
1020
|
end
|
1052
1021
|
|
@@ -1087,16 +1056,16 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
1087
1056
|
assert_equal false, person_klass.columns_hash["wealth"].null
|
1088
1057
|
|
1089
1058
|
# 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)
|
1059
|
+
if (!current_adapter?(:IBM_DBAdapter) || @ibm_db_rename_supported)
|
1091
1060
|
person_klass.connection.rename_column "testings", "wealth", "money"
|
1092
1061
|
person_klass.reset_column_information
|
1093
1062
|
assert_nil person_klass.columns_hash["wealth"]
|
1094
1063
|
assert_equal 100, person_klass.columns_hash["money"].default
|
1095
1064
|
assert_equal false, person_klass.columns_hash["money"].null
|
1096
|
-
end
|
1065
|
+
end
|
1097
1066
|
|
1098
1067
|
# change column
|
1099
|
-
unless
|
1068
|
+
unless current_adapter?(:IBM_DBAdapter)
|
1100
1069
|
person_klass.connection.change_column "testings", "money", :integer, :null => false, :default => 1000
|
1101
1070
|
person_klass.reset_column_information
|
1102
1071
|
assert_equal 1000, person_klass.columns_hash["money"].default
|
@@ -1106,10 +1075,10 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
1106
1075
|
person_klass.reset_column_information
|
1107
1076
|
assert_equal 1000, person_klass.columns_hash["wealth"].default
|
1108
1077
|
assert_equal false, person_klass.columns_hash["wealth"].null
|
1109
|
-
end
|
1078
|
+
end
|
1110
1079
|
|
1111
1080
|
# change column, make it nullable and clear default
|
1112
|
-
unless
|
1081
|
+
unless current_adapter?(:IBM_DBAdapter)
|
1113
1082
|
person_klass.connection.change_column "testings", "money", :integer, :null => true, :default => nil
|
1114
1083
|
person_klass.reset_column_information
|
1115
1084
|
assert_nil person_klass.columns_hash["money"].default
|
@@ -1119,10 +1088,10 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
1119
1088
|
person_klass.reset_column_information
|
1120
1089
|
assert_nil person_klass.columns_hash["wealth"].default
|
1121
1090
|
assert_equal true, person_klass.columns_hash["wealth"].null
|
1122
|
-
end
|
1091
|
+
end
|
1123
1092
|
|
1124
1093
|
# change_column_null, make it not nullable and set null values to a default value
|
1125
|
-
unless
|
1094
|
+
unless current_adapter?(:IBM_DBAdapter)
|
1126
1095
|
person_klass.connection.execute('UPDATE testings SET money = NULL')
|
1127
1096
|
person_klass.connection.change_column_null "testings", "money", false, 2000
|
1128
1097
|
person_klass.reset_column_information
|
@@ -1131,12 +1100,15 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
1131
1100
|
assert_equal [2000], Person.connection.select_values("SELECT money FROM testings").map { |s| s.to_i }.sort
|
1132
1101
|
else
|
1133
1102
|
# 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
|
1103
|
+
# in the next statement a not null constraint is being applied which is wrong
|
1104
|
+
#person_klass.connection.execute('UPDATE testings SET money = NULL')
|
1136
1105
|
person_klass.connection.change_column_null "testings", "wealth", false, 2000
|
1137
1106
|
person_klass.reset_column_information
|
1107
|
+
#assert_nil person_klass.columns_hash["wealth"].default #Setting default to 2000 and expecting nil is nor correct
|
1108
|
+
assert_not_nil person_klass.columns_hash["wealth"].default
|
1138
1109
|
assert_equal false, person_klass.columns_hash["wealth"].null
|
1139
|
-
|
1110
|
+
#Changing default does not change the already inserted value. Hence expecting 2000 is wrong.
|
1111
|
+
assert_equal [99], Person.connection.select_values("SELECT wealth FROM testings").map { |s| s.to_i }.sort
|
1140
1112
|
end
|
1141
1113
|
ensure
|
1142
1114
|
Person.connection.drop_table :testings rescue nil
|
@@ -1187,6 +1159,18 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
1187
1159
|
Person.connection.drop_table :testings rescue nil
|
1188
1160
|
end
|
1189
1161
|
|
1162
|
+
def test_column_exists_on_table_with_no_options_parameter_supplied
|
1163
|
+
Person.connection.create_table :testings do |t|
|
1164
|
+
t.string :foo
|
1165
|
+
end
|
1166
|
+
Person.connection.change_table :testings do |t|
|
1167
|
+
assert t.column_exists?(:foo)
|
1168
|
+
assert !(t.column_exists?(:bar))
|
1169
|
+
end
|
1170
|
+
ensure
|
1171
|
+
Person.connection.drop_table :testings rescue nil
|
1172
|
+
end
|
1173
|
+
|
1190
1174
|
def test_add_table
|
1191
1175
|
assert !Reminder.table_exists?
|
1192
1176
|
|
@@ -1224,17 +1208,17 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
1224
1208
|
|
1225
1209
|
# TODO: set world_population >= 2**62 to cover 64-bit platforms and test
|
1226
1210
|
# is_a?(Bignum)
|
1227
|
-
unless current_adapter?(:IBM_DBAdapter)
|
1211
|
+
unless current_adapter?(:IBM_DBAdapter)
|
1228
1212
|
assert_kind_of Integer, b.world_population
|
1229
1213
|
else
|
1230
1214
|
assert_kind_of BigDecimal, b.world_population
|
1231
|
-
end
|
1215
|
+
end
|
1232
1216
|
assert_equal 6000000000, b.world_population
|
1233
|
-
unless current_adapter?(:IBM_DBAdapter)
|
1217
|
+
unless current_adapter?(:IBM_DBAdapter)
|
1234
1218
|
assert_kind_of Fixnum, b.my_house_population
|
1235
1219
|
else
|
1236
1220
|
assert_kind_of BigDecimal, b.my_house_population
|
1237
|
-
end
|
1221
|
+
end
|
1238
1222
|
assert_equal 3, b.my_house_population
|
1239
1223
|
assert_kind_of BigDecimal, b.bank_balance
|
1240
1224
|
assert_equal BigDecimal("1586.43"), b.bank_balance
|
@@ -1254,17 +1238,17 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
1254
1238
|
# so this happens there too
|
1255
1239
|
assert_kind_of BigDecimal, b.value_of_e
|
1256
1240
|
assert_equal BigDecimal("2.7182818284590452353602875"), b.value_of_e
|
1257
|
-
elsif current_adapter?(:
|
1241
|
+
elsif current_adapter?(:SQLite3Adapter)
|
1258
1242
|
# - SQLite3 stores a float, in violation of SQL
|
1259
1243
|
assert_kind_of BigDecimal, b.value_of_e
|
1260
1244
|
assert_in_delta BigDecimal("2.71828182845905"), b.value_of_e, 0.00000000000001
|
1261
1245
|
else
|
1262
1246
|
# - SQL standard is an integer
|
1263
|
-
|
1264
|
-
|
1265
|
-
|
1266
|
-
|
1267
|
-
|
1247
|
+
unless current_adapter?(:IBM_DBAdapter)
|
1248
|
+
assert_kind_of Fixnum, b.value_of_e
|
1249
|
+
else
|
1250
|
+
assert_kind_of BigDecimal, b.value_of_e
|
1251
|
+
end
|
1268
1252
|
assert_equal 2, b.value_of_e
|
1269
1253
|
end
|
1270
1254
|
|
@@ -1292,6 +1276,44 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
1292
1276
|
assert_raise(ActiveRecord::StatementInvalid) { Reminder.find(:first) }
|
1293
1277
|
end
|
1294
1278
|
|
1279
|
+
class MockMigration < ActiveRecord::Migration
|
1280
|
+
attr_reader :went_up, :went_down
|
1281
|
+
def initialize
|
1282
|
+
@went_up = false
|
1283
|
+
@went_down = false
|
1284
|
+
end
|
1285
|
+
|
1286
|
+
def up
|
1287
|
+
@went_up = true
|
1288
|
+
super
|
1289
|
+
end
|
1290
|
+
|
1291
|
+
def down
|
1292
|
+
@went_down = true
|
1293
|
+
super
|
1294
|
+
end
|
1295
|
+
end
|
1296
|
+
|
1297
|
+
def test_instance_based_migration_up
|
1298
|
+
migration = MockMigration.new
|
1299
|
+
assert !migration.went_up, 'have not gone up'
|
1300
|
+
assert !migration.went_down, 'have not gone down'
|
1301
|
+
|
1302
|
+
migration.migrate :up
|
1303
|
+
assert migration.went_up, 'have gone up'
|
1304
|
+
assert !migration.went_down, 'have not gone down'
|
1305
|
+
end
|
1306
|
+
|
1307
|
+
def test_instance_based_migration_down
|
1308
|
+
migration = MockMigration.new
|
1309
|
+
assert !migration.went_up, 'have not gone up'
|
1310
|
+
assert !migration.went_down, 'have not gone down'
|
1311
|
+
|
1312
|
+
migration.migrate :down
|
1313
|
+
assert !migration.went_up, 'have gone up'
|
1314
|
+
assert migration.went_down, 'have not gone down'
|
1315
|
+
end
|
1316
|
+
|
1295
1317
|
def test_migrator_one_up
|
1296
1318
|
assert !Person.column_methods_hash.include?(:last_name)
|
1297
1319
|
assert !Reminder.table_exists?
|
@@ -1359,51 +1381,56 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
1359
1381
|
def test_finds_migrations
|
1360
1382
|
migrations = ActiveRecord::Migrator.new(:up, MIGRATIONS_ROOT + "/valid").migrations
|
1361
1383
|
|
1362
|
-
[[1, '
|
1384
|
+
[[1, 'ValidPeopleHaveLastNames'], [2, 'WeNeedReminders'], [3, 'InnocentJointable']].each_with_index do |pair, i|
|
1363
1385
|
assert_equal migrations[i].version, pair.first
|
1364
1386
|
assert_equal migrations[i].name, pair.last
|
1365
1387
|
end
|
1366
1388
|
end
|
1367
1389
|
|
1390
|
+
def test_finds_migrations_from_two_directories
|
1391
|
+
directories = [MIGRATIONS_ROOT + '/valid_with_timestamps', MIGRATIONS_ROOT + '/to_copy_with_timestamps']
|
1392
|
+
migrations = ActiveRecord::Migrator.new(:up, directories).migrations
|
1393
|
+
|
1394
|
+
[[20090101010101, "PeopleHaveHobbies"],
|
1395
|
+
[20090101010202, "PeopleHaveDescriptions"],
|
1396
|
+
[20100101010101, "ValidWithTimestampsPeopleHaveLastNames"],
|
1397
|
+
[20100201010101, "ValidWithTimestampsWeNeedReminders"],
|
1398
|
+
[20100301010101, "ValidWithTimestampsInnocentJointable"]].each_with_index do |pair, i|
|
1399
|
+
assert_equal pair.first, migrations[i].version
|
1400
|
+
assert_equal pair.last, migrations[i].name
|
1401
|
+
end
|
1402
|
+
end
|
1403
|
+
|
1368
1404
|
def test_finds_pending_migrations
|
1369
1405
|
ActiveRecord::Migrator.up(MIGRATIONS_ROOT + "/interleaved/pass_2", 1)
|
1370
1406
|
migrations = ActiveRecord::Migrator.new(:up, MIGRATIONS_ROOT + "/interleaved/pass_2").pending_migrations
|
1371
1407
|
|
1372
1408
|
assert_equal 1, migrations.size
|
1373
1409
|
assert_equal migrations[0].version, 3
|
1374
|
-
assert_equal migrations[0].name, '
|
1410
|
+
assert_equal migrations[0].name, 'InterleavedInnocentJointable'
|
1375
1411
|
end
|
1376
1412
|
|
1377
1413
|
def test_relative_migrations
|
1378
|
-
|
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
|
1414
|
+
list = Dir.chdir(MIGRATIONS_ROOT) do
|
1384
1415
|
ActiveRecord::Migrator.up("valid/", 1)
|
1385
1416
|
end
|
1386
1417
|
|
1387
|
-
|
1418
|
+
migration_proxy = list.find { |item|
|
1419
|
+
item.name == 'ValidPeopleHaveLastNames'
|
1420
|
+
}
|
1421
|
+
assert migration_proxy, 'should find pending migration'
|
1388
1422
|
end
|
1389
1423
|
|
1390
1424
|
def test_only_loads_pending_migrations
|
1391
1425
|
# migrate up to 1
|
1392
1426
|
ActiveRecord::Migrator.up(MIGRATIONS_ROOT + "/valid", 1)
|
1393
1427
|
|
1394
|
-
|
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
|
1428
|
+
proxies = ActiveRecord::Migrator.migrate(MIGRATIONS_ROOT + "/valid", nil)
|
1404
1429
|
|
1405
|
-
|
1406
|
-
|
1430
|
+
names = proxies.map(&:name)
|
1431
|
+
assert !names.include?('ValidPeopleHaveLastNames')
|
1432
|
+
assert names.include?('WeNeedReminders')
|
1433
|
+
assert names.include?('InnocentJointable')
|
1407
1434
|
end
|
1408
1435
|
|
1409
1436
|
def test_target_version_zero_should_run_only_once
|
@@ -1413,16 +1440,9 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
1413
1440
|
# migrate down to 0
|
1414
1441
|
ActiveRecord::Migrator.migrate(MIGRATIONS_ROOT + "/valid", 0)
|
1415
1442
|
|
1416
|
-
# now unload the migrations that have been defined
|
1417
|
-
PeopleHaveLastNames.unloadable
|
1418
|
-
ActiveSupport::Dependencies.remove_unloadable_constants!
|
1419
|
-
|
1420
1443
|
# 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")
|
1444
|
+
proxies = ActiveRecord::Migrator.migrate(MIGRATIONS_ROOT + "/valid", 0)
|
1445
|
+
assert_equal [], proxies
|
1426
1446
|
end
|
1427
1447
|
|
1428
1448
|
def test_migrator_db_has_no_schema_migrations_table
|
@@ -1439,20 +1459,20 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
1439
1459
|
|
1440
1460
|
def test_migrator_verbosity
|
1441
1461
|
ActiveRecord::Migrator.up(MIGRATIONS_ROOT + "/valid", 1)
|
1442
|
-
|
1443
|
-
|
1462
|
+
assert_not_equal 0, ActiveRecord::Migration.message_count
|
1463
|
+
ActiveRecord::Migration.message_count = 0
|
1444
1464
|
|
1445
1465
|
ActiveRecord::Migrator.down(MIGRATIONS_ROOT + "/valid", 0)
|
1446
|
-
|
1447
|
-
|
1466
|
+
assert_not_equal 0, ActiveRecord::Migration.message_count
|
1467
|
+
ActiveRecord::Migration.message_count = 0
|
1448
1468
|
end
|
1449
1469
|
|
1450
1470
|
def test_migrator_verbosity_off
|
1451
|
-
|
1471
|
+
ActiveRecord::Migration.verbose = false
|
1452
1472
|
ActiveRecord::Migrator.up(MIGRATIONS_ROOT + "/valid", 1)
|
1453
|
-
|
1473
|
+
assert_equal 0, ActiveRecord::Migration.message_count
|
1454
1474
|
ActiveRecord::Migrator.down(MIGRATIONS_ROOT + "/valid", 0)
|
1455
|
-
|
1475
|
+
assert_equal 0, ActiveRecord::Migration.message_count
|
1456
1476
|
end
|
1457
1477
|
|
1458
1478
|
def test_migrator_going_down_due_to_version_target
|
@@ -1715,13 +1735,23 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
1715
1735
|
end
|
1716
1736
|
end
|
1717
1737
|
|
1718
|
-
if current_adapter?(:PostgreSQLAdapter)
|
1738
|
+
if current_adapter?(:PostgreSQLAdapter) || current_adapter?(:SQLite3Adapter) || current_adapter?(:MysqlAdapter) || current_adapter?(:Mysql2Adapter) || current_adapter?(:IBM_DBAdapter)
|
1719
1739
|
def test_xml_creates_xml_column
|
1740
|
+
type = (current_adapter?(:PostgreSQLAdapter) || current_adapter?(:IBM_DBAdapter)) ? 'xml' : :text
|
1741
|
+
|
1720
1742
|
with_new_table do |t|
|
1721
|
-
t.expects(:column).with(:data,
|
1743
|
+
t.expects(:column).with(:data, type, {})
|
1722
1744
|
t.xml :data
|
1723
1745
|
end
|
1724
1746
|
end
|
1747
|
+
else
|
1748
|
+
def test_xml_creates_xml_column
|
1749
|
+
with_new_table do |t|
|
1750
|
+
assert_raises(NotImplementedError) do
|
1751
|
+
t.xml :data
|
1752
|
+
end
|
1753
|
+
end
|
1754
|
+
end
|
1725
1755
|
end
|
1726
1756
|
|
1727
1757
|
protected
|
@@ -1736,10 +1766,6 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
1736
1766
|
end # SexyMigrationsTest
|
1737
1767
|
|
1738
1768
|
class MigrationLoggerTest < ActiveRecord::TestCase
|
1739
|
-
def setup
|
1740
|
-
Object.send(:remove_const, :InnocentJointable)
|
1741
|
-
end
|
1742
|
-
|
1743
1769
|
def test_migration_should_be_run_without_logger
|
1744
1770
|
previous_logger = ActiveRecord::Base.logger
|
1745
1771
|
ActiveRecord::Base.logger = nil
|
@@ -1752,10 +1778,6 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
1752
1778
|
end
|
1753
1779
|
|
1754
1780
|
class InterleavedMigrationsTest < ActiveRecord::TestCase
|
1755
|
-
def setup
|
1756
|
-
Object.send(:remove_const, :PeopleHaveLastNames)
|
1757
|
-
end
|
1758
|
-
|
1759
1781
|
def test_migrator_interleaved_migrations
|
1760
1782
|
ActiveRecord::Migrator.up(MIGRATIONS_ROOT + "/interleaved/pass_1")
|
1761
1783
|
|
@@ -1766,10 +1788,12 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
1766
1788
|
Person.reset_column_information
|
1767
1789
|
assert Person.column_methods_hash.include?(:last_name)
|
1768
1790
|
|
1769
|
-
Object.send(:remove_const, :PeopleHaveLastNames)
|
1770
|
-
Object.send(:remove_const, :InnocentJointable)
|
1771
1791
|
assert_nothing_raised do
|
1772
|
-
ActiveRecord::Migrator.down(
|
1792
|
+
proxies = ActiveRecord::Migrator.down(
|
1793
|
+
MIGRATIONS_ROOT + "/interleaved/pass_3")
|
1794
|
+
names = proxies.map(&:name)
|
1795
|
+
assert names.include?('InterleavedPeopleHaveLastNames')
|
1796
|
+
assert names.include?('InterleavedInnocentJointable')
|
1773
1797
|
end
|
1774
1798
|
end
|
1775
1799
|
end
|
@@ -2010,5 +2034,307 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
2010
2034
|
end
|
2011
2035
|
end
|
2012
2036
|
end
|
2013
|
-
end
|
2014
2037
|
|
2038
|
+
if ActiveRecord::Base.connection.supports_bulk_alter?
|
2039
|
+
class BulkAlterTableMigrationsTest < ActiveRecord::TestCase
|
2040
|
+
def setup
|
2041
|
+
@connection = Person.connection
|
2042
|
+
@connection.create_table(:delete_me, :force => true) {|t| }
|
2043
|
+
end
|
2044
|
+
|
2045
|
+
def teardown
|
2046
|
+
Person.connection.drop_table(:delete_me) rescue nil
|
2047
|
+
end
|
2048
|
+
|
2049
|
+
def test_adding_multiple_columns
|
2050
|
+
assert_queries(1) do
|
2051
|
+
with_bulk_change_table do |t|
|
2052
|
+
t.column :name, :string
|
2053
|
+
t.string :qualification, :experience
|
2054
|
+
t.integer :age, :default => 0
|
2055
|
+
t.date :birthdate
|
2056
|
+
t.timestamps
|
2057
|
+
end
|
2058
|
+
end
|
2059
|
+
|
2060
|
+
assert_equal 8, columns.size
|
2061
|
+
[:name, :qualification, :experience].each {|s| assert_equal :string, column(s).type }
|
2062
|
+
assert_equal 0, column(:age).default
|
2063
|
+
end
|
2064
|
+
|
2065
|
+
def test_removing_columns
|
2066
|
+
with_bulk_change_table do |t|
|
2067
|
+
t.string :qualification, :experience
|
2068
|
+
end
|
2069
|
+
|
2070
|
+
[:qualification, :experience].each {|c| assert column(c) }
|
2071
|
+
|
2072
|
+
assert_queries(1) do
|
2073
|
+
with_bulk_change_table do |t|
|
2074
|
+
t.remove :qualification, :experience
|
2075
|
+
t.string :qualification_experience
|
2076
|
+
end
|
2077
|
+
end
|
2078
|
+
|
2079
|
+
[:qualification, :experience].each {|c| assert ! column(c) }
|
2080
|
+
assert column(:qualification_experience)
|
2081
|
+
end
|
2082
|
+
|
2083
|
+
def test_adding_indexes
|
2084
|
+
with_bulk_change_table do |t|
|
2085
|
+
t.string :username
|
2086
|
+
t.string :name
|
2087
|
+
t.integer :age
|
2088
|
+
end
|
2089
|
+
|
2090
|
+
# Adding an index fires a query every time to check if an index already exists or not
|
2091
|
+
assert_queries(3) do
|
2092
|
+
with_bulk_change_table do |t|
|
2093
|
+
t.index :username, :unique => true, :name => :awesome_username_index
|
2094
|
+
t.index [:name, :age]
|
2095
|
+
end
|
2096
|
+
end
|
2097
|
+
|
2098
|
+
assert_equal 2, indexes.size
|
2099
|
+
|
2100
|
+
name_age_index = index(:index_delete_me_on_name_and_age)
|
2101
|
+
assert_equal ['name', 'age'].sort, name_age_index.columns.sort
|
2102
|
+
assert ! name_age_index.unique
|
2103
|
+
|
2104
|
+
assert index(:awesome_username_index).unique
|
2105
|
+
end
|
2106
|
+
|
2107
|
+
def test_removing_index
|
2108
|
+
with_bulk_change_table do |t|
|
2109
|
+
t.string :name
|
2110
|
+
t.index :name
|
2111
|
+
end
|
2112
|
+
|
2113
|
+
assert index(:index_delete_me_on_name)
|
2114
|
+
|
2115
|
+
assert_queries(3) do
|
2116
|
+
with_bulk_change_table do |t|
|
2117
|
+
t.remove_index :name
|
2118
|
+
t.index :name, :name => :new_name_index, :unique => true
|
2119
|
+
end
|
2120
|
+
end
|
2121
|
+
|
2122
|
+
assert ! index(:index_delete_me_on_name)
|
2123
|
+
|
2124
|
+
new_name_index = index(:new_name_index)
|
2125
|
+
assert new_name_index.unique
|
2126
|
+
end
|
2127
|
+
|
2128
|
+
def test_changing_columns
|
2129
|
+
with_bulk_change_table do |t|
|
2130
|
+
t.string :name
|
2131
|
+
t.date :birthdate
|
2132
|
+
end
|
2133
|
+
|
2134
|
+
assert ! column(:name).default
|
2135
|
+
assert_equal :date, column(:birthdate).type
|
2136
|
+
|
2137
|
+
# One query for columns (delete_me table)
|
2138
|
+
# One query for primary key (delete_me table)
|
2139
|
+
# One query to do the bulk change
|
2140
|
+
assert_queries(3) do
|
2141
|
+
with_bulk_change_table do |t|
|
2142
|
+
t.change :name, :string, :default => 'NONAME'
|
2143
|
+
t.change :birthdate, :datetime
|
2144
|
+
end
|
2145
|
+
end
|
2146
|
+
|
2147
|
+
assert_equal 'NONAME', column(:name).default
|
2148
|
+
assert_equal :datetime, column(:birthdate).type
|
2149
|
+
end
|
2150
|
+
|
2151
|
+
protected
|
2152
|
+
|
2153
|
+
def with_bulk_change_table
|
2154
|
+
# Reset columns/indexes cache as we're changing the table
|
2155
|
+
@columns = @indexes = nil
|
2156
|
+
|
2157
|
+
Person.connection.change_table(:delete_me, :bulk => true) do |t|
|
2158
|
+
yield t
|
2159
|
+
end
|
2160
|
+
end
|
2161
|
+
|
2162
|
+
def column(name)
|
2163
|
+
columns.detect {|c| c.name == name.to_s }
|
2164
|
+
end
|
2165
|
+
|
2166
|
+
def columns
|
2167
|
+
@columns ||= Person.connection.columns('delete_me')
|
2168
|
+
end
|
2169
|
+
|
2170
|
+
def index(name)
|
2171
|
+
indexes.detect {|i| i.name == name.to_s }
|
2172
|
+
end
|
2173
|
+
|
2174
|
+
def indexes
|
2175
|
+
@indexes ||= Person.connection.indexes('delete_me')
|
2176
|
+
end
|
2177
|
+
end # AlterTableMigrationsTest
|
2178
|
+
|
2179
|
+
end
|
2180
|
+
|
2181
|
+
class CopyMigrationsTest < ActiveRecord::TestCase
|
2182
|
+
def setup
|
2183
|
+
end
|
2184
|
+
|
2185
|
+
def clear
|
2186
|
+
ActiveRecord::Base.timestamped_migrations = true
|
2187
|
+
to_delete = Dir[@migrations_path + "/*.rb"] - @existing_migrations
|
2188
|
+
File.delete(*to_delete)
|
2189
|
+
end
|
2190
|
+
|
2191
|
+
def test_copying_migrations_without_timestamps
|
2192
|
+
ActiveRecord::Base.timestamped_migrations = false
|
2193
|
+
@migrations_path = MIGRATIONS_ROOT + "/valid"
|
2194
|
+
@existing_migrations = Dir[@migrations_path + "/*.rb"]
|
2195
|
+
|
2196
|
+
copied = ActiveRecord::Migration.copy(@migrations_path, {:bukkits => MIGRATIONS_ROOT + "/to_copy"})
|
2197
|
+
assert File.exists?(@migrations_path + "/4_people_have_hobbies.rb")
|
2198
|
+
assert File.exists?(@migrations_path + "/5_people_have_descriptions.rb")
|
2199
|
+
assert_equal [@migrations_path + "/4_people_have_hobbies.rb", @migrations_path + "/5_people_have_descriptions.rb"], copied.map(&:filename)
|
2200
|
+
|
2201
|
+
files_count = Dir[@migrations_path + "/*.rb"].length
|
2202
|
+
copied = ActiveRecord::Migration.copy(@migrations_path, {:bukkits => MIGRATIONS_ROOT + "/to_copy"})
|
2203
|
+
assert_equal files_count, Dir[@migrations_path + "/*.rb"].length
|
2204
|
+
assert copied.empty?
|
2205
|
+
ensure
|
2206
|
+
clear
|
2207
|
+
end
|
2208
|
+
|
2209
|
+
def test_copying_migrations_without_timestamps_from_2_sources
|
2210
|
+
ActiveRecord::Base.timestamped_migrations = false
|
2211
|
+
@migrations_path = MIGRATIONS_ROOT + "/valid"
|
2212
|
+
@existing_migrations = Dir[@migrations_path + "/*.rb"]
|
2213
|
+
|
2214
|
+
sources = ActiveSupport::OrderedHash.new
|
2215
|
+
sources[:bukkits] = MIGRATIONS_ROOT + "/to_copy"
|
2216
|
+
sources[:omg] = MIGRATIONS_ROOT + "/to_copy2"
|
2217
|
+
ActiveRecord::Migration.copy(@migrations_path, sources)
|
2218
|
+
assert File.exists?(@migrations_path + "/4_people_have_hobbies.rb")
|
2219
|
+
assert File.exists?(@migrations_path + "/5_people_have_descriptions.rb")
|
2220
|
+
assert File.exists?(@migrations_path + "/6_create_articles.rb")
|
2221
|
+
assert File.exists?(@migrations_path + "/7_create_comments.rb")
|
2222
|
+
|
2223
|
+
files_count = Dir[@migrations_path + "/*.rb"].length
|
2224
|
+
ActiveRecord::Migration.copy(@migrations_path, sources)
|
2225
|
+
assert_equal files_count, Dir[@migrations_path + "/*.rb"].length
|
2226
|
+
ensure
|
2227
|
+
clear
|
2228
|
+
end
|
2229
|
+
|
2230
|
+
def test_copying_migrations_with_timestamps
|
2231
|
+
@migrations_path = MIGRATIONS_ROOT + "/valid_with_timestamps"
|
2232
|
+
@existing_migrations = Dir[@migrations_path + "/*.rb"]
|
2233
|
+
|
2234
|
+
Time.travel_to(Time.utc(2010, 7, 26, 10, 10, 10)) do
|
2235
|
+
copied = ActiveRecord::Migration.copy(@migrations_path, {:bukkits => MIGRATIONS_ROOT + "/to_copy_with_timestamps"})
|
2236
|
+
assert File.exists?(@migrations_path + "/20100726101010_people_have_hobbies.rb")
|
2237
|
+
assert File.exists?(@migrations_path + "/20100726101011_people_have_descriptions.rb")
|
2238
|
+
expected = [@migrations_path + "/20100726101010_people_have_hobbies.rb",
|
2239
|
+
@migrations_path + "/20100726101011_people_have_descriptions.rb"]
|
2240
|
+
assert_equal expected, copied.map(&:filename)
|
2241
|
+
|
2242
|
+
files_count = Dir[@migrations_path + "/*.rb"].length
|
2243
|
+
copied = ActiveRecord::Migration.copy(@migrations_path, {:bukkits => MIGRATIONS_ROOT + "/to_copy_with_timestamps"})
|
2244
|
+
assert_equal files_count, Dir[@migrations_path + "/*.rb"].length
|
2245
|
+
assert copied.empty?
|
2246
|
+
end
|
2247
|
+
ensure
|
2248
|
+
clear
|
2249
|
+
end
|
2250
|
+
|
2251
|
+
def test_copying_migrations_with_timestamps_from_2_sources
|
2252
|
+
@migrations_path = MIGRATIONS_ROOT + "/valid_with_timestamps"
|
2253
|
+
@existing_migrations = Dir[@migrations_path + "/*.rb"]
|
2254
|
+
|
2255
|
+
sources = ActiveSupport::OrderedHash.new
|
2256
|
+
sources[:bukkits] = MIGRATIONS_ROOT + "/to_copy_with_timestamps"
|
2257
|
+
sources[:omg] = MIGRATIONS_ROOT + "/to_copy_with_timestamps2"
|
2258
|
+
|
2259
|
+
Time.travel_to(Time.utc(2010, 7, 26, 10, 10, 10)) do
|
2260
|
+
copied = ActiveRecord::Migration.copy(@migrations_path, sources)
|
2261
|
+
assert File.exists?(@migrations_path + "/20100726101010_people_have_hobbies.rb")
|
2262
|
+
assert File.exists?(@migrations_path + "/20100726101011_people_have_descriptions.rb")
|
2263
|
+
assert File.exists?(@migrations_path + "/20100726101012_create_articles.rb")
|
2264
|
+
assert File.exists?(@migrations_path + "/20100726101013_create_comments.rb")
|
2265
|
+
assert_equal 4, copied.length
|
2266
|
+
|
2267
|
+
files_count = Dir[@migrations_path + "/*.rb"].length
|
2268
|
+
ActiveRecord::Migration.copy(@migrations_path, sources)
|
2269
|
+
assert_equal files_count, Dir[@migrations_path + "/*.rb"].length
|
2270
|
+
end
|
2271
|
+
ensure
|
2272
|
+
clear
|
2273
|
+
end
|
2274
|
+
|
2275
|
+
def test_copying_migrations_with_timestamps_to_destination_with_timestamps_in_future
|
2276
|
+
@migrations_path = MIGRATIONS_ROOT + "/valid_with_timestamps"
|
2277
|
+
@existing_migrations = Dir[@migrations_path + "/*.rb"]
|
2278
|
+
|
2279
|
+
Time.travel_to(Time.utc(2010, 2, 20, 10, 10, 10)) do
|
2280
|
+
ActiveRecord::Migration.copy(@migrations_path, {:bukkits => MIGRATIONS_ROOT + "/to_copy_with_timestamps"})
|
2281
|
+
assert File.exists?(@migrations_path + "/20100301010102_people_have_hobbies.rb")
|
2282
|
+
assert File.exists?(@migrations_path + "/20100301010103_people_have_descriptions.rb")
|
2283
|
+
|
2284
|
+
files_count = Dir[@migrations_path + "/*.rb"].length
|
2285
|
+
copied = ActiveRecord::Migration.copy(@migrations_path, {:bukkits => MIGRATIONS_ROOT + "/to_copy_with_timestamps"})
|
2286
|
+
assert_equal files_count, Dir[@migrations_path + "/*.rb"].length
|
2287
|
+
assert copied.empty?
|
2288
|
+
end
|
2289
|
+
ensure
|
2290
|
+
clear
|
2291
|
+
end
|
2292
|
+
|
2293
|
+
def test_skipping_migrations
|
2294
|
+
@migrations_path = MIGRATIONS_ROOT + "/valid_with_timestamps"
|
2295
|
+
@existing_migrations = Dir[@migrations_path + "/*.rb"]
|
2296
|
+
|
2297
|
+
sources = ActiveSupport::OrderedHash.new
|
2298
|
+
sources[:bukkits] = sources[:omg] = MIGRATIONS_ROOT + "/to_copy_with_timestamps"
|
2299
|
+
|
2300
|
+
skipped = []
|
2301
|
+
on_skip = Proc.new { |name, migration| skipped << "#{name} #{migration.name}" }
|
2302
|
+
copied = ActiveRecord::Migration.copy(@migrations_path, sources, :on_skip => on_skip)
|
2303
|
+
assert_equal 2, copied.length
|
2304
|
+
|
2305
|
+
assert_equal 2, skipped.length
|
2306
|
+
assert_equal ["bukkits PeopleHaveHobbies", "bukkits PeopleHaveDescriptions"], skipped
|
2307
|
+
ensure
|
2308
|
+
clear
|
2309
|
+
end
|
2310
|
+
|
2311
|
+
def test_copying_migrations_to_non_existing_directory
|
2312
|
+
@migrations_path = MIGRATIONS_ROOT + "/non_existing"
|
2313
|
+
@existing_migrations = []
|
2314
|
+
|
2315
|
+
Time.travel_to(Time.utc(2010, 7, 26, 10, 10, 10)) do
|
2316
|
+
copied = ActiveRecord::Migration.copy(@migrations_path, {:bukkits => MIGRATIONS_ROOT + "/to_copy_with_timestamps"})
|
2317
|
+
assert File.exists?(@migrations_path + "/20100726101010_people_have_hobbies.rb")
|
2318
|
+
assert File.exists?(@migrations_path + "/20100726101011_people_have_descriptions.rb")
|
2319
|
+
assert_equal 2, copied.length
|
2320
|
+
end
|
2321
|
+
ensure
|
2322
|
+
clear
|
2323
|
+
Dir.delete(@migrations_path)
|
2324
|
+
end
|
2325
|
+
|
2326
|
+
def test_copying_migrations_to_empty_directory
|
2327
|
+
@migrations_path = MIGRATIONS_ROOT + "/empty"
|
2328
|
+
@existing_migrations = []
|
2329
|
+
|
2330
|
+
Time.travel_to(Time.utc(2010, 7, 26, 10, 10, 10)) do
|
2331
|
+
copied = ActiveRecord::Migration.copy(@migrations_path, {:bukkits => MIGRATIONS_ROOT + "/to_copy_with_timestamps"})
|
2332
|
+
assert File.exists?(@migrations_path + "/20100726101010_people_have_hobbies.rb")
|
2333
|
+
assert File.exists?(@migrations_path + "/20100726101011_people_have_descriptions.rb")
|
2334
|
+
assert_equal 2, copied.length
|
2335
|
+
end
|
2336
|
+
ensure
|
2337
|
+
clear
|
2338
|
+
end
|
2339
|
+
end
|
2340
|
+
end
|