odbc-rails 1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. data/AUTHORS +16 -0
  2. data/COPYING +21 -0
  3. data/ChangeLog +89 -0
  4. data/LICENSE +5 -0
  5. data/NEWS +12 -0
  6. data/README +282 -0
  7. data/lib/active_record/connection_adapters/odbc_adapter.rb +1792 -0
  8. data/lib/active_record/vendor/odbcext_db2.rb +87 -0
  9. data/lib/active_record/vendor/odbcext_informix.rb +132 -0
  10. data/lib/active_record/vendor/odbcext_informix_col.rb +45 -0
  11. data/lib/active_record/vendor/odbcext_ingres.rb +156 -0
  12. data/lib/active_record/vendor/odbcext_microsoftsqlserver.rb +185 -0
  13. data/lib/active_record/vendor/odbcext_microsoftsqlserver_col.rb +40 -0
  14. data/lib/active_record/vendor/odbcext_mysql.rb +136 -0
  15. data/lib/active_record/vendor/odbcext_oracle.rb +220 -0
  16. data/lib/active_record/vendor/odbcext_postgresql.rb +179 -0
  17. data/lib/active_record/vendor/odbcext_progress.rb +139 -0
  18. data/lib/active_record/vendor/odbcext_progress89.rb +259 -0
  19. data/lib/active_record/vendor/odbcext_sybase.rb +212 -0
  20. data/lib/active_record/vendor/odbcext_sybase_col.rb +49 -0
  21. data/lib/active_record/vendor/odbcext_virtuoso.rb +146 -0
  22. data/lib/odbc_adapter.rb +28 -0
  23. data/support/lib/active_record/connection_adapters/abstract/schema_definitions.rb +259 -0
  24. data/support/odbc_rails.diff +707 -0
  25. data/support/pack_odbc.rb +119 -0
  26. data/support/rake/rails_plugin_package_task.rb +212 -0
  27. data/support/test/base_test.rb +1349 -0
  28. data/support/test/migration_test.rb +566 -0
  29. data/test/connections/native_odbc/connection.rb +95 -0
  30. data/test/fixtures/db_definitions/db2.drop.sql +30 -0
  31. data/test/fixtures/db_definitions/db2.sql +217 -0
  32. data/test/fixtures/db_definitions/db22.drop.sql +2 -0
  33. data/test/fixtures/db_definitions/db22.sql +5 -0
  34. data/test/fixtures/db_definitions/informix.drop.sql +30 -0
  35. data/test/fixtures/db_definitions/informix.sql +205 -0
  36. data/test/fixtures/db_definitions/informix2.drop.sql +2 -0
  37. data/test/fixtures/db_definitions/informix2.sql +5 -0
  38. data/test/fixtures/db_definitions/ingres.drop.sql +62 -0
  39. data/test/fixtures/db_definitions/ingres.sql +232 -0
  40. data/test/fixtures/db_definitions/ingres2.drop.sql +2 -0
  41. data/test/fixtures/db_definitions/ingres2.sql +5 -0
  42. data/test/fixtures/db_definitions/mysql.drop.sql +30 -0
  43. data/test/fixtures/db_definitions/mysql.sql +219 -0
  44. data/test/fixtures/db_definitions/mysql2.drop.sql +2 -0
  45. data/test/fixtures/db_definitions/mysql2.sql +5 -0
  46. data/test/fixtures/db_definitions/oracle_odbc.drop.sql +64 -0
  47. data/test/fixtures/db_definitions/oracle_odbc.sql +257 -0
  48. data/test/fixtures/db_definitions/oracle_odbc2.drop.sql +2 -0
  49. data/test/fixtures/db_definitions/oracle_odbc2.sql +6 -0
  50. data/test/fixtures/db_definitions/progress.drop.sql +61 -0
  51. data/test/fixtures/db_definitions/progress.sql +234 -0
  52. data/test/fixtures/db_definitions/progress2.drop.sql +2 -0
  53. data/test/fixtures/db_definitions/progress2.sql +6 -0
  54. data/test/fixtures/db_definitions/sqlserver.drop.sql +30 -0
  55. data/test/fixtures/db_definitions/sqlserver.sql +203 -0
  56. data/test/fixtures/db_definitions/sqlserver2.drop.sql +2 -0
  57. data/test/fixtures/db_definitions/sqlserver2.sql +5 -0
  58. data/test/fixtures/db_definitions/sybase.drop.sql +31 -0
  59. data/test/fixtures/db_definitions/sybase.sql +204 -0
  60. data/test/fixtures/db_definitions/sybase2.drop.sql +4 -0
  61. data/test/fixtures/db_definitions/sybase2.sql +5 -0
  62. data/test/fixtures/db_definitions/virtuoso.drop.sql +30 -0
  63. data/test/fixtures/db_definitions/virtuoso.sql +200 -0
  64. data/test/fixtures/db_definitions/virtuoso2.drop.sql +2 -0
  65. data/test/fixtures/db_definitions/virtuoso2.sql +5 -0
  66. metadata +149 -0
@@ -0,0 +1,707 @@
1
+ Index: lib/active_record/connection_adapters/abstract/schema_definitions.rb
2
+ ===================================================================
3
+ --- lib/active_record/connection_adapters/abstract/schema_definitions.rb (revision 1)
4
+ +++ lib/active_record/connection_adapters/abstract/schema_definitions.rb (working copy)
5
+ @@ -195,7 +195,8 @@
6
+ # Appends a primary key definition to the table definition.
7
+ # Can be called multiple times, but this is probably not a good idea.
8
+ def primary_key(name)
9
+ - column(name, native[:primary_key])
10
+ + # column(name, native[:primary_key])
11
+ + column(name, :primary_key)
12
+ end
13
+
14
+ # Returns a ColumnDefinition for the column with name +name+.
15
+ Index: test/base_test.rb
16
+ ===================================================================
17
+ --- test/base_test.rb (revision 1)
18
+ +++ test/base_test.rb (working copy)
19
+ @@ -44,7 +44,7 @@
20
+ end
21
+
22
+ class BasicsTest < Test::Unit::TestCase
23
+ - fixtures :topics, :companies, :developers, :projects, :computers
24
+ + fixtures :topics, :companies, :developers, :projects, :computers, :accounts
25
+
26
+ def test_table_exists
27
+ assert !NonExistentTable.table_exists?
28
+ @@ -297,7 +297,15 @@
29
+ Time, Topic.find(1).last_read,
30
+ "The last_read attribute should be of the Time class"
31
+ )
32
+ + elsif current_adapter?(:ODBCAdapter) && [:ingres, :microsoftsqlserver, :oracle].include?(ActiveRecord::Base.connection.dbmsName)
33
+ + # Above databases don't have a pure date type. (They have a datetime-like type).
34
+ + assert_kind_of(
35
+ + Time, Topic.find(1).last_read,
36
+ + "The last_read attribute should be of the Time class"
37
+ + )
38
+ else
39
+ + # ODBCAdapter fails against SQL Server because topics.last_read is
40
+ + # defined as a datetime column, which is returned as a Ruby Time object.
41
+ assert_kind_of(
42
+ Date, Topic.find(1).last_read,
43
+ "The last_read attribute should be of the Date class"
44
+ @@ -563,7 +571,12 @@
45
+
46
+ def test_default_values_on_empty_strings
47
+ topic = Topic.new
48
+ - topic.approved = nil
49
+ + #Sybase does not allow nulls in boolean columns
50
+ + if current_adapter?(:ODBCAdapter) && ActiveRecord::Base.connection.dbmsName == :sybase
51
+ + topic.approved = false
52
+ + else
53
+ + topic.approved = nil
54
+ + end
55
+ topic.last_read = nil
56
+
57
+ topic.save
58
+ @@ -572,7 +585,8 @@
59
+ assert_nil topic.last_read
60
+
61
+ # Sybase adapter does not allow nulls in boolean columns
62
+ - if current_adapter?(:SybaseAdapter)
63
+ + if current_adapter?(:SybaseAdapter) ||
64
+ + current_adapter?(:ODBCAdapter) && ActiveRecord::Base.connection.dbmsName == :sybase
65
+ assert topic.approved == false
66
+ else
67
+ assert_nil topic.approved
68
+ @@ -733,7 +747,12 @@
69
+
70
+ def test_attributes_on_dummy_time
71
+ # Oracle and SQL Server do not have a TIME datatype.
72
+ - return true if current_adapter?(:SQLServerAdapter) || current_adapter?(:OracleAdapter)
73
+ + return true if current_adapter?(:SQLServerAdapter) ||
74
+ + current_adapter?(:OracleAdapter)
75
+ + if current_adapter?(:ODBCAdapter)
76
+ + # Check for databases which don't have a true TIME datatype
77
+ + return true if [:ingres, :oracle].include?(ActiveRecord::Base.connection.dbmsName)
78
+ + end
79
+
80
+ attributes = {
81
+ "bonus_time" => "5:42:00AM"
82
+ @@ -965,7 +984,12 @@
83
+ end
84
+
85
+ def test_quote
86
+ - author_name = "\\ \001 ' \n \\n \""
87
+ + if current_adapter?(:ODBCAdapter) && [:informix, :sybase].include?(ActiveRecord::Base.connection.dbmsName)
88
+ + #Informix and Sybase only allow printable characters in VARCHAR columns.
89
+ + author_name = "\\ \041 ' \n \\n \""
90
+ + else
91
+ + author_name = "\\ \001 ' \n \\n \""
92
+ + end
93
+ topic = Topic.create('author_name' => author_name)
94
+ assert_equal author_name, Topic.find(topic.id).author_name
95
+ end
96
+ @@ -1204,14 +1228,22 @@
97
+ assert xml.include?(%(<content>Have a nice day</content>))
98
+ assert xml.include?(%(<author-email-address>david@loudthinking.com</author-email-address>))
99
+ assert xml.include?(%(<parent-id></parent-id>))
100
+ - if current_adapter?(:SybaseAdapter) or current_adapter?(:SQLServerAdapter)
101
+ + # Following databases don't have a true date type, only a composite datetime type
102
+ + if current_adapter?(:SybaseAdapter) or current_adapter?(:SQLServerAdapter) or
103
+ + current_adapter?(:ODBCAdapter) &&
104
+ + [:ingres,:oracle,:microsoftsqlserver].include?(ActiveRecord::Base.connection.dbmsName)
105
+ assert xml.include?(%(<last-read type="datetime">#{last_read_in_current_timezone}</last-read>))
106
+ else
107
+ assert xml.include?(%(<last-read type="date">2004-04-15</last-read>))
108
+ end
109
+ - # Oracle and DB2 don't have true boolean or time-only fields
110
+ + # Following databases don't have a true boolean type
111
+ + unless current_adapter?(:OracleAdapter) || current_adapter?(:DB2Adapter) ||
112
+ + current_adapter?(:ODBCAdapter) &&
113
+ + [:ingres,:virtuoso,:oracle,:mysql,:db2].include?(ActiveRecord::Base.connection.dbmsName)
114
+ + assert xml.include?(%(<approved type="boolean">false</approved>)), "Approved should be a boolean"
115
+ + end
116
+ + # Oracle and DB2 don't have a true time-only field
117
+ unless current_adapter?(:OracleAdapter) || current_adapter?(:DB2Adapter)
118
+ - assert xml.include?(%(<approved type="boolean">false</approved>)), "Approved should be a boolean"
119
+ assert xml.include?(%(<bonus-time type="datetime">#{bonus_time_in_current_timezone}</bonus-time>))
120
+ end
121
+ end
122
+ Index: test/fixtures/db_definitions/db2.sql
123
+ ===================================================================
124
+ --- test/fixtures/db_definitions/db2.sql (revision 1)
125
+ +++ test/fixtures/db_definitions/db2.sql (working copy)
126
+ @@ -152,7 +152,7 @@
127
+ CREATE TABLE computers (
128
+ id INT GENERATED BY DEFAULT AS IDENTITY (START WITH 10000),
129
+ developer INT NOT NULL,
130
+ - extendedWarranty INT NOT NULL
131
+ + "extendedWarranty" INT NOT NULL
132
+ );
133
+
134
+ CREATE TABLE posts (
135
+ Index: test/fixtures/db_definitions/mysql.sql
136
+ ===================================================================
137
+ --- test/fixtures/db_definitions/mysql.sql (revision 1)
138
+ +++ test/fixtures/db_definitions/mysql.sql (working copy)
139
+ @@ -51,7 +51,7 @@
140
+ CREATE TABLE `projects` (
141
+ `id` int(11) NOT NULL auto_increment,
142
+ `name` varchar(100) default NULL,
143
+ - `type` VARCHAR(255) NOT NULL,
144
+ + `type` VARCHAR(255) default NULL,
145
+ PRIMARY KEY (`id`)
146
+ ) TYPE=InnoDB;
147
+
148
+ @@ -131,7 +131,7 @@
149
+ ) TYPE=InnoDB;
150
+
151
+ CREATE TABLE `people` (
152
+ - `id` INTEGER NOT NULL PRIMARY KEY,
153
+ + `id` INTEGER NOT NULL auto_increment PRIMARY KEY,
154
+ `first_name` VARCHAR(40) NOT NULL,
155
+ `lock_version` INTEGER NOT NULL DEFAULT 0
156
+ ) TYPE=InnoDB;
157
+ Index: test/fixtures/db_definitions/sybase.sql
158
+ ===================================================================
159
+ --- test/fixtures/db_definitions/sybase.sql (revision 1)
160
+ +++ test/fixtures/db_definitions/sybase.sql (working copy)
161
+ @@ -1,16 +1,16 @@
162
+ CREATE TABLE accounts (
163
+ - id numeric(9,0) IDENTITY PRIMARY KEY,
164
+ + id int IDENTITY PRIMARY KEY,
165
+ firm_id int NULL,
166
+ credit_limit int NULL
167
+ )
168
+
169
+ CREATE TABLE funny_jokes (
170
+ -id numeric(9,0) IDENTITY PRIMARY KEY,
171
+ +id int IDENTITY PRIMARY KEY,
172
+ name varchar(50) NULL
173
+ )
174
+
175
+ CREATE TABLE companies (
176
+ - id numeric(9,0) IDENTITY PRIMARY KEY,
177
+ + id int IDENTITY PRIMARY KEY,
178
+ type varchar(50) NULL,
179
+ ruby_type varchar(50) NULL,
180
+ firm_id int NULL,
181
+ @@ -21,13 +21,13 @@
182
+
183
+
184
+ CREATE TABLE topics (
185
+ - id numeric(9,0) IDENTITY PRIMARY KEY,
186
+ + id int IDENTITY PRIMARY KEY,
187
+ title varchar(255) NULL,
188
+ author_name varchar(255) NULL,
189
+ author_email_address varchar(255) NULL,
190
+ written_on datetime NULL,
191
+ bonus_time time NULL,
192
+ - last_read datetime NULL,
193
+ + last_read date NULL,
194
+ content varchar(255) NULL,
195
+ approved bit default 1,
196
+ replies_count int default 0,
197
+ @@ -36,7 +36,7 @@
198
+ )
199
+
200
+ CREATE TABLE developers (
201
+ - id numeric(9,0) IDENTITY PRIMARY KEY,
202
+ + id int IDENTITY PRIMARY KEY,
203
+ name varchar(100) NULL,
204
+ salary int default 70000,
205
+ created_at datetime NULL,
206
+ @@ -44,7 +44,7 @@
207
+ )
208
+
209
+ CREATE TABLE projects (
210
+ - id numeric(9,0) IDENTITY PRIMARY KEY,
211
+ + id int IDENTITY PRIMARY KEY,
212
+ name varchar(100) NULL,
213
+ type varchar(255) NULL
214
+ )
215
+ @@ -57,14 +57,14 @@
216
+ )
217
+
218
+ CREATE TABLE orders (
219
+ - id numeric(9,0) IDENTITY PRIMARY KEY,
220
+ + id int IDENTITY PRIMARY KEY,
221
+ name varchar(100) NULL,
222
+ billing_customer_id int NULL,
223
+ shipping_customer_id int NULL
224
+ )
225
+
226
+ CREATE TABLE customers (
227
+ - id numeric(9,0) IDENTITY PRIMARY KEY,
228
+ + id int IDENTITY PRIMARY KEY,
229
+ name varchar(100) NULL,
230
+ balance int default 0,
231
+ address_street varchar(100) NULL,
232
+ @@ -74,7 +74,7 @@
233
+ )
234
+
235
+ CREATE TABLE movies (
236
+ - movieid numeric(9,0) IDENTITY PRIMARY KEY,
237
+ + movieid int IDENTITY PRIMARY KEY,
238
+ name varchar(100) NULL
239
+ )
240
+
241
+ @@ -84,28 +84,28 @@
242
+ )
243
+
244
+ CREATE TABLE booleantests (
245
+ - id numeric(9,0) IDENTITY PRIMARY KEY,
246
+ + id int IDENTITY PRIMARY KEY,
247
+ value int NULL
248
+ )
249
+
250
+ CREATE TABLE auto_id_tests (
251
+ - auto_id numeric(9,0) IDENTITY PRIMARY KEY,
252
+ + auto_id int IDENTITY PRIMARY KEY,
253
+ value int NULL
254
+ )
255
+
256
+ CREATE TABLE entrants (
257
+ - id numeric(9,0) IDENTITY PRIMARY KEY,
258
+ + id int IDENTITY PRIMARY KEY,
259
+ name varchar(255) NOT NULL,
260
+ course_id int NOT NULL
261
+ )
262
+
263
+ CREATE TABLE colnametests (
264
+ - id numeric(9,0) IDENTITY PRIMARY KEY,
265
+ + id int IDENTITY PRIMARY KEY,
266
+ [references] int NOT NULL
267
+ )
268
+
269
+ CREATE TABLE mixins (
270
+ - id numeric(9,0) IDENTITY PRIMARY KEY,
271
+ + id int IDENTITY PRIMARY KEY,
272
+ parent_id int NULL,
273
+ pos int NULL,
274
+ created_at datetime NULL,
275
+ @@ -117,30 +117,30 @@
276
+ )
277
+
278
+ CREATE TABLE people (
279
+ - id numeric(9,0) IDENTITY PRIMARY KEY,
280
+ + id int IDENTITY PRIMARY KEY,
281
+ first_name varchar(40) NOT NULL,
282
+ lock_version int DEFAULT 0
283
+ )
284
+
285
+ CREATE TABLE readers (
286
+ - id numeric(9,0) IDENTITY PRIMARY KEY,
287
+ + id int IDENTITY PRIMARY KEY,
288
+ post_id int NOT NULL,
289
+ person_id int NOT NULL
290
+ )
291
+
292
+ CREATE TABLE binaries (
293
+ - id numeric(9,0) IDENTITY PRIMARY KEY,
294
+ + id int IDENTITY PRIMARY KEY,
295
+ data image NULL
296
+ )
297
+
298
+ CREATE TABLE computers (
299
+ - id numeric(9,0) IDENTITY PRIMARY KEY,
300
+ + id int IDENTITY PRIMARY KEY,
301
+ developer int NOT NULL,
302
+ extendedWarranty int NOT NULL
303
+ )
304
+
305
+ CREATE TABLE posts (
306
+ - id numeric(9,0) IDENTITY PRIMARY KEY,
307
+ + id int IDENTITY PRIMARY KEY,
308
+ author_id int NULL,
309
+ title varchar(255) NOT NULL,
310
+ body varchar(2048) NOT NULL,
311
+ @@ -148,25 +148,25 @@
312
+ )
313
+
314
+ CREATE TABLE comments (
315
+ - id numeric(9,0) IDENTITY PRIMARY KEY,
316
+ + id int IDENTITY PRIMARY KEY,
317
+ post_id int NOT NULL,
318
+ body varchar(2048) NOT NULL,
319
+ type varchar(255) NOT NULL
320
+ )
321
+
322
+ CREATE TABLE authors (
323
+ - id numeric(9,0) IDENTITY PRIMARY KEY,
324
+ + id int IDENTITY PRIMARY KEY,
325
+ name varchar(255) NOT NULL
326
+ )
327
+
328
+ CREATE TABLE tasks (
329
+ - id numeric(9,0) IDENTITY PRIMARY KEY,
330
+ + id int IDENTITY PRIMARY KEY,
331
+ starting datetime NULL,
332
+ ending datetime NULL
333
+ )
334
+
335
+ CREATE TABLE categories (
336
+ - id numeric(9,0) IDENTITY PRIMARY KEY,
337
+ + id int IDENTITY PRIMARY KEY,
338
+ name varchar(255) NOT NULL,
339
+ type varchar(255) NOT NULL
340
+ )
341
+ @@ -177,25 +177,25 @@
342
+ )
343
+
344
+ CREATE TABLE fk_test_has_pk (
345
+ - id numeric(9,0) IDENTITY PRIMARY KEY
346
+ + id int IDENTITY PRIMARY KEY
347
+ )
348
+
349
+ CREATE TABLE fk_test_has_fk (
350
+ - id numeric(9,0) PRIMARY KEY,
351
+ - fk_id numeric(9,0) NOT NULL,
352
+ + id int PRIMARY KEY,
353
+ + fk_id int NOT NULL,
354
+
355
+ FOREIGN KEY (fk_id) REFERENCES fk_test_has_pk(id)
356
+ )
357
+
358
+
359
+ CREATE TABLE keyboards (
360
+ - key_number numeric(9,0) IDENTITY PRIMARY KEY,
361
+ + key_number int IDENTITY PRIMARY KEY,
362
+ name varchar(50) NULL
363
+ )
364
+
365
+ --This table has an altered lock_version column name.
366
+ CREATE TABLE legacy_things (
367
+ - id numeric(9,0) IDENTITY PRIMARY KEY,
368
+ + id int IDENTITY PRIMARY KEY,
369
+ tps_report_number int default NULL,
370
+ version int default 0,
371
+ )
372
+ Index: test/migration_test.rb
373
+ ===================================================================
374
+ --- test/migration_test.rb (revision 1)
375
+ +++ test/migration_test.rb (working copy)
376
+ @@ -46,7 +46,14 @@
377
+ end
378
+
379
+ def test_add_index
380
+ - Person.connection.add_column "people", "last_name", :string
381
+ + if current_adapter?(:ODBCAdapter) && ActiveRecord::Base.connection.dbmsName == :informix
382
+ + # Index on (last_name, first_name) exceeds max. index width supported by Informix if
383
+ + # both columns are created with a default width of 255, in which case
384
+ + # Informix may return error -517: "The total size of the index is too large..."
385
+ + Person.connection.add_column "people", "last_name", :string, {:limit => 40}
386
+ + else
387
+ + Person.connection.add_column "people", "last_name", :string
388
+ + end
389
+ Person.connection.add_column "people", "administrator", :boolean
390
+ Person.connection.add_column "people", "key", :string
391
+
392
+ @@ -61,7 +68,8 @@
393
+ assert_nothing_raised { Person.connection.remove_index("people", :name => "key") }
394
+
395
+ # Sybase adapter does not support indexes on :boolean columns
396
+ - unless current_adapter?(:SybaseAdapter)
397
+ + unless current_adapter?(:SybaseAdapter) ||
398
+ + current_adapter?(:ODBCAdapter) && ActiveRecord::Base.connection.dbmsName == :sybase
399
+ assert_nothing_raised { Person.connection.add_index("people", %w(last_name first_name administrator), :name => "named_admin") }
400
+ assert_nothing_raised { Person.connection.remove_index("people", :name => "named_admin") }
401
+ end
402
+ @@ -109,6 +117,12 @@
403
+ # Oracle doesn't support native booleans
404
+ assert_equal true, two.default == 1
405
+ assert_equal false, three.default != 0
406
+ + elsif current_adapter?(:ODBCAdapter) &&
407
+ + [:informix, :ingres, :virtuoso, :oracle, :mysql, :microsoftsqlserver].include?(ActiveRecord::Base.connection.dbmsName)
408
+ + # Above databases/ODBC drivers don't support native booleans.
409
+ + # They use an integer type instead.
410
+ + assert_equal true, two.default == 1
411
+ + assert_equal false, three.default != 0
412
+ else
413
+ assert_equal true, two.default
414
+ assert_equal false, three.default
415
+ @@ -122,12 +136,14 @@
416
+ # SQL Server and Sybase will not allow you to add a NOT NULL column
417
+ # to a table without specifying a default value, so the
418
+ # following test must be skipped
419
+ - unless current_adapter?(:SQLServerAdapter) || current_adapter?(:SybaseAdapter)
420
+ + unless current_adapter?(:SQLServerAdapter) || current_adapter?(:SybaseAdapter) ||
421
+ + current_adapter?(:ODBCAdapter) && [:microsoftsqlserver, :sybase].include?(ActiveRecord::Base.connection.dbmsName)
422
+ def test_add_column_not_null_without_default
423
+ +
424
+ Person.connection.create_table :testings do |t|
425
+ - t.column :foo, :string
426
+ + t.column :foo, :string
427
+ end
428
+ - Person.connection.add_column :testings, :bar, :string, :null => false
429
+ + Person.connection.add_column :testings, :bar, :string, :null => false
430
+
431
+ assert_raises(ActiveRecord::StatementInvalid) do
432
+ Person.connection.execute "insert into testings (foo, bar) values ('hello', NULL)"
433
+ @@ -141,8 +157,14 @@
434
+ Person.connection.create_table :testings do |t|
435
+ t.column :foo, :string
436
+ end
437
+ - Person.connection.add_column :testings, :bar, :string, :null => false, :default => "default"
438
+ -
439
+ + if current_adapter?(:ODBCAdapter) && [:ingres].include?(ActiveRecord::Base.connection.dbmsName)
440
+ + # Ingres requires that if 'ALTER TABLE table ADD column' specifies a NOT NULL constraint,
441
+ + # then 'WITH DEFAULT' must also be specified *without* a default value.
442
+ + Person.connection.add_column :testings, :bar, :string, :null => false
443
+ + else
444
+ + Person.connection.add_column :testings, :bar, :string, :null => false, :default => "default"
445
+ + end
446
+ +
447
+ assert_raises(ActiveRecord::StatementInvalid) do
448
+ Person.connection.execute "insert into testings (foo, bar) values ('hello', NULL)"
449
+ end
450
+ @@ -174,8 +196,12 @@
451
+ assert_equal Fixnum, bob.age.class
452
+ assert_equal Time, bob.birthday.class
453
+
454
+ - if current_adapter?(:SQLServerAdapter) || current_adapter?(:OracleAdapter) || current_adapter?(:SybaseAdapter)
455
+ - # SQL Server, Sybase, and Oracle don't differentiate between date/time
456
+ + if current_adapter?(:SQLServerAdapter) ||
457
+ + current_adapter?(:OracleAdapter) ||
458
+ + current_adapter?(:SybaseAdapter) ||
459
+ + (current_adapter?(:ODBCAdapter) &&
460
+ + [:ingres, :oracle, :microsoftsqlserver].include?(ActiveRecord::Base.connection.dbmsName))
461
+ + # SQL Server, Sybase, Oracle and Ingres don't differentiate between date/time
462
+ assert_equal Time, bob.favorite_day.class
463
+ else
464
+ assert_equal Date, bob.favorite_day.class
465
+ @@ -186,7 +212,7 @@
466
+
467
+ def test_add_remove_single_field_using_string_arguments
468
+ assert !Person.column_methods_hash.include?(:last_name)
469
+ -
470
+ +
471
+ ActiveRecord::Migration.add_column 'people', 'last_name', :string
472
+
473
+ Person.reset_column_information
474
+ @@ -212,94 +238,130 @@
475
+ assert !Person.column_methods_hash.include?(:last_name)
476
+ end
477
+
478
+ - def test_add_rename
479
+ - Person.delete_all
480
+ -
481
+ - begin
482
+ - Person.connection.add_column "people", "girlfriend", :string
483
+ - Person.create :girlfriend => 'bobette'
484
+ -
485
+ - Person.connection.rename_column "people", "girlfriend", "exgirlfriend"
486
+ -
487
+ - Person.reset_column_information
488
+ - bob = Person.find(:first)
489
+ -
490
+ - assert_equal "bobette", bob.exgirlfriend
491
+ - ensure
492
+ - Person.connection.remove_column("people", "girlfriend") rescue nil
493
+ + # Ingres, Virtuoso:
494
+ + # Neither supports renaming of columns. Skip test.
495
+ + unless current_adapter?(:ODBCAdapter) &&
496
+ + [:ingres, :virtuoso].include?(ActiveRecord::Base.connection.dbmsName)
497
+ + def test_add_rename
498
+ + Person.delete_all
499
+ +
500
+ + begin
501
+ + # Some DBs complain girlfriend column already exists on two consecutive add_column calls
502
+ + unless current_adapter?(:ODBCAdapter) && [:informix, :oracle, :mysql, :microsoftsqlserver, :sybase].include?(ActiveRecord::Base.connection.dbmsName)
503
+ + Person.connection.add_column "people", "girlfriend", :string
504
+ + end
505
+ + Person.connection.add_column "people", "girlfriend", :string, :limit => 40
506
+ + Person.create :girlfriend => 'bobette'
507
+ +
508
+ + Person.connection.rename_column "people", "girlfriend", "exgirlfriend"
509
+ +
510
+ + Person.reset_column_information
511
+ + bob = Person.find(:first)
512
+ +
513
+ + assert_equal "bobette", bob.exgirlfriend
514
+ + ensure
515
+ + Person.connection.remove_column("people", "girlfriend") rescue nil
516
+ Person.connection.remove_column("people", "exgirlfriend") rescue nil
517
+ + end
518
+ end
519
+ -
520
+ end
521
+
522
+ - def test_rename_column_using_symbol_arguments
523
+ - begin
524
+ - Person.connection.rename_column :people, :first_name, :nick_name
525
+ - Person.reset_column_information
526
+ - assert Person.column_names.include?("nick_name")
527
+ - ensure
528
+ - Person.connection.remove_column("people","nick_name")
529
+ - Person.connection.add_column("people","first_name", :string)
530
+ + # Ingres and Virtuoso don't support renaming of columns. Skip test.
531
+ + unless current_adapter?(:ODBCAdapter) && [:ingres, :virtuoso].include?(ActiveRecord::Base.connection.dbmsName)
532
+ + def test_rename_column_using_symbol_arguments
533
+ + begin
534
+ + Person.connection.rename_column :people, :first_name, :nick_name
535
+ + Person.reset_column_information
536
+ + assert Person.column_names.include?("nick_name")
537
+ + ensure
538
+ + Person.connection.remove_column("people","nick_name")
539
+ + Person.connection.add_column("people","first_name", :string)
540
+ + end
541
+ end
542
+ end
543
+ -
544
+ - def test_rename_column
545
+ - begin
546
+ - Person.connection.rename_column "people", "first_name", "nick_name"
547
+ - Person.reset_column_information
548
+ - assert Person.column_names.include?("nick_name")
549
+ - ensure
550
+ - Person.connection.remove_column("people","nick_name")
551
+ - Person.connection.add_column("people","first_name", :string)
552
+ +
553
+ + # Ingres and Virtuoso don't support renaming of columns. Skip test.
554
+ + unless current_adapter?(:ODBCAdapter) && [:ingres, :virtuoso].include?(ActiveRecord::Base.connection.dbmsName)
555
+ + def test_rename_column
556
+ + begin
557
+ + Person.connection.rename_column "people", "first_name", "nick_name"
558
+ + Person.reset_column_information
559
+ + assert Person.column_names.include?("nick_name")
560
+ + ensure
561
+ + Person.connection.remove_column("people","nick_name")
562
+ + Person.connection.add_column("people","first_name", :string)
563
+ + end
564
+ end
565
+ end
566
+
567
+ - def test_rename_table
568
+ - begin
569
+ - ActiveRecord::Base.connection.create_table :octopuses do |t|
570
+ - t.column :url, :string
571
+ - end
572
+ - ActiveRecord::Base.connection.rename_table :octopuses, :octopi
573
+ -
574
+ - assert_nothing_raised do
575
+ - if current_adapter?(:OracleAdapter)
576
+ - # Oracle requires the explicit sequence value for the pk
577
+ - ActiveRecord::Base.connection.execute "INSERT INTO octopi (id, url) VALUES (1, 'http://www.foreverflying.com/octopus-black7.jpg')"
578
+ - else
579
+ - ActiveRecord::Base.connection.execute "INSERT INTO octopi (url) VALUES ('http://www.foreverflying.com/octopus-black7.jpg')"
580
+ + # Ingres doesn't support renaming of tables. Skip test.
581
+ + unless current_adapter?(:ODBCAdapter) && [:ingres].include?(ActiveRecord::Base.connection.dbmsName)
582
+ + def test_rename_table
583
+ + begin
584
+ + ActiveRecord::Base.connection.create_table :octopuses do |t|
585
+ + t.column :url, :string
586
+ end
587
+ + ActiveRecord::Base.connection.rename_table :octopuses, :octopi
588
+ +
589
+ + assert_nothing_raised do
590
+ + if current_adapter?(:OracleAdapter) ||
591
+ + current_adapter?(:ODBCAdapter) && [:oracle].include?(ActiveRecord::Base.connection.dbmsName)
592
+ + # Oracle requires the explicit sequence value for the pk
593
+ + ActiveRecord::Base.connection.execute "INSERT INTO octopi (id, url) VALUES (1, 'http://www.foreverflying.com/octopus-black7.jpg')"
594
+ + else
595
+ + ActiveRecord::Base.connection.execute "INSERT INTO octopi (url) VALUES ('http://www.foreverflying.com/octopus-black7.jpg')"
596
+ + end
597
+ + end
598
+ +
599
+ + assert_equal 'http://www.foreverflying.com/octopus-black7.jpg', ActiveRecord::Base.connection.select_value("SELECT url FROM octopi WHERE id=1")
600
+ +
601
+ + ensure
602
+ + ActiveRecord::Base.connection.drop_table :octopuses rescue nil
603
+ + ActiveRecord::Base.connection.drop_table :octopi rescue nil
604
+ end
605
+ -
606
+ - assert_equal 'http://www.foreverflying.com/octopus-black7.jpg', ActiveRecord::Base.connection.select_value("SELECT url FROM octopi WHERE id=1")
607
+ -
608
+ - ensure
609
+ - ActiveRecord::Base.connection.drop_table :octopuses rescue nil
610
+ - ActiveRecord::Base.connection.drop_table :octopi rescue nil
611
+ end
612
+ end
613
+
614
+ - def test_change_column
615
+ - Person.connection.add_column 'people', 'age', :integer
616
+ - old_columns = Person.connection.columns(Person.table_name, "#{name} Columns")
617
+ - assert old_columns.find { |c| c.name == 'age' and c.type == :integer }
618
+ + # Virtuoso disallows virtually all column type conversions.
619
+ + # Conversion between any of the native types used by the ActiveRecord generic types is not allowed.
620
+ + # Skip the test.
621
+ + unless current_adapter?(:ODBCAdapter) && [:virtuoso].include?(ActiveRecord::Base.connection.dbmsName)
622
+ + def test_change_column
623
+ + #Ingres doesn't support changing an integer column to varchar/text.
624
+ + if current_adapter?(:ODBCAdapter) && [:ingres].include?(ActiveRecord::Base.connection.dbmsName)
625
+ + initial_type = :integer
626
+ + new_type = :float
627
+ + else
628
+ + initial_type = :integer
629
+ + new_type = :string
630
+ + end
631
+ +
632
+ + Person.connection.add_column 'people', 'age', initial_type
633
+ + old_columns = Person.connection.columns(Person.table_name, "#{name} Columns")
634
+ + assert old_columns.find { |c| c.name == 'age' and c.type == initial_type }
635
+ +
636
+ + assert_nothing_raised { Person.connection.change_column "people", "age", new_type }
637
+ +
638
+ + new_columns = Person.connection.columns(Person.table_name, "#{name} Columns")
639
+ + assert_nil new_columns.find { |c| c.name == 'age' and c.type == initial_type }
640
+ + assert new_columns.find { |c| c.name == 'age' and c.type == new_type }
641
+ + end
642
+ + end
643
+
644
+ - assert_nothing_raised { Person.connection.change_column "people", "age", :string }
645
+ -
646
+ - new_columns = Person.connection.columns(Person.table_name, "#{name} Columns")
647
+ - assert_nil new_columns.find { |c| c.name == 'age' and c.type == :integer }
648
+ - assert new_columns.find { |c| c.name == 'age' and c.type == :string }
649
+ - end
650
+ -
651
+ - def test_change_column_with_new_default
652
+ - Person.connection.add_column "people", "administrator", :boolean, :default => 1
653
+ - Person.reset_column_information
654
+ - assert Person.new.administrator?
655
+ -
656
+ - assert_nothing_raised { Person.connection.change_column "people", "administrator", :boolean, :default => 0 }
657
+ - Person.reset_column_information
658
+ - assert !Person.new.administrator?
659
+ - end
660
+ -
661
+ + # Ingres doesn't support ALTER TABLE ADD COLUMN WITH NULL WITH DEFAULT.
662
+ + # Sybase ASE's ALTER TABLE doesn't support altering a column's DEFAULT definition.
663
+ + unless current_adapter?(:ODBCAdapter) && [:ingres, :sybase].include?(ActiveRecord::Base.connection.dbmsName)
664
+ + def test_change_column_with_new_default
665
+ + Person.connection.add_column "people", "administrator", :boolean, :default => 1
666
+ + Person.reset_column_information
667
+ + assert Person.new.administrator?
668
+ +
669
+ + assert_nothing_raised { Person.connection.change_column "people", "administrator", :boolean, :default => 0 }
670
+ + Person.reset_column_information
671
+ + assert !Person.new.administrator?
672
+ + end
673
+ + end
674
+ +
675
+ def test_add_table
676
+ assert !Reminder.table_exists?
677
+
678
+ @@ -465,9 +527,20 @@
679
+ Person.connection.drop_table :binary_testings rescue nil
680
+
681
+ assert_nothing_raised {
682
+ + if current_adapter?(:ODBCAdapter) && [:informix, :ingres].include?(ActiveRecord::Base.connection.dbmsName)
683
+ + # Specifying a non-null default generates the following error:
684
+ + # Informix:
685
+ + # "Cannot specify non-null default value for blob column. (-594)"
686
+ + # Ingres:
687
+ + # "Cannot create a default on column of type 'long byte'"
688
+ Person.connection.create_table :binary_testings do |t|
689
+ + t.column "data", :binary
690
+ + end
691
+ + else
692
+ + Person.connection.create_table :binary_testings do |t|
693
+ t.column "data", :binary, :default => "", :null => false
694
+ end
695
+ + end
696
+ }
697
+
698
+ columns = Person.connection.columns(:binary_testings)
699
+ @@ -475,6 +548,8 @@
700
+
701
+ if current_adapter?(:OracleAdapter)
702
+ assert_equal "empty_blob()", data_column.default
703
+ + elsif current_adapter?(:ODBCAdapter) && [:informix, :ingres].include?(ActiveRecord::Base.connection.dbmsName)
704
+ + assert_nil data_column.default
705
+ else
706
+ assert_equal "", data_column.default
707
+ end