ibm_db 0.9.4 → 0.9.5
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +15 -0
- data/README +11 -4
- data/ext/ibm_db.c +16 -15
- data/lib/active_record/connection_adapters/ibm_db_adapter.rb +268 -73
- data/test/adapter_test.rb +26 -8
- data/test/associations/eager_test.rb +63 -58
- data/test/associations_test.rb +584 -272
- data/test/base_test.rb +312 -130
- data/test/fixtures/db_definitions/i5/ibm_db.drop.sql +1 -0
- data/test/fixtures/db_definitions/i5/ibm_db.sql +5 -1
- data/test/fixtures/db_definitions/ids/ibm_db.drop.sql +1 -0
- data/test/fixtures/db_definitions/ids/ibm_db.sql +3 -0
- data/test/fixtures/db_definitions/luw/ibm_db.drop.sql +1 -0
- data/test/fixtures/db_definitions/luw/ibm_db.sql +5 -1
- data/test/fixtures/db_definitions/schema.rb +361 -0
- data/test/fixtures/db_definitions/zOS/ibm_db.drop.sql +1 -0
- data/test/fixtures/db_definitions/zOS/ibm_db.sql +5 -1
- data/test/locking_test.rb +95 -3
- data/test/migration_test.rb +308 -142
- metadata +3 -2
@@ -27,7 +27,7 @@ CREATE TABLE topics (
|
|
27
27
|
title VARCHAR(255) DEFAULT NULL,
|
28
28
|
author_name VARCHAR(255) DEFAULT NULL,
|
29
29
|
author_email_address VARCHAR(255) DEFAULT NULL,
|
30
|
-
written_on
|
30
|
+
written_on TIME DEFAULT NULL,
|
31
31
|
bonus_time TIME DEFAULT NULL,
|
32
32
|
last_read DATE DEFAULT NULL,
|
33
33
|
content VARCHAR(3000),
|
@@ -230,3 +230,7 @@ CREATE TABLE mixed_case_monkeys (
|
|
230
230
|
fleaCount INT DEFAULT 0,
|
231
231
|
PRIMARY KEY (monkeyID)
|
232
232
|
);
|
233
|
+
|
234
|
+
CREATE TABLE minimalistics (
|
235
|
+
id INT GENERATED BY DEFAULT AS IDENTITY (START WITH 100)
|
236
|
+
);
|
@@ -27,7 +27,7 @@ CREATE TABLE topics (
|
|
27
27
|
title VARCHAR(255) DEFAULT NULL,
|
28
28
|
author_name VARCHAR(255) DEFAULT NULL,
|
29
29
|
author_email_address VARCHAR(255) DEFAULT NULL,
|
30
|
-
written_on
|
30
|
+
written_on TIME DEFAULT NULL,
|
31
31
|
bonus_time TIME DEFAULT NULL,
|
32
32
|
last_read DATE DEFAULT NULL,
|
33
33
|
content VARCHAR(3000),
|
@@ -230,3 +230,7 @@ CREATE TABLE mixed_case_monkeys (
|
|
230
230
|
fleaCount INT DEFAULT 0,
|
231
231
|
PRIMARY KEY (monkeyID)
|
232
232
|
);
|
233
|
+
|
234
|
+
CREATE TABLE minimalistics (
|
235
|
+
id INT GENERATED BY DEFAULT AS IDENTITY (START WITH 100)
|
236
|
+
);
|
@@ -0,0 +1,361 @@
|
|
1
|
+
ActiveRecord::Schema.define do
|
2
|
+
|
3
|
+
# adapter name is checked because we are under a transition of
|
4
|
+
# moving the sql files under activerecord/test/fixtures/db_definitions
|
5
|
+
# to this file, schema.rb.
|
6
|
+
if adapter_name == "MySQL"
|
7
|
+
|
8
|
+
# Please keep these create table statements in alphabetical order
|
9
|
+
# unless the ordering matters. In which case, define them below
|
10
|
+
create_table :accounts, :force => true do |t|
|
11
|
+
t.integer :firm_id
|
12
|
+
t.integer :credit_limit
|
13
|
+
end
|
14
|
+
|
15
|
+
create_table :authors, :force => true do |t|
|
16
|
+
t.string :name, :null => false
|
17
|
+
end
|
18
|
+
|
19
|
+
create_table :auto_id_tests, :force => true, :id => false do |t|
|
20
|
+
t.primary_key :auto_id
|
21
|
+
t.integer :value
|
22
|
+
end
|
23
|
+
|
24
|
+
create_table :binaries, :force => true do |t|
|
25
|
+
t.binary :data
|
26
|
+
end
|
27
|
+
|
28
|
+
create_table :booleantests, :force => true do |t|
|
29
|
+
t.integer :value
|
30
|
+
end
|
31
|
+
|
32
|
+
create_table :categories, :force => true do |t|
|
33
|
+
t.string :name, :null => false
|
34
|
+
t.string :type
|
35
|
+
end
|
36
|
+
|
37
|
+
create_table :categories_posts, :force => true, :id => false do |t|
|
38
|
+
t.integer :category_id, :null => false
|
39
|
+
t.integer :post_id, :null => false
|
40
|
+
end
|
41
|
+
|
42
|
+
create_table :colnametests, :force => true do |t|
|
43
|
+
t.integer :references, :null => false
|
44
|
+
end
|
45
|
+
|
46
|
+
create_table :comments, :force => true do |t|
|
47
|
+
t.integer :post_id, :null => false
|
48
|
+
t.text :body, :null => false
|
49
|
+
t.string :type
|
50
|
+
end
|
51
|
+
|
52
|
+
create_table :companies, :force => true do |t|
|
53
|
+
t.string :type
|
54
|
+
t.string :ruby_type
|
55
|
+
t.integer :firm_id
|
56
|
+
t.string :name
|
57
|
+
t.integer :client_of
|
58
|
+
t.integer :rating, :default => 1
|
59
|
+
end
|
60
|
+
|
61
|
+
create_table :computers, :force => true do |t|
|
62
|
+
t.integer :developer, :null => false
|
63
|
+
t.integer :extendedWarranty, :null => false
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
create_table :customers, :force => true do |t|
|
68
|
+
t.string :name
|
69
|
+
t.integer :balance, :default => 0
|
70
|
+
t.string :address_street
|
71
|
+
t.string :address_city
|
72
|
+
t.string :address_country
|
73
|
+
t.string :gps_location
|
74
|
+
end
|
75
|
+
|
76
|
+
create_table :developers, :force => true do |t|
|
77
|
+
t.string :name
|
78
|
+
t.integer :salary, :default => 70000
|
79
|
+
t.datetime :created_at
|
80
|
+
t.datetime :updated_at
|
81
|
+
end
|
82
|
+
|
83
|
+
create_table :developers_projects, :force => true, :id => false do |t|
|
84
|
+
t.integer :developer_id, :null => false
|
85
|
+
t.integer :project_id, :null => false
|
86
|
+
t.date :joined_on
|
87
|
+
t.integer :access_level, :default => 1
|
88
|
+
end
|
89
|
+
|
90
|
+
create_table :entrants, :force => true do |t|
|
91
|
+
t.string :name, :null => false
|
92
|
+
t.integer :course_id, :null => false
|
93
|
+
end
|
94
|
+
|
95
|
+
create_table :funny_jokes, :force => true do |t|
|
96
|
+
t.string :name
|
97
|
+
end
|
98
|
+
|
99
|
+
create_table :keyboards, :force => true, :id => false do |t|
|
100
|
+
t.primary_key :key_number
|
101
|
+
t.string :name
|
102
|
+
end
|
103
|
+
|
104
|
+
create_table :legacy_things, :force => true do |t|
|
105
|
+
t.integer :tps_report_number
|
106
|
+
t.integer :version, :null => false, :default => 0
|
107
|
+
end
|
108
|
+
|
109
|
+
create_table :minimalistics, :force => true do |t|
|
110
|
+
end
|
111
|
+
|
112
|
+
create_table :mixed_case_monkeys, :force => true, :id => false do |t|
|
113
|
+
t.primary_key :monkeyID
|
114
|
+
t.integer :fleaCount
|
115
|
+
end
|
116
|
+
|
117
|
+
create_table :mixins, :force => true do |t|
|
118
|
+
t.integer :parent_id
|
119
|
+
t.integer :pos
|
120
|
+
t.datetime :created_at
|
121
|
+
t.datetime :updated_at
|
122
|
+
t.integer :lft
|
123
|
+
t.integer :rgt
|
124
|
+
t.integer :root_id
|
125
|
+
t.string :type
|
126
|
+
end
|
127
|
+
|
128
|
+
create_table :movies, :force => true, :id => false do |t|
|
129
|
+
t.primary_key :movieid
|
130
|
+
t.string :name
|
131
|
+
end
|
132
|
+
|
133
|
+
create_table :numeric_data, :force => true do |t|
|
134
|
+
t.decimal :bank_balance, :precision => 10, :scale => 2
|
135
|
+
t.decimal :big_bank_balance, :precision => 15, :scale => 2
|
136
|
+
t.decimal :world_population, :precision => 10, :scale => 0
|
137
|
+
t.decimal :my_house_population, :precision => 2, :scale => 0
|
138
|
+
t.decimal :decimal_number_with_default, :precision => 3, :scale => 2, :default => 2.78
|
139
|
+
end
|
140
|
+
|
141
|
+
create_table :orders, :force => true do |t|
|
142
|
+
t.string :name
|
143
|
+
t.integer :billing_customer_id
|
144
|
+
t.integer :shipping_customer_id
|
145
|
+
end
|
146
|
+
|
147
|
+
create_table :people, :force => true do |t|
|
148
|
+
t.string :first_name, :null => false
|
149
|
+
t.integer :lock_version, :null => false, :default => 0
|
150
|
+
end
|
151
|
+
|
152
|
+
create_table :posts, :force => true do |t|
|
153
|
+
t.integer :author_id
|
154
|
+
t.string :title, :null => false
|
155
|
+
t.text :body, :null => false
|
156
|
+
t.string :type
|
157
|
+
end
|
158
|
+
|
159
|
+
create_table :projects, :force => true do |t|
|
160
|
+
t.string :name
|
161
|
+
t.string :type
|
162
|
+
end
|
163
|
+
|
164
|
+
create_table :readers, :force => true do |t|
|
165
|
+
t.integer :post_id, :null => false
|
166
|
+
t.integer :person_id, :null => false
|
167
|
+
end
|
168
|
+
|
169
|
+
create_table :subscribers, :force => true, :id => false do |t|
|
170
|
+
t.string :nick, :null => false
|
171
|
+
t.string :name
|
172
|
+
end
|
173
|
+
add_index :subscribers, :nick, :unique => true
|
174
|
+
|
175
|
+
create_table :tasks, :force => true do |t|
|
176
|
+
t.datetime :starting
|
177
|
+
t.datetime :ending
|
178
|
+
end
|
179
|
+
|
180
|
+
create_table :topics, :force => true do |t|
|
181
|
+
t.string :title
|
182
|
+
t.string :author_name
|
183
|
+
t.string :author_email_address
|
184
|
+
t.datetime :written_on
|
185
|
+
t.time :bonus_time
|
186
|
+
t.date :last_read
|
187
|
+
t.text :content
|
188
|
+
t.boolean :approved, :default => true
|
189
|
+
t.integer :replies_count, :default => 0
|
190
|
+
t.integer :parent_id
|
191
|
+
t.string :type
|
192
|
+
end
|
193
|
+
|
194
|
+
|
195
|
+
|
196
|
+
### These tables are created last as the order is significant
|
197
|
+
|
198
|
+
# fk_test_has_fk should be before fk_test_has_pk
|
199
|
+
create_table :fk_test_has_fk, :force => true do |t|
|
200
|
+
t.integer :fk_id, :null => false
|
201
|
+
end
|
202
|
+
|
203
|
+
create_table :fk_test_has_pk, :force => true do |t|
|
204
|
+
end
|
205
|
+
|
206
|
+
execute 'alter table fk_test_has_fk
|
207
|
+
add FOREIGN KEY (`fk_id`) REFERENCES `fk_test_has_pk`(`id`)'
|
208
|
+
|
209
|
+
|
210
|
+
end
|
211
|
+
|
212
|
+
# For Firebird, set the sequence values 10000 when create_table is called;
|
213
|
+
# this prevents primary key collisions between "normally" created records
|
214
|
+
# and fixture-based (YAML) records.
|
215
|
+
if adapter_name == "Firebird"
|
216
|
+
def create_table(*args, &block)
|
217
|
+
ActiveRecord::Base.connection.create_table(*args, &block)
|
218
|
+
ActiveRecord::Base.connection.execute "SET GENERATOR #{args.first}_seq TO 10000"
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
create_table :taggings, :force => true do |t|
|
223
|
+
t.column :tag_id, :integer
|
224
|
+
t.column :super_tag_id, :integer
|
225
|
+
t.column :taggable_type, :string
|
226
|
+
t.column :taggable_id, :integer
|
227
|
+
end
|
228
|
+
|
229
|
+
create_table :tags, :force => true do |t|
|
230
|
+
t.column :name, :string
|
231
|
+
t.column :taggings_count, :integer, :default => 0
|
232
|
+
end
|
233
|
+
|
234
|
+
create_table :categorizations, :force => true do |t|
|
235
|
+
t.column :category_id, :integer
|
236
|
+
t.column :post_id, :integer
|
237
|
+
t.column :author_id, :integer
|
238
|
+
end
|
239
|
+
|
240
|
+
add_column :posts, :taggings_count, :integer, :default => 0
|
241
|
+
add_column :authors, :author_address_id, :integer
|
242
|
+
|
243
|
+
create_table :author_addresses, :force => true do |t|
|
244
|
+
t.column :author_address_id, :integer
|
245
|
+
end
|
246
|
+
|
247
|
+
create_table :author_favorites, :force => true do |t|
|
248
|
+
t.column :author_id, :integer
|
249
|
+
t.column :favorite_author_id, :integer
|
250
|
+
end
|
251
|
+
|
252
|
+
create_table :vertices, :force => true do |t|
|
253
|
+
t.column :label, :string
|
254
|
+
end
|
255
|
+
|
256
|
+
create_table :edges, :force => true do |t|
|
257
|
+
t.column :source_id, :integer, :null => false
|
258
|
+
t.column :sink_id, :integer, :null => false
|
259
|
+
end
|
260
|
+
add_index :edges, [:source_id, :sink_id], :unique => true, :name => 'unique_edge_index'
|
261
|
+
|
262
|
+
create_table :lock_without_defaults, :force => true do |t|
|
263
|
+
t.column :lock_version, :integer
|
264
|
+
end
|
265
|
+
|
266
|
+
create_table :lock_without_defaults_cust, :force => true do |t|
|
267
|
+
t.column :custom_lock_version, :integer
|
268
|
+
end
|
269
|
+
|
270
|
+
if adapter_name == 'IBM_DB'
|
271
|
+
create_table :items, :force => true do |t|
|
272
|
+
t.column :name, :string
|
273
|
+
end
|
274
|
+
else
|
275
|
+
create_table :items, :force => true do |t|
|
276
|
+
t.column :name, :integer
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
|
281
|
+
# For sqlite 3.1.0+, make a table with a autoincrement column
|
282
|
+
if adapter_name == 'SQLite' and supports_autoincrement?
|
283
|
+
create_table :table_with_autoincrement, :force => true do |t|
|
284
|
+
t.column :name, :string
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
# For sqlserver 2000+, ensure real columns can be used
|
289
|
+
if adapter_name.starts_with?("SQLServer")
|
290
|
+
create_table :table_with_real_columns, :force => true do |t|
|
291
|
+
t.column :real_number, :real
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
295
|
+
create_table :audit_logs, :force => true do |t|
|
296
|
+
t.column :message, :string, :null=>false
|
297
|
+
t.column :developer_id, :integer, :null=>false
|
298
|
+
end
|
299
|
+
|
300
|
+
create_table :books, :force => true do |t|
|
301
|
+
t.column :name, :string
|
302
|
+
end
|
303
|
+
|
304
|
+
create_table :citations, :force => true do |t|
|
305
|
+
t.column :book1_id, :integer
|
306
|
+
t.column :book2_id, :integer
|
307
|
+
end
|
308
|
+
|
309
|
+
create_table :inept_wizards, :force => true do |t|
|
310
|
+
t.column :name, :string, :null => false
|
311
|
+
t.column :city, :string, :null => false
|
312
|
+
t.column :type, :string
|
313
|
+
end
|
314
|
+
|
315
|
+
create_table :parrots, :force => true do |t|
|
316
|
+
t.column :name, :string
|
317
|
+
t.column :parrot_sti_class, :string
|
318
|
+
t.column :killer_id, :integer
|
319
|
+
t.column :created_at, :datetime
|
320
|
+
t.column :created_on, :datetime
|
321
|
+
t.column :updated_at, :datetime
|
322
|
+
t.column :updated_on, :datetime
|
323
|
+
end
|
324
|
+
|
325
|
+
create_table :pirates, :force => true do |t|
|
326
|
+
t.column :catchphrase, :string
|
327
|
+
t.column :parrot_id, :integer
|
328
|
+
t.column :created_on, :datetime
|
329
|
+
t.column :updated_on, :datetime
|
330
|
+
end
|
331
|
+
|
332
|
+
create_table :parrots_pirates, :id => false, :force => true do |t|
|
333
|
+
t.column :parrot_id, :integer
|
334
|
+
t.column :pirate_id, :integer
|
335
|
+
end
|
336
|
+
|
337
|
+
create_table :treasures, :force => true do |t|
|
338
|
+
t.column :name, :string
|
339
|
+
t.column :looter_id, :integer
|
340
|
+
t.column :looter_type, :string
|
341
|
+
end
|
342
|
+
|
343
|
+
create_table :parrots_treasures, :id => false, :force => true do |t|
|
344
|
+
t.column :parrot_id, :integer
|
345
|
+
t.column :treasure_id, :integer
|
346
|
+
end
|
347
|
+
|
348
|
+
create_table :mateys, :id => false, :force => true do |t|
|
349
|
+
t.column :pirate_id, :integer
|
350
|
+
t.column :target_id, :integer
|
351
|
+
t.column :weight, :integer
|
352
|
+
end
|
353
|
+
|
354
|
+
create_table :ships, :force => true do |t|
|
355
|
+
t.string :name
|
356
|
+
t.datetime :created_at
|
357
|
+
t.datetime :created_on
|
358
|
+
t.datetime :updated_at
|
359
|
+
t.datetime :updated_on
|
360
|
+
end
|
361
|
+
end
|
@@ -33,7 +33,7 @@ CREATE TABLE topics (
|
|
33
33
|
title VARCHAR(255) DEFAULT NULL,
|
34
34
|
author_name VARCHAR(255) DEFAULT NULL,
|
35
35
|
author_email_address VARCHAR(255) DEFAULT NULL,
|
36
|
-
written_on
|
36
|
+
written_on TIME DEFAULT NULL,
|
37
37
|
--bonus_time TIMESTAMP DEFAULT NULL,
|
38
38
|
bonus_time TIME DEFAULT NULL,
|
39
39
|
last_read DATE DEFAULT NULL,
|
@@ -282,3 +282,7 @@ CREATE TABLE mixed_case_monkeys (
|
|
282
282
|
|
283
283
|
CREATE UNIQUE INDEX mixed_monkeys_idx ON
|
284
284
|
mixed_case_monkeys (monkeyID);
|
285
|
+
|
286
|
+
CREATE TABLE minimalistics (
|
287
|
+
id INT GENERATED BY DEFAULT AS IDENTITY (START WITH 100)
|
288
|
+
);
|
data/test/locking_test.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'abstract_unit'
|
2
2
|
require 'fixtures/person'
|
3
|
+
require 'fixtures/reader'
|
3
4
|
require 'fixtures/legacy_thing'
|
4
5
|
|
5
6
|
class LockWithoutDefault < ActiveRecord::Base; end
|
@@ -9,9 +10,18 @@ class LockWithCustomColumnWithoutDefault < ActiveRecord::Base
|
|
9
10
|
set_locking_column :custom_lock_version
|
10
11
|
end
|
11
12
|
|
12
|
-
class
|
13
|
+
class ReadonlyFirstNamePerson < Person
|
14
|
+
attr_readonly :first_name
|
15
|
+
end
|
16
|
+
|
17
|
+
class IBMDBOptimisticLockingTest < Test::Unit::TestCase
|
13
18
|
fixtures :people, :legacy_things
|
14
19
|
|
20
|
+
# need to disable transactional fixtures, because otherwise the sqlite3
|
21
|
+
# adapter (at least) chokes when we try and change the schema in the middle
|
22
|
+
# of a test (see test_increment_counter_*).
|
23
|
+
self.use_transactional_fixtures = false
|
24
|
+
|
15
25
|
def test_lock_existing
|
16
26
|
p1 = Person.find(1)
|
17
27
|
p2 = Person.find(1)
|
@@ -24,6 +34,20 @@ class OptimisticLockingTest < Test::Unit::TestCase
|
|
24
34
|
|
25
35
|
assert_raises(ActiveRecord::StaleObjectError) { p2.save! }
|
26
36
|
end
|
37
|
+
|
38
|
+
def test_lock_repeating
|
39
|
+
p1 = Person.find(1)
|
40
|
+
p2 = Person.find(1)
|
41
|
+
assert_equal 0, p1.lock_version
|
42
|
+
assert_equal 0, p2.lock_version
|
43
|
+
|
44
|
+
p1.save!
|
45
|
+
assert_equal 1, p1.lock_version
|
46
|
+
assert_equal 0, p2.lock_version
|
47
|
+
|
48
|
+
assert_raises(ActiveRecord::StaleObjectError) { p2.save! }
|
49
|
+
assert_raises(ActiveRecord::StaleObjectError) { p2.save! }
|
50
|
+
end
|
27
51
|
|
28
52
|
def test_lock_new
|
29
53
|
p1 = Person.new(:first_name => 'anika')
|
@@ -40,6 +64,15 @@ class OptimisticLockingTest < Test::Unit::TestCase
|
|
40
64
|
|
41
65
|
assert_raises(ActiveRecord::StaleObjectError) { p2.save! }
|
42
66
|
end
|
67
|
+
|
68
|
+
def test_lock_new_with_nil
|
69
|
+
p1 = Person.new(:first_name => 'anika')
|
70
|
+
p1.save!
|
71
|
+
p1.lock_version = nil # simulate bad fixture or column with no default
|
72
|
+
p1.save!
|
73
|
+
assert_equal 1, p1.lock_version
|
74
|
+
end
|
75
|
+
|
43
76
|
|
44
77
|
def test_lock_column_name_existing
|
45
78
|
t1 = LegacyThing.find(1)
|
@@ -73,6 +106,65 @@ class OptimisticLockingTest < Test::Unit::TestCase
|
|
73
106
|
t1 = LockWithCustomColumnWithoutDefault.new
|
74
107
|
assert_equal 0, t1.custom_lock_version
|
75
108
|
end
|
109
|
+
|
110
|
+
def test_readonly_attributes
|
111
|
+
assert_equal Set.new([ 'first_name' ]), ReadonlyFirstNamePerson.readonly_attributes
|
112
|
+
|
113
|
+
p = ReadonlyFirstNamePerson.create(:first_name => "unchangeable name")
|
114
|
+
p.reload
|
115
|
+
assert_equal "unchangeable name", p.first_name
|
116
|
+
|
117
|
+
p.update_attributes(:first_name => "changed name")
|
118
|
+
p.reload
|
119
|
+
assert_equal "unchangeable name", p.first_name
|
120
|
+
end
|
121
|
+
|
122
|
+
{ :lock_version => Person, :custom_lock_version => LegacyThing }.each do |name, model|
|
123
|
+
define_method("test_increment_counter_updates_#{name}") do
|
124
|
+
counter_test model, 1 do |id|
|
125
|
+
model.increment_counter :test_count, id
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
define_method("test_decrement_counter_updates_#{name}") do
|
130
|
+
counter_test model, -1 do |id|
|
131
|
+
model.decrement_counter :test_count, id
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
define_method("test_update_counters_updates_#{name}") do
|
136
|
+
counter_test model, 1 do |id|
|
137
|
+
model.update_counters id, :test_count => 1
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
private
|
143
|
+
|
144
|
+
def add_counter_column_to(model)
|
145
|
+
model.connection.add_column model.table_name, :test_count, :integer, :null => false, :default => 0
|
146
|
+
model.reset_column_information
|
147
|
+
# OpenBase does not set a value to existing rows when adding a not null default column
|
148
|
+
model.update_all(:test_count => 0) if current_adapter?(:OpenBaseAdapter)
|
149
|
+
end
|
150
|
+
|
151
|
+
def remove_counter_column_from(model)
|
152
|
+
model.connection.remove_column model.table_name, :test_count
|
153
|
+
model.reset_column_information
|
154
|
+
end
|
155
|
+
|
156
|
+
def counter_test(model, expected_count)
|
157
|
+
add_counter_column_to(model)
|
158
|
+
object = model.find(:first)
|
159
|
+
assert_equal 0, object.test_count
|
160
|
+
assert_equal 0, object.send(model.locking_column)
|
161
|
+
yield object.id
|
162
|
+
object.reload
|
163
|
+
assert_equal expected_count, object.test_count
|
164
|
+
assert_equal 1, object.send(model.locking_column)
|
165
|
+
ensure
|
166
|
+
remove_counter_column_from(model)
|
167
|
+
end
|
76
168
|
end
|
77
169
|
|
78
170
|
|
@@ -81,9 +173,9 @@ end
|
|
81
173
|
# blocks, so separate script called by Kernel#system is needed.
|
82
174
|
# (See exec vs. async_exec in the PostgreSQL adapter.)
|
83
175
|
|
84
|
-
# TODO: The SQL Server and
|
176
|
+
# TODO: The SQL Server, Sybase, and OpenBase adapters currently have no support for pessimistic locking
|
85
177
|
|
86
|
-
unless current_adapter?(:SQLServerAdapter, :SybaseAdapter)
|
178
|
+
unless current_adapter?(:SQLServerAdapter, :SybaseAdapter, :OpenBaseAdapter)
|
87
179
|
class PessimisticLockingTest < Test::Unit::TestCase
|
88
180
|
self.use_transactional_fixtures = false
|
89
181
|
fixtures :people, :readers
|