ibm_db 0.9.4 → 0.9.5
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 +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
|