odbc-rails 1.2
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/AUTHORS +16 -0
- data/COPYING +21 -0
- data/ChangeLog +89 -0
- data/LICENSE +5 -0
- data/NEWS +12 -0
- data/README +282 -0
- data/lib/active_record/connection_adapters/odbc_adapter.rb +1792 -0
- data/lib/active_record/vendor/odbcext_db2.rb +87 -0
- data/lib/active_record/vendor/odbcext_informix.rb +132 -0
- data/lib/active_record/vendor/odbcext_informix_col.rb +45 -0
- data/lib/active_record/vendor/odbcext_ingres.rb +156 -0
- data/lib/active_record/vendor/odbcext_microsoftsqlserver.rb +185 -0
- data/lib/active_record/vendor/odbcext_microsoftsqlserver_col.rb +40 -0
- data/lib/active_record/vendor/odbcext_mysql.rb +136 -0
- data/lib/active_record/vendor/odbcext_oracle.rb +220 -0
- data/lib/active_record/vendor/odbcext_postgresql.rb +179 -0
- data/lib/active_record/vendor/odbcext_progress.rb +139 -0
- data/lib/active_record/vendor/odbcext_progress89.rb +259 -0
- data/lib/active_record/vendor/odbcext_sybase.rb +212 -0
- data/lib/active_record/vendor/odbcext_sybase_col.rb +49 -0
- data/lib/active_record/vendor/odbcext_virtuoso.rb +146 -0
- data/lib/odbc_adapter.rb +28 -0
- data/support/lib/active_record/connection_adapters/abstract/schema_definitions.rb +259 -0
- data/support/odbc_rails.diff +707 -0
- data/support/pack_odbc.rb +119 -0
- data/support/rake/rails_plugin_package_task.rb +212 -0
- data/support/test/base_test.rb +1349 -0
- data/support/test/migration_test.rb +566 -0
- data/test/connections/native_odbc/connection.rb +95 -0
- data/test/fixtures/db_definitions/db2.drop.sql +30 -0
- data/test/fixtures/db_definitions/db2.sql +217 -0
- data/test/fixtures/db_definitions/db22.drop.sql +2 -0
- data/test/fixtures/db_definitions/db22.sql +5 -0
- data/test/fixtures/db_definitions/informix.drop.sql +30 -0
- data/test/fixtures/db_definitions/informix.sql +205 -0
- data/test/fixtures/db_definitions/informix2.drop.sql +2 -0
- data/test/fixtures/db_definitions/informix2.sql +5 -0
- data/test/fixtures/db_definitions/ingres.drop.sql +62 -0
- data/test/fixtures/db_definitions/ingres.sql +232 -0
- data/test/fixtures/db_definitions/ingres2.drop.sql +2 -0
- data/test/fixtures/db_definitions/ingres2.sql +5 -0
- data/test/fixtures/db_definitions/mysql.drop.sql +30 -0
- data/test/fixtures/db_definitions/mysql.sql +219 -0
- data/test/fixtures/db_definitions/mysql2.drop.sql +2 -0
- data/test/fixtures/db_definitions/mysql2.sql +5 -0
- data/test/fixtures/db_definitions/oracle_odbc.drop.sql +64 -0
- data/test/fixtures/db_definitions/oracle_odbc.sql +257 -0
- data/test/fixtures/db_definitions/oracle_odbc2.drop.sql +2 -0
- data/test/fixtures/db_definitions/oracle_odbc2.sql +6 -0
- data/test/fixtures/db_definitions/progress.drop.sql +61 -0
- data/test/fixtures/db_definitions/progress.sql +234 -0
- data/test/fixtures/db_definitions/progress2.drop.sql +2 -0
- data/test/fixtures/db_definitions/progress2.sql +6 -0
- data/test/fixtures/db_definitions/sqlserver.drop.sql +30 -0
- data/test/fixtures/db_definitions/sqlserver.sql +203 -0
- data/test/fixtures/db_definitions/sqlserver2.drop.sql +2 -0
- data/test/fixtures/db_definitions/sqlserver2.sql +5 -0
- data/test/fixtures/db_definitions/sybase.drop.sql +31 -0
- data/test/fixtures/db_definitions/sybase.sql +204 -0
- data/test/fixtures/db_definitions/sybase2.drop.sql +4 -0
- data/test/fixtures/db_definitions/sybase2.sql +5 -0
- data/test/fixtures/db_definitions/virtuoso.drop.sql +30 -0
- data/test/fixtures/db_definitions/virtuoso.sql +200 -0
- data/test/fixtures/db_definitions/virtuoso2.drop.sql +2 -0
- data/test/fixtures/db_definitions/virtuoso2.sql +5 -0
- metadata +149 -0
@@ -0,0 +1,566 @@
|
|
1
|
+
require 'abstract_unit'
|
2
|
+
require 'fixtures/person'
|
3
|
+
require File.dirname(__FILE__) + '/fixtures/migrations/1_people_have_last_names'
|
4
|
+
require File.dirname(__FILE__) + '/fixtures/migrations/2_we_need_reminders'
|
5
|
+
|
6
|
+
if ActiveRecord::Base.connection.supports_migrations?
|
7
|
+
class Reminder < ActiveRecord::Base; end
|
8
|
+
|
9
|
+
class ActiveRecord::Migration
|
10
|
+
class <<self
|
11
|
+
attr_accessor :message_count
|
12
|
+
def puts(text="")
|
13
|
+
self.message_count ||= 0
|
14
|
+
self.message_count += 1
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class MigrationTest < Test::Unit::TestCase
|
20
|
+
self.use_transactional_fixtures = false
|
21
|
+
|
22
|
+
def setup
|
23
|
+
ActiveRecord::Migration.verbose = true
|
24
|
+
PeopleHaveLastNames.message_count = 0
|
25
|
+
end
|
26
|
+
|
27
|
+
def teardown
|
28
|
+
ActiveRecord::Base.connection.initialize_schema_information
|
29
|
+
ActiveRecord::Base.connection.update "UPDATE #{ActiveRecord::Migrator.schema_info_table_name} SET version = 0"
|
30
|
+
|
31
|
+
Reminder.connection.drop_table("reminders") rescue nil
|
32
|
+
Reminder.connection.drop_table("people_reminders") rescue nil
|
33
|
+
Reminder.connection.drop_table("prefix_reminders_suffix") rescue nil
|
34
|
+
Reminder.reset_column_information
|
35
|
+
|
36
|
+
Person.connection.remove_column("people", "last_name") rescue nil
|
37
|
+
Person.connection.remove_column("people", "key") rescue nil
|
38
|
+
Person.connection.remove_column("people", "bio") rescue nil
|
39
|
+
Person.connection.remove_column("people", "age") rescue nil
|
40
|
+
Person.connection.remove_column("people", "height") rescue nil
|
41
|
+
Person.connection.remove_column("people", "birthday") rescue nil
|
42
|
+
Person.connection.remove_column("people", "favorite_day") rescue nil
|
43
|
+
Person.connection.remove_column("people", "male") rescue nil
|
44
|
+
Person.connection.remove_column("people", "administrator") rescue nil
|
45
|
+
Person.reset_column_information
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_add_index
|
49
|
+
if current_adapter?(:ODBCAdapter) && ActiveRecord::Base.connection.dbmsName == :informix
|
50
|
+
# Index on (last_name, first_name) exceeds max. index width supported by Informix if
|
51
|
+
# both columns are created with a default width of 255, in which case
|
52
|
+
# Informix may return error -517: "The total size of the index is too large..."
|
53
|
+
Person.connection.add_column "people", "last_name", :string, {:limit => 40}
|
54
|
+
else
|
55
|
+
Person.connection.add_column "people", "last_name", :string
|
56
|
+
end
|
57
|
+
Person.connection.add_column "people", "administrator", :boolean
|
58
|
+
Person.connection.add_column "people", "key", :string
|
59
|
+
|
60
|
+
assert_nothing_raised { Person.connection.add_index("people", "last_name") }
|
61
|
+
assert_nothing_raised { Person.connection.remove_index("people", "last_name") }
|
62
|
+
|
63
|
+
assert_nothing_raised { Person.connection.add_index("people", ["last_name", "first_name"]) }
|
64
|
+
assert_nothing_raised { Person.connection.remove_index("people", "last_name") }
|
65
|
+
|
66
|
+
# quoting
|
67
|
+
assert_nothing_raised { Person.connection.add_index("people", ["key"], :name => "key", :unique => true) }
|
68
|
+
assert_nothing_raised { Person.connection.remove_index("people", :name => "key") }
|
69
|
+
|
70
|
+
# Sybase adapter does not support indexes on :boolean columns
|
71
|
+
unless current_adapter?(:SybaseAdapter) ||
|
72
|
+
current_adapter?(:ODBCAdapter) && ActiveRecord::Base.connection.dbmsName == :sybase
|
73
|
+
assert_nothing_raised { Person.connection.add_index("people", %w(last_name first_name administrator), :name => "named_admin") }
|
74
|
+
assert_nothing_raised { Person.connection.remove_index("people", :name => "named_admin") }
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_create_table_adds_id
|
79
|
+
Person.connection.create_table :testings do |t|
|
80
|
+
t.column :foo, :string
|
81
|
+
end
|
82
|
+
|
83
|
+
assert_equal %w(foo id),
|
84
|
+
Person.connection.columns(:testings).map { |c| c.name }.sort
|
85
|
+
ensure
|
86
|
+
Person.connection.drop_table :testings rescue nil
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_create_table_with_not_null_column
|
90
|
+
Person.connection.create_table :testings do |t|
|
91
|
+
t.column :foo, :string, :null => false
|
92
|
+
end
|
93
|
+
|
94
|
+
assert_raises(ActiveRecord::StatementInvalid) do
|
95
|
+
Person.connection.execute "insert into testings (foo) values (NULL)"
|
96
|
+
end
|
97
|
+
ensure
|
98
|
+
Person.connection.drop_table :testings rescue nil
|
99
|
+
end
|
100
|
+
|
101
|
+
def test_create_table_with_defaults
|
102
|
+
Person.connection.create_table :testings do |t|
|
103
|
+
t.column :one, :string, :default => "hello"
|
104
|
+
t.column :two, :boolean, :default => true
|
105
|
+
t.column :three, :boolean, :default => false
|
106
|
+
t.column :four, :integer, :default => 1
|
107
|
+
end
|
108
|
+
|
109
|
+
columns = Person.connection.columns(:testings)
|
110
|
+
one = columns.detect { |c| c.name == "one" }
|
111
|
+
two = columns.detect { |c| c.name == "two" }
|
112
|
+
three = columns.detect { |c| c.name == "three" }
|
113
|
+
four = columns.detect { |c| c.name == "four" }
|
114
|
+
|
115
|
+
assert_equal "hello", one.default
|
116
|
+
if current_adapter?(:OracleAdapter)
|
117
|
+
# Oracle doesn't support native booleans
|
118
|
+
assert_equal true, two.default == 1
|
119
|
+
assert_equal false, three.default != 0
|
120
|
+
elsif current_adapter?(:ODBCAdapter) &&
|
121
|
+
[:informix, :ingres, :virtuoso, :oracle, :mysql, :microsoftsqlserver].include?(ActiveRecord::Base.connection.dbmsName)
|
122
|
+
# Above databases/ODBC drivers don't support native booleans.
|
123
|
+
# They use an integer type instead.
|
124
|
+
assert_equal true, two.default == 1
|
125
|
+
assert_equal false, three.default != 0
|
126
|
+
else
|
127
|
+
assert_equal true, two.default
|
128
|
+
assert_equal false, three.default
|
129
|
+
end
|
130
|
+
assert_equal 1, four.default
|
131
|
+
|
132
|
+
ensure
|
133
|
+
Person.connection.drop_table :testings rescue nil
|
134
|
+
end
|
135
|
+
|
136
|
+
# SQL Server and Sybase will not allow you to add a NOT NULL column
|
137
|
+
# to a table without specifying a default value, so the
|
138
|
+
# following test must be skipped
|
139
|
+
unless current_adapter?(:SQLServerAdapter) || current_adapter?(:SybaseAdapter) ||
|
140
|
+
current_adapter?(:ODBCAdapter) && [:microsoftsqlserver, :sybase].include?(ActiveRecord::Base.connection.dbmsName)
|
141
|
+
def test_add_column_not_null_without_default
|
142
|
+
|
143
|
+
Person.connection.create_table :testings do |t|
|
144
|
+
t.column :foo, :string
|
145
|
+
end
|
146
|
+
Person.connection.add_column :testings, :bar, :string, :null => false
|
147
|
+
|
148
|
+
assert_raises(ActiveRecord::StatementInvalid) do
|
149
|
+
Person.connection.execute "insert into testings (foo, bar) values ('hello', NULL)"
|
150
|
+
end
|
151
|
+
ensure
|
152
|
+
Person.connection.drop_table :testings rescue nil
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
def test_add_column_not_null_with_default
|
157
|
+
Person.connection.create_table :testings do |t|
|
158
|
+
t.column :foo, :string
|
159
|
+
end
|
160
|
+
if current_adapter?(:ODBCAdapter) && [:ingres].include?(ActiveRecord::Base.connection.dbmsName)
|
161
|
+
# Ingres requires that if 'ALTER TABLE table ADD column' specifies a NOT NULL constraint,
|
162
|
+
# then 'WITH DEFAULT' must also be specified *without* a default value.
|
163
|
+
Person.connection.add_column :testings, :bar, :string, :null => false
|
164
|
+
else
|
165
|
+
Person.connection.add_column :testings, :bar, :string, :null => false, :default => "default"
|
166
|
+
end
|
167
|
+
|
168
|
+
assert_raises(ActiveRecord::StatementInvalid) do
|
169
|
+
Person.connection.execute "insert into testings (foo, bar) values ('hello', NULL)"
|
170
|
+
end
|
171
|
+
ensure
|
172
|
+
Person.connection.drop_table :testings rescue nil
|
173
|
+
end
|
174
|
+
|
175
|
+
def test_native_types
|
176
|
+
Person.delete_all
|
177
|
+
Person.connection.add_column "people", "last_name", :string
|
178
|
+
Person.connection.add_column "people", "bio", :text
|
179
|
+
Person.connection.add_column "people", "age", :integer
|
180
|
+
Person.connection.add_column "people", "height", :float
|
181
|
+
Person.connection.add_column "people", "birthday", :datetime
|
182
|
+
Person.connection.add_column "people", "favorite_day", :date
|
183
|
+
Person.connection.add_column "people", "male", :boolean
|
184
|
+
assert_nothing_raised { Person.create :first_name => 'bob', :last_name => 'bobsen', :bio => "I was born ....", :age => 18, :height => 1.78, :birthday => 18.years.ago, :favorite_day => 10.days.ago, :male => true }
|
185
|
+
bob = Person.find(:first)
|
186
|
+
|
187
|
+
assert_equal bob.first_name, 'bob'
|
188
|
+
assert_equal bob.last_name, 'bobsen'
|
189
|
+
assert_equal bob.bio, "I was born ...."
|
190
|
+
assert_equal bob.age, 18
|
191
|
+
assert_equal bob.male?, true
|
192
|
+
|
193
|
+
assert_equal String, bob.first_name.class
|
194
|
+
assert_equal String, bob.last_name.class
|
195
|
+
assert_equal String, bob.bio.class
|
196
|
+
assert_equal Fixnum, bob.age.class
|
197
|
+
assert_equal Time, bob.birthday.class
|
198
|
+
|
199
|
+
if current_adapter?(:SQLServerAdapter) ||
|
200
|
+
current_adapter?(:OracleAdapter) ||
|
201
|
+
current_adapter?(:SybaseAdapter) ||
|
202
|
+
(current_adapter?(:ODBCAdapter) &&
|
203
|
+
[:ingres, :oracle, :microsoftsqlserver].include?(ActiveRecord::Base.connection.dbmsName))
|
204
|
+
# SQL Server, Sybase, Oracle and Ingres don't differentiate between date/time
|
205
|
+
assert_equal Time, bob.favorite_day.class
|
206
|
+
else
|
207
|
+
assert_equal Date, bob.favorite_day.class
|
208
|
+
end
|
209
|
+
|
210
|
+
assert_equal TrueClass, bob.male?.class
|
211
|
+
end
|
212
|
+
|
213
|
+
def test_add_remove_single_field_using_string_arguments
|
214
|
+
assert !Person.column_methods_hash.include?(:last_name)
|
215
|
+
|
216
|
+
ActiveRecord::Migration.add_column 'people', 'last_name', :string
|
217
|
+
|
218
|
+
Person.reset_column_information
|
219
|
+
assert Person.column_methods_hash.include?(:last_name)
|
220
|
+
|
221
|
+
ActiveRecord::Migration.remove_column 'people', 'last_name'
|
222
|
+
|
223
|
+
Person.reset_column_information
|
224
|
+
assert !Person.column_methods_hash.include?(:last_name)
|
225
|
+
end
|
226
|
+
|
227
|
+
def test_add_remove_single_field_using_symbol_arguments
|
228
|
+
assert !Person.column_methods_hash.include?(:last_name)
|
229
|
+
|
230
|
+
ActiveRecord::Migration.add_column :people, :last_name, :string
|
231
|
+
|
232
|
+
Person.reset_column_information
|
233
|
+
assert Person.column_methods_hash.include?(:last_name)
|
234
|
+
|
235
|
+
ActiveRecord::Migration.remove_column :people, :last_name
|
236
|
+
|
237
|
+
Person.reset_column_information
|
238
|
+
assert !Person.column_methods_hash.include?(:last_name)
|
239
|
+
end
|
240
|
+
|
241
|
+
# Ingres, Virtuoso:
|
242
|
+
# Neither supports renaming of columns. Skip test.
|
243
|
+
unless current_adapter?(:ODBCAdapter) &&
|
244
|
+
[:ingres, :virtuoso].include?(ActiveRecord::Base.connection.dbmsName)
|
245
|
+
def test_add_rename
|
246
|
+
Person.delete_all
|
247
|
+
|
248
|
+
begin
|
249
|
+
# Some DBs complain girlfriend column already exists on two consecutive add_column calls
|
250
|
+
unless current_adapter?(:ODBCAdapter) && [:informix, :oracle, :mysql, :microsoftsqlserver, :sybase].include?(ActiveRecord::Base.connection.dbmsName)
|
251
|
+
Person.connection.add_column "people", "girlfriend", :string
|
252
|
+
end
|
253
|
+
Person.connection.add_column "people", "girlfriend", :string, :limit => 40
|
254
|
+
Person.create :girlfriend => 'bobette'
|
255
|
+
|
256
|
+
Person.connection.rename_column "people", "girlfriend", "exgirlfriend"
|
257
|
+
|
258
|
+
Person.reset_column_information
|
259
|
+
bob = Person.find(:first)
|
260
|
+
|
261
|
+
assert_equal "bobette", bob.exgirlfriend
|
262
|
+
ensure
|
263
|
+
Person.connection.remove_column("people", "girlfriend") rescue nil
|
264
|
+
Person.connection.remove_column("people", "exgirlfriend") rescue nil
|
265
|
+
end
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
# Ingres and Virtuoso don't support renaming of columns. Skip test.
|
270
|
+
unless current_adapter?(:ODBCAdapter) && [:ingres, :virtuoso].include?(ActiveRecord::Base.connection.dbmsName)
|
271
|
+
def test_rename_column_using_symbol_arguments
|
272
|
+
begin
|
273
|
+
Person.connection.rename_column :people, :first_name, :nick_name
|
274
|
+
Person.reset_column_information
|
275
|
+
assert Person.column_names.include?("nick_name")
|
276
|
+
ensure
|
277
|
+
Person.connection.remove_column("people","nick_name")
|
278
|
+
Person.connection.add_column("people","first_name", :string)
|
279
|
+
end
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
283
|
+
# Ingres and Virtuoso don't support renaming of columns. Skip test.
|
284
|
+
unless current_adapter?(:ODBCAdapter) && [:ingres, :virtuoso].include?(ActiveRecord::Base.connection.dbmsName)
|
285
|
+
def test_rename_column
|
286
|
+
begin
|
287
|
+
Person.connection.rename_column "people", "first_name", "nick_name"
|
288
|
+
Person.reset_column_information
|
289
|
+
assert Person.column_names.include?("nick_name")
|
290
|
+
ensure
|
291
|
+
Person.connection.remove_column("people","nick_name")
|
292
|
+
Person.connection.add_column("people","first_name", :string)
|
293
|
+
end
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
# Ingres doesn't support renaming of tables. Skip test.
|
298
|
+
unless current_adapter?(:ODBCAdapter) && [:ingres].include?(ActiveRecord::Base.connection.dbmsName)
|
299
|
+
def test_rename_table
|
300
|
+
begin
|
301
|
+
ActiveRecord::Base.connection.create_table :octopuses do |t|
|
302
|
+
t.column :url, :string
|
303
|
+
end
|
304
|
+
ActiveRecord::Base.connection.rename_table :octopuses, :octopi
|
305
|
+
|
306
|
+
assert_nothing_raised do
|
307
|
+
if current_adapter?(:OracleAdapter) ||
|
308
|
+
current_adapter?(:ODBCAdapter) && [:oracle].include?(ActiveRecord::Base.connection.dbmsName)
|
309
|
+
# Oracle requires the explicit sequence value for the pk
|
310
|
+
ActiveRecord::Base.connection.execute "INSERT INTO octopi (id, url) VALUES (1, 'http://www.foreverflying.com/octopus-black7.jpg')"
|
311
|
+
else
|
312
|
+
ActiveRecord::Base.connection.execute "INSERT INTO octopi (url) VALUES ('http://www.foreverflying.com/octopus-black7.jpg')"
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
316
|
+
assert_equal 'http://www.foreverflying.com/octopus-black7.jpg', ActiveRecord::Base.connection.select_value("SELECT url FROM octopi WHERE id=1")
|
317
|
+
|
318
|
+
ensure
|
319
|
+
ActiveRecord::Base.connection.drop_table :octopuses rescue nil
|
320
|
+
ActiveRecord::Base.connection.drop_table :octopi rescue nil
|
321
|
+
end
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
325
|
+
# Virtuoso disallows virtually all column type conversions.
|
326
|
+
# Conversion between any of the native types used by the ActiveRecord generic types is not allowed.
|
327
|
+
# Skip the test.
|
328
|
+
unless current_adapter?(:ODBCAdapter) && [:virtuoso].include?(ActiveRecord::Base.connection.dbmsName)
|
329
|
+
def test_change_column
|
330
|
+
#Ingres doesn't support changing an integer column to varchar/text.
|
331
|
+
if current_adapter?(:ODBCAdapter) && [:ingres].include?(ActiveRecord::Base.connection.dbmsName)
|
332
|
+
initial_type = :integer
|
333
|
+
new_type = :float
|
334
|
+
else
|
335
|
+
initial_type = :integer
|
336
|
+
new_type = :string
|
337
|
+
end
|
338
|
+
|
339
|
+
Person.connection.add_column 'people', 'age', initial_type
|
340
|
+
old_columns = Person.connection.columns(Person.table_name, "#{name} Columns")
|
341
|
+
assert old_columns.find { |c| c.name == 'age' and c.type == initial_type }
|
342
|
+
|
343
|
+
assert_nothing_raised { Person.connection.change_column "people", "age", new_type }
|
344
|
+
|
345
|
+
new_columns = Person.connection.columns(Person.table_name, "#{name} Columns")
|
346
|
+
assert_nil new_columns.find { |c| c.name == 'age' and c.type == initial_type }
|
347
|
+
assert new_columns.find { |c| c.name == 'age' and c.type == new_type }
|
348
|
+
end
|
349
|
+
end
|
350
|
+
|
351
|
+
# Ingres doesn't support ALTER TABLE ADD COLUMN WITH NULL WITH DEFAULT.
|
352
|
+
# Sybase ASE's ALTER TABLE doesn't support altering a column's DEFAULT definition.
|
353
|
+
unless current_adapter?(:ODBCAdapter) && [:ingres, :sybase].include?(ActiveRecord::Base.connection.dbmsName)
|
354
|
+
def test_change_column_with_new_default
|
355
|
+
Person.connection.add_column "people", "administrator", :boolean, :default => 1
|
356
|
+
Person.reset_column_information
|
357
|
+
assert Person.new.administrator?
|
358
|
+
|
359
|
+
assert_nothing_raised { Person.connection.change_column "people", "administrator", :boolean, :default => 0 }
|
360
|
+
Person.reset_column_information
|
361
|
+
assert !Person.new.administrator?
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
def test_add_table
|
366
|
+
assert !Reminder.table_exists?
|
367
|
+
|
368
|
+
WeNeedReminders.up
|
369
|
+
|
370
|
+
assert Reminder.create("content" => "hello world", "remind_at" => Time.now)
|
371
|
+
assert_equal "hello world", Reminder.find(:first).content
|
372
|
+
|
373
|
+
WeNeedReminders.down
|
374
|
+
assert_raises(ActiveRecord::StatementInvalid) { Reminder.find(:first) }
|
375
|
+
end
|
376
|
+
|
377
|
+
def test_migrator
|
378
|
+
assert !Person.column_methods_hash.include?(:last_name)
|
379
|
+
assert !Reminder.table_exists?
|
380
|
+
|
381
|
+
ActiveRecord::Migrator.up(File.dirname(__FILE__) + '/fixtures/migrations/')
|
382
|
+
|
383
|
+
assert_equal 3, ActiveRecord::Migrator.current_version
|
384
|
+
Person.reset_column_information
|
385
|
+
assert Person.column_methods_hash.include?(:last_name)
|
386
|
+
assert Reminder.create("content" => "hello world", "remind_at" => Time.now)
|
387
|
+
assert_equal "hello world", Reminder.find(:first).content
|
388
|
+
|
389
|
+
ActiveRecord::Migrator.down(File.dirname(__FILE__) + '/fixtures/migrations/')
|
390
|
+
|
391
|
+
assert_equal 0, ActiveRecord::Migrator.current_version
|
392
|
+
Person.reset_column_information
|
393
|
+
assert !Person.column_methods_hash.include?(:last_name)
|
394
|
+
assert_raises(ActiveRecord::StatementInvalid) { Reminder.find(:first) }
|
395
|
+
end
|
396
|
+
|
397
|
+
def test_migrator_one_up
|
398
|
+
assert !Person.column_methods_hash.include?(:last_name)
|
399
|
+
assert !Reminder.table_exists?
|
400
|
+
|
401
|
+
ActiveRecord::Migrator.up(File.dirname(__FILE__) + '/fixtures/migrations/', 1)
|
402
|
+
|
403
|
+
Person.reset_column_information
|
404
|
+
assert Person.column_methods_hash.include?(:last_name)
|
405
|
+
assert !Reminder.table_exists?
|
406
|
+
|
407
|
+
ActiveRecord::Migrator.up(File.dirname(__FILE__) + '/fixtures/migrations/', 2)
|
408
|
+
|
409
|
+
assert Reminder.create("content" => "hello world", "remind_at" => Time.now)
|
410
|
+
assert_equal "hello world", Reminder.find(:first).content
|
411
|
+
end
|
412
|
+
|
413
|
+
def test_migrator_one_down
|
414
|
+
ActiveRecord::Migrator.up(File.dirname(__FILE__) + '/fixtures/migrations/')
|
415
|
+
|
416
|
+
ActiveRecord::Migrator.down(File.dirname(__FILE__) + '/fixtures/migrations/', 1)
|
417
|
+
|
418
|
+
Person.reset_column_information
|
419
|
+
assert Person.column_methods_hash.include?(:last_name)
|
420
|
+
assert !Reminder.table_exists?
|
421
|
+
end
|
422
|
+
|
423
|
+
def test_migrator_one_up_one_down
|
424
|
+
ActiveRecord::Migrator.up(File.dirname(__FILE__) + '/fixtures/migrations/', 1)
|
425
|
+
ActiveRecord::Migrator.down(File.dirname(__FILE__) + '/fixtures/migrations/', 0)
|
426
|
+
|
427
|
+
assert !Person.column_methods_hash.include?(:last_name)
|
428
|
+
assert !Reminder.table_exists?
|
429
|
+
end
|
430
|
+
|
431
|
+
def test_migrator_verbosity
|
432
|
+
ActiveRecord::Migrator.up(File.dirname(__FILE__) + '/fixtures/migrations/', 1)
|
433
|
+
assert PeopleHaveLastNames.message_count > 0
|
434
|
+
PeopleHaveLastNames.message_count = 0
|
435
|
+
|
436
|
+
ActiveRecord::Migrator.down(File.dirname(__FILE__) + '/fixtures/migrations/', 0)
|
437
|
+
assert PeopleHaveLastNames.message_count > 0
|
438
|
+
PeopleHaveLastNames.message_count = 0
|
439
|
+
end
|
440
|
+
|
441
|
+
def test_migrator_verbosity_off
|
442
|
+
PeopleHaveLastNames.verbose = false
|
443
|
+
ActiveRecord::Migrator.up(File.dirname(__FILE__) + '/fixtures/migrations/', 1)
|
444
|
+
assert PeopleHaveLastNames.message_count.zero?
|
445
|
+
ActiveRecord::Migrator.down(File.dirname(__FILE__) + '/fixtures/migrations/', 0)
|
446
|
+
assert PeopleHaveLastNames.message_count.zero?
|
447
|
+
end
|
448
|
+
|
449
|
+
def test_migrator_going_down_due_to_version_target
|
450
|
+
ActiveRecord::Migrator.up(File.dirname(__FILE__) + '/fixtures/migrations/', 1)
|
451
|
+
ActiveRecord::Migrator.migrate(File.dirname(__FILE__) + '/fixtures/migrations/', 0)
|
452
|
+
|
453
|
+
assert !Person.column_methods_hash.include?(:last_name)
|
454
|
+
assert !Reminder.table_exists?
|
455
|
+
|
456
|
+
ActiveRecord::Migrator.migrate(File.dirname(__FILE__) + '/fixtures/migrations/')
|
457
|
+
|
458
|
+
Person.reset_column_information
|
459
|
+
assert Person.column_methods_hash.include?(:last_name)
|
460
|
+
assert Reminder.create("content" => "hello world", "remind_at" => Time.now)
|
461
|
+
assert_equal "hello world", Reminder.find(:first).content
|
462
|
+
end
|
463
|
+
|
464
|
+
def test_schema_info_table_name
|
465
|
+
ActiveRecord::Base.table_name_prefix = "prefix_"
|
466
|
+
ActiveRecord::Base.table_name_suffix = "_suffix"
|
467
|
+
Reminder.reset_table_name
|
468
|
+
assert_equal "prefix_schema_info_suffix", ActiveRecord::Migrator.schema_info_table_name
|
469
|
+
ActiveRecord::Base.table_name_prefix = ""
|
470
|
+
ActiveRecord::Base.table_name_suffix = ""
|
471
|
+
Reminder.reset_table_name
|
472
|
+
assert_equal "schema_info", ActiveRecord::Migrator.schema_info_table_name
|
473
|
+
ensure
|
474
|
+
ActiveRecord::Base.table_name_prefix = ""
|
475
|
+
ActiveRecord::Base.table_name_suffix = ""
|
476
|
+
end
|
477
|
+
|
478
|
+
def test_proper_table_name
|
479
|
+
assert_equal "table", ActiveRecord::Migrator.proper_table_name('table')
|
480
|
+
assert_equal "table", ActiveRecord::Migrator.proper_table_name(:table)
|
481
|
+
assert_equal "reminders", ActiveRecord::Migrator.proper_table_name(Reminder)
|
482
|
+
Reminder.reset_table_name
|
483
|
+
assert_equal Reminder.table_name, ActiveRecord::Migrator.proper_table_name(Reminder)
|
484
|
+
|
485
|
+
# Use the model's own prefix/suffix if a model is given
|
486
|
+
ActiveRecord::Base.table_name_prefix = "ARprefix_"
|
487
|
+
ActiveRecord::Base.table_name_suffix = "_ARsuffix"
|
488
|
+
Reminder.table_name_prefix = 'prefix_'
|
489
|
+
Reminder.table_name_suffix = '_suffix'
|
490
|
+
Reminder.reset_table_name
|
491
|
+
assert_equal "prefix_reminders_suffix", ActiveRecord::Migrator.proper_table_name(Reminder)
|
492
|
+
Reminder.table_name_prefix = ''
|
493
|
+
Reminder.table_name_suffix = ''
|
494
|
+
Reminder.reset_table_name
|
495
|
+
|
496
|
+
# Use AR::Base's prefix/suffix if string or symbol is given
|
497
|
+
ActiveRecord::Base.table_name_prefix = "prefix_"
|
498
|
+
ActiveRecord::Base.table_name_suffix = "_suffix"
|
499
|
+
Reminder.reset_table_name
|
500
|
+
assert_equal "prefix_table_suffix", ActiveRecord::Migrator.proper_table_name('table')
|
501
|
+
assert_equal "prefix_table_suffix", ActiveRecord::Migrator.proper_table_name(:table)
|
502
|
+
ActiveRecord::Base.table_name_prefix = ""
|
503
|
+
ActiveRecord::Base.table_name_suffix = ""
|
504
|
+
Reminder.reset_table_name
|
505
|
+
end
|
506
|
+
|
507
|
+
def test_add_drop_table_with_prefix_and_suffix
|
508
|
+
assert !Reminder.table_exists?
|
509
|
+
ActiveRecord::Base.table_name_prefix = 'prefix_'
|
510
|
+
ActiveRecord::Base.table_name_suffix = '_suffix'
|
511
|
+
Reminder.reset_table_name
|
512
|
+
Reminder.reset_sequence_name
|
513
|
+
WeNeedReminders.up
|
514
|
+
assert Reminder.create("content" => "hello world", "remind_at" => Time.now)
|
515
|
+
assert_equal "hello world", Reminder.find(:first).content
|
516
|
+
|
517
|
+
WeNeedReminders.down
|
518
|
+
assert_raises(ActiveRecord::StatementInvalid) { Reminder.find(:first) }
|
519
|
+
ensure
|
520
|
+
ActiveRecord::Base.table_name_prefix = ''
|
521
|
+
ActiveRecord::Base.table_name_suffix = ''
|
522
|
+
Reminder.reset_table_name
|
523
|
+
Reminder.reset_sequence_name
|
524
|
+
end
|
525
|
+
|
526
|
+
def test_create_table_with_binary_column
|
527
|
+
Person.connection.drop_table :binary_testings rescue nil
|
528
|
+
|
529
|
+
assert_nothing_raised {
|
530
|
+
if current_adapter?(:ODBCAdapter) && [:informix, :ingres].include?(ActiveRecord::Base.connection.dbmsName)
|
531
|
+
# Specifying a non-null default generates the following error:
|
532
|
+
# Informix:
|
533
|
+
# "Cannot specify non-null default value for blob column. (-594)"
|
534
|
+
# Ingres:
|
535
|
+
# "Cannot create a default on column of type 'long byte'"
|
536
|
+
Person.connection.create_table :binary_testings do |t|
|
537
|
+
t.column "data", :binary
|
538
|
+
end
|
539
|
+
else
|
540
|
+
Person.connection.create_table :binary_testings do |t|
|
541
|
+
t.column "data", :binary, :default => "", :null => false
|
542
|
+
end
|
543
|
+
end
|
544
|
+
}
|
545
|
+
|
546
|
+
columns = Person.connection.columns(:binary_testings)
|
547
|
+
data_column = columns.detect { |c| c.name == "data" }
|
548
|
+
|
549
|
+
if current_adapter?(:OracleAdapter)
|
550
|
+
assert_equal "empty_blob()", data_column.default
|
551
|
+
elsif current_adapter?(:ODBCAdapter) && [:informix, :ingres].include?(ActiveRecord::Base.connection.dbmsName)
|
552
|
+
assert_nil data_column.default
|
553
|
+
else
|
554
|
+
assert_equal "", data_column.default
|
555
|
+
end
|
556
|
+
|
557
|
+
Person.connection.drop_table :binary_testings rescue nil
|
558
|
+
end
|
559
|
+
|
560
|
+
def test_migrator_with_duplicates
|
561
|
+
assert_raises(ActiveRecord::DuplicateMigrationVersionError) do
|
562
|
+
ActiveRecord::Migrator.migrate(File.dirname(__FILE__) + '/fixtures/migrations_with_duplicate/', nil)
|
563
|
+
end
|
564
|
+
end
|
565
|
+
end
|
566
|
+
end
|