ibm_db 0.4.0 → 0.4.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,2 @@
1
+ DROP TABLE courses;
2
+
@@ -0,0 +1,5 @@
1
+ CREATE TABLE courses (
2
+ id INT NOT NULL PRIMARY KEY,
3
+ name VARCHAR(255) NOT NULL
4
+ );
5
+
@@ -0,0 +1,32 @@
1
+ DROP TABLE accounts;
2
+ DROP TABLE funny_jokes;
3
+ DROP TABLE companies;
4
+ DROP TABLE topics;
5
+ DROP TABLE developers;
6
+ DROP TABLE projects;
7
+ DROP TABLE developers_projects;
8
+ DROP TABLE orders;
9
+ DROP TABLE customers;
10
+ DROP TABLE movies;
11
+ DROP TABLE subscribers;
12
+ DROP TABLE booleantests;
13
+ DROP TABLE auto_id_tests;
14
+ DROP TABLE entrants;
15
+ DROP TABLE colnametests;
16
+ DROP TABLE mixins;
17
+ DROP TABLE people;
18
+ DROP TABLE readers;
19
+ DROP TABLE binaries;
20
+ DROP TABLE computers;
21
+ DROP TABLE posts;
22
+ DROP TABLE comments;
23
+ DROP TABLE authors;
24
+ DROP TABLE tasks;
25
+ DROP TABLE categories;
26
+ DROP TABLE categories_posts;
27
+ DROP TABLE fk_test_has_pk;
28
+ DROP TABLE fk_test_has_fk;
29
+ DROP TABLE keyboards;
30
+ DROP TABLE legacy_things;
31
+ DROP TABLE numeric_data;
32
+ DROP TABLE mixed_case_monkeys;
@@ -0,0 +1,284 @@
1
+ CREATE TABLE accounts (
2
+ id INT GENERATED BY DEFAULT AS IDENTITY (START WITH 100),
3
+ firm_id INT DEFAULT NULL,
4
+ credit_limit INT DEFAULT NULL,
5
+ PRIMARY KEY (id)
6
+ );
7
+ CREATE UNIQUE INDEX accounts_id_idx ON
8
+ accounts (id);
9
+
10
+ CREATE TABLE funny_jokes (
11
+ id INT GENERATED BY DEFAULT AS IDENTITY (START WITH 100),
12
+ name VARCHAR(50) DEFAULT NULL,
13
+ PRIMARY KEY (id)
14
+ );
15
+ CREATE UNIQUE INDEX funny_jokes_id_idx ON
16
+ funny_jokes (id);
17
+
18
+ CREATE TABLE companies (
19
+ id INT GENERATED BY DEFAULT AS IDENTITY (START WITH 100),
20
+ type VARCHAR(50) DEFAULT NULL,
21
+ ruby_type VARCHAR(50) DEFAULT NULL,
22
+ firm_id INT DEFAULT NULL,
23
+ name VARCHAR(50) DEFAULT NULL,
24
+ client_of INT DEFAULT NULL,
25
+ rating INT DEFAULT 1,
26
+ PRIMARY KEY (id)
27
+ );
28
+ CREATE UNIQUE INDEX companies_id_idx ON
29
+ companies (id);
30
+
31
+ CREATE TABLE topics (
32
+ id INT GENERATED BY DEFAULT AS IDENTITY (START WITH 100),
33
+ title VARCHAR(255) DEFAULT NULL,
34
+ author_name VARCHAR(255) DEFAULT NULL,
35
+ author_email_address VARCHAR(255) DEFAULT NULL,
36
+ written_on TIMESTAMP DEFAULT NULL,
37
+ --bonus_time TIMESTAMP DEFAULT NULL,
38
+ bonus_time TIME DEFAULT NULL,
39
+ last_read DATE DEFAULT NULL,
40
+ content VARCHAR(3000),
41
+ approved SMALLINT DEFAULT 1,
42
+ replies_count INT DEFAULT 0,
43
+ parent_id INT DEFAULT NULL,
44
+ type VARCHAR(50) DEFAULT NULL,
45
+ PRIMARY KEY (id)
46
+ );
47
+ CREATE UNIQUE INDEX topics_id_idx ON
48
+ topics (id);
49
+
50
+ CREATE TABLE developers (
51
+ id INT GENERATED BY DEFAULT AS IDENTITY (START WITH 100),
52
+ name VARCHAR(100) DEFAULT NULL,
53
+ salary INT DEFAULT 70000,
54
+ created_at TIMESTAMP DEFAULT NULL,
55
+ updated_at TIMESTAMP DEFAULT NULL,
56
+ PRIMARY KEY (id)
57
+ );
58
+ CREATE UNIQUE INDEX developers_id_idx ON
59
+ developers (id);
60
+
61
+ CREATE TABLE projects (
62
+ id INT GENERATED BY DEFAULT AS IDENTITY (START WITH 100),
63
+ name VARCHAR(100) DEFAULT NULL,
64
+ type VARCHAR(255) DEFAULT NULL,
65
+ PRIMARY KEY (id)
66
+ );
67
+ CREATE UNIQUE INDEX projects_id_idx ON
68
+ projects (id);
69
+
70
+ CREATE TABLE developers_projects (
71
+ developer_id INT NOT NULL,
72
+ project_id INT NOT NULL,
73
+ joined_on DATE DEFAULT NULL,
74
+ access_level SMALLINT DEFAULT 1
75
+ );
76
+
77
+ CREATE TABLE orders (
78
+ id INT GENERATED BY DEFAULT AS IDENTITY (START WITH 100),
79
+ name VARCHAR(100) DEFAULT NULL,
80
+ billing_customer_id INT DEFAULT NULL,
81
+ shipping_customer_id INT DEFAULT NULL,
82
+ PRIMARY KEY (id)
83
+ );
84
+ CREATE UNIQUE INDEX orders_idx ON
85
+ orders (id);
86
+
87
+ CREATE TABLE customers (
88
+ id INT GENERATED BY DEFAULT AS IDENTITY (START WITH 100),
89
+ name VARCHAR(100) DEFAULT NULL,
90
+ balance INT DEFAULT 0,
91
+ address_street VARCHAR(100) DEFAULT NULL,
92
+ address_city VARCHAR(100) DEFAULT NULL,
93
+ address_country VARCHAR(100) DEFAULT NULL,
94
+ gps_location VARCHAR(100) DEFAULT NULL,
95
+ PRIMARY KEY (id)
96
+ );
97
+ CREATE UNIQUE INDEX customers_id_idx ON
98
+ customers (id);
99
+
100
+ CREATE TABLE movies (
101
+ movieid INT GENERATED BY DEFAULT AS IDENTITY (START WITH 100),
102
+ name VARCHAR(100) DEFAULT NULL,
103
+ PRIMARY KEY (movieid)
104
+ );
105
+ CREATE UNIQUE INDEX movies_id_idx ON
106
+ movies (movieid);
107
+
108
+ CREATE TABLE subscribers (
109
+ nick VARCHAR(100) NOT NULL,
110
+ name VARCHAR(100) DEFAULT NULL,
111
+ PRIMARY KEY (nick)
112
+ );
113
+ CREATE UNIQUE INDEX subscribers_id_idx ON
114
+ subscribers (nick);
115
+
116
+ CREATE TABLE booleantests (
117
+ id INT GENERATED BY DEFAULT AS IDENTITY (START WITH 100),
118
+ value INT DEFAULT NULL,
119
+ PRIMARY KEY (id)
120
+ );
121
+ CREATE UNIQUE INDEX booleantest_id_idx ON
122
+ booleantests (id);
123
+
124
+ CREATE TABLE auto_id_tests (
125
+ auto_id INT GENERATED BY DEFAULT AS IDENTITY (START WITH 100),
126
+ value INT DEFAULT NULL,
127
+ PRIMARY KEY (auto_id)
128
+ );
129
+ CREATE UNIQUE INDEX auto_id_tests_idx ON
130
+ auto_id_tests (auto_id);
131
+
132
+ CREATE TABLE entrants (
133
+ id INT NOT NULL PRIMARY KEY,
134
+ name VARCHAR(255) NOT NULL,
135
+ course_id INT NOT NULL
136
+ );
137
+ CREATE UNIQUE INDEX entrants_id_idx ON
138
+ entrants (id);
139
+
140
+ CREATE TABLE colnametests (
141
+ id INT GENERATED BY DEFAULT AS IDENTITY (START WITH 100),
142
+ references INT NOT NULL,
143
+ PRIMARY KEY (id)
144
+ );
145
+ CREATE UNIQUE INDEX colnametest_id_idx ON
146
+ colnametests (id);
147
+
148
+ CREATE TABLE mixins (
149
+ id INT GENERATED BY DEFAULT AS IDENTITY (START WITH 100),
150
+ parent_id INT DEFAULT NULL,
151
+ pos INT DEFAULT NULL,
152
+ created_at TIMESTAMP DEFAULT NULL,
153
+ updated_at TIMESTAMP DEFAULT NULL,
154
+ lft INT DEFAULT NULL,
155
+ rgt INT DEFAULT NULL,
156
+ root_id INT DEFAULT NULL,
157
+ type VARCHAR(40) DEFAULT NULL,
158
+ PRIMARY KEY (id)
159
+ );
160
+ CREATE UNIQUE INDEX mixins_id_idx ON
161
+ mixins (id);
162
+
163
+ CREATE TABLE people (
164
+ id INT GENERATED BY DEFAULT AS IDENTITY (START WITH 100),
165
+ first_name VARCHAR(40) NOT NULL,
166
+ lock_version INT DEFAULT 0,
167
+ PRIMARY KEY (id)
168
+ );
169
+ CREATE UNIQUE INDEX people_id_idx ON
170
+ people (id);
171
+
172
+ CREATE TABLE readers (
173
+ id INT GENERATED BY DEFAULT AS IDENTITY (START WITH 100),
174
+ post_id INT NOT NULL,
175
+ person_id INT NOT NULL,
176
+ PRIMARY KEY (id)
177
+ );
178
+ CREATE UNIQUE INDEX readers_id_idx ON
179
+ readers (id);
180
+
181
+ CREATE TABLE binaries (
182
+ id INT GENERATED BY DEFAULT AS IDENTITY (START WITH 100),
183
+ data BLOB(5000000),
184
+ PRIMARY KEY (id)
185
+ );
186
+ CREATE UNIQUE INDEX binaries_id_idx ON
187
+ binaries (id);
188
+ --CREATE LOB TABLESPACE datalob;
189
+ --CREATE AUXILIARY TABLE data_aux IN datalob
190
+ --STORES binaries COLUMN data;
191
+ --CREATE UNIQUE INDEX lob_data_idx ON data_aux;
192
+
193
+ CREATE TABLE computers (
194
+ id INT GENERATED BY DEFAULT AS IDENTITY (START WITH 100),
195
+ developer INT NOT NULL,
196
+ extendedWarranty INT NOT NULL
197
+ );
198
+
199
+ CREATE TABLE posts (
200
+ id INT GENERATED BY DEFAULT AS IDENTITY (START WITH 100),
201
+ author_id INT DEFAULT NULL,
202
+ title VARCHAR(255) DEFAULT NULL,
203
+ type VARCHAR(255) DEFAULT NULL,
204
+ body VARCHAR(3000) DEFAULT NULL
205
+ );
206
+
207
+ CREATE TABLE comments (
208
+ id INT GENERATED BY DEFAULT AS IDENTITY (START WITH 100),
209
+ post_id INT DEFAULT NULL,
210
+ type VARCHAR(255) DEFAULT NULL,
211
+ body VARCHAR(3000) DEFAULT NULL
212
+ );
213
+
214
+ CREATE TABLE authors (
215
+ id INT GENERATED BY DEFAULT AS IDENTITY (START WITH 100),
216
+ name VARCHAR(255) DEFAULT NULL
217
+ );
218
+
219
+ CREATE TABLE tasks (
220
+ id INT GENERATED BY DEFAULT AS IDENTITY (START WITH 100),
221
+ starting TIMESTAMP DEFAULT NULL,
222
+ ending TIMESTAMP DEFAULT NULL
223
+ );
224
+
225
+ CREATE TABLE categories (
226
+ id INT GENERATED BY DEFAULT AS IDENTITY (START WITH 100),
227
+ name VARCHAR(255) NOT NULL,
228
+ type VARCHAR(40) DEFAULT NULL
229
+ );
230
+
231
+ CREATE TABLE categories_posts (
232
+ category_id INT NOT NULL,
233
+ post_id INT NOT NULL
234
+ );
235
+
236
+ CREATE TABLE keyboards (
237
+ key_number INT GENERATED BY DEFAULT AS IDENTITY (START WITH 100),
238
+ name VARCHAR(255)
239
+ );
240
+
241
+ CREATE TABLE fk_test_has_pk (
242
+ id INT NOT NULL PRIMARY KEY
243
+ );
244
+ CREATE UNIQUE INDEX fk_test_has_id_idx ON
245
+ fk_test_has_pk (id);
246
+
247
+ CREATE TABLE fk_test_has_fk (
248
+ id INT NOT NULL PRIMARY KEY,
249
+ fk_id INT NOT NULL,
250
+
251
+ FOREIGN KEY (fk_id) REFERENCES fk_test_has_pk(id)
252
+ );
253
+ CREATE UNIQUE INDEX fk_test_has_fk_idx ON
254
+ fk_test_has_fk (id);
255
+
256
+ --This table has an altered lock_version column name
257
+ CREATE TABLE legacy_things (
258
+ id INT GENERATED BY DEFAULT AS IDENTITY (START WITH 100),
259
+ tps_report_number INT DEFAULT NULL,
260
+ version INT DEFAULT 0,
261
+ PRIMARY KEY (id)
262
+ );
263
+ CREATE UNIQUE INDEX legacy_thin_id_idx ON
264
+ legacy_things (id);
265
+
266
+ CREATE TABLE numeric_data (
267
+ id INT GENERATED BY DEFAULT AS IDENTITY (START WITH 100),
268
+ bank_balance DECIMAL(10,2),
269
+ big_bank_balance DECIMAL(15,2),
270
+ world_population DECIMAL(10),
271
+ my_house_population DECIMAL(2),
272
+ decimal_number_with_default DECIMAL(3,2) DEFAULT 2.78
273
+ );
274
+ CREATE UNIQUE INDEX numeric_data_idx ON
275
+ numeric_data (id);
276
+
277
+ CREATE TABLE mixed_case_monkeys (
278
+ monkeyID INT GENERATED BY DEFAULT AS IDENTITY (START WITH 100),
279
+ fleaCount INT DEFAULT 0,
280
+ PRIMARY KEY (monkeyID)
281
+ );
282
+
283
+ CREATE UNIQUE INDEX mixed_monkeys_idx ON
284
+ mixed_case_monkeys (monkeyID);
@@ -0,0 +1,2 @@
1
+ DROP TABLE courses;
2
+
@@ -0,0 +1,7 @@
1
+ CREATE TABLE courses (
2
+ id INT NOT NULL PRIMARY KEY,
3
+ name VARCHAR(255) NOT NULL
4
+ );
5
+ CREATE UNIQUE INDEX courses_id_idx ON
6
+ courses (id);
7
+
@@ -0,0 +1,190 @@
1
+ require 'abstract_unit'
2
+ require 'fixtures/person'
3
+ require 'fixtures/legacy_thing'
4
+
5
+ class LockWithoutDefault < ActiveRecord::Base; end
6
+
7
+ class LockWithCustomColumnWithoutDefault < ActiveRecord::Base
8
+ set_table_name :lock_without_defaults_cust
9
+ set_locking_column :custom_lock_version
10
+ end
11
+
12
+ class OptimisticLockingTest < Test::Unit::TestCase
13
+ fixtures :people, :legacy_things
14
+
15
+ def test_lock_existing
16
+ p1 = Person.find(1)
17
+ p2 = Person.find(1)
18
+ assert_equal 0, p1.lock_version
19
+ assert_equal 0, p2.lock_version
20
+
21
+ p1.save!
22
+ assert_equal 1, p1.lock_version
23
+ assert_equal 0, p2.lock_version
24
+
25
+ assert_raises(ActiveRecord::StaleObjectError) { p2.save! }
26
+ end
27
+
28
+ def test_lock_new
29
+ p1 = Person.new(:first_name => 'anika')
30
+ assert_equal 0, p1.lock_version
31
+
32
+ p1.save!
33
+ p2 = Person.find(p1.id)
34
+ assert_equal 0, p1.lock_version
35
+ assert_equal 0, p2.lock_version
36
+
37
+ p1.save!
38
+ assert_equal 1, p1.lock_version
39
+ assert_equal 0, p2.lock_version
40
+
41
+ assert_raises(ActiveRecord::StaleObjectError) { p2.save! }
42
+ end
43
+
44
+ def test_lock_column_name_existing
45
+ t1 = LegacyThing.find(1)
46
+ t2 = LegacyThing.find(1)
47
+ assert_equal 0, t1.version
48
+ assert_equal 0, t2.version
49
+
50
+ t1.save!
51
+ assert_equal 1, t1.version
52
+ assert_equal 0, t2.version
53
+
54
+ assert_raises(ActiveRecord::StaleObjectError) { t2.save! }
55
+ end
56
+
57
+ def test_lock_column_is_mass_assignable
58
+ p1 = Person.create(:first_name => 'bianca')
59
+ assert_equal 0, p1.lock_version
60
+ assert_equal p1.lock_version, Person.new(p1.attributes).lock_version
61
+
62
+ p1.save!
63
+ assert_equal 1, p1.lock_version
64
+ assert_equal p1.lock_version, Person.new(p1.attributes).lock_version
65
+ end
66
+
67
+ def test_lock_without_default_sets_version_to_zero
68
+ t1 = LockWithoutDefault.new
69
+ assert_equal 0, t1.lock_version
70
+ end
71
+
72
+ def test_lock_with_custom_column_without_default_sets_version_to_zero
73
+ t1 = LockWithCustomColumnWithoutDefault.new
74
+ assert_equal 0, t1.custom_lock_version
75
+ end
76
+ end
77
+
78
+
79
+ # TODO: test against the generated SQL since testing locking behavior itself
80
+ # is so cumbersome. Will deadlock Ruby threads if the underlying db.execute
81
+ # blocks, so separate script called by Kernel#system is needed.
82
+ # (See exec vs. async_exec in the PostgreSQL adapter.)
83
+
84
+ # TODO: The SQL Server and Sybase adapters currently have no support for pessimistic locking
85
+
86
+ unless current_adapter?(:SQLServerAdapter, :SybaseAdapter)
87
+ class PessimisticLockingTest < Test::Unit::TestCase
88
+ self.use_transactional_fixtures = false
89
+ fixtures :people, :readers
90
+
91
+ def setup
92
+ # Avoid introspection queries during tests.
93
+ Person.columns; Reader.columns
94
+
95
+ @allow_concurrency = ActiveRecord::Base.allow_concurrency
96
+ ActiveRecord::Base.allow_concurrency = true
97
+ end
98
+
99
+ def teardown
100
+ ActiveRecord::Base.allow_concurrency = @allow_concurrency
101
+ end
102
+
103
+ # Test typical find.
104
+ def test_sane_find_with_lock
105
+ assert_nothing_raised do
106
+ Person.transaction do
107
+ Person.find 1, :lock => true
108
+ end
109
+ end
110
+ end
111
+
112
+ # Test scoped lock.
113
+ def test_sane_find_with_scoped_lock
114
+ assert_nothing_raised do
115
+ Person.transaction do
116
+ Person.with_scope(:find => { :lock => true }) do
117
+ Person.find 1
118
+ end
119
+ end
120
+ end
121
+ end
122
+
123
+ # PostgreSQL protests SELECT ... FOR UPDATE on an outer join.
124
+ unless current_adapter?(:PostgreSQLAdapter, :IBM_DBAdapter)
125
+ # Test locked eager find.
126
+ def test_eager_find_with_lock
127
+ assert_nothing_raised do
128
+ Person.transaction do
129
+ Person.find 1, :include => :readers, :lock => true
130
+ end
131
+ end
132
+ end
133
+ end
134
+
135
+ # Locking a record reloads it.
136
+ def test_sane_lock_method
137
+ assert_nothing_raised do
138
+ Person.transaction do
139
+ person = Person.find 1
140
+ old, person.first_name = person.first_name, 'fooman'
141
+ person.lock!
142
+ assert_equal old, person.first_name
143
+ end
144
+ end
145
+ end
146
+
147
+ if current_adapter?(:PostgreSQLAdapter, :OracleAdapter)
148
+ def test_no_locks_no_wait
149
+ first, second = duel { Person.find 1 }
150
+ assert first.end > second.end
151
+ end
152
+
153
+ def test_second_lock_waits
154
+ assert [0.2, 1, 5].any? { |zzz|
155
+ first, second = duel(zzz) { Person.find 1, :lock => true }
156
+ second.end > first.end
157
+ }
158
+ end
159
+
160
+ protected
161
+ def duel(zzz = 5)
162
+ t0, t1, t2, t3 = nil, nil, nil, nil
163
+
164
+ a = Thread.new do
165
+ t0 = Time.now
166
+ Person.transaction do
167
+ yield
168
+ sleep zzz # block thread 2 for zzz seconds
169
+ end
170
+ t1 = Time.now
171
+ end
172
+
173
+ b = Thread.new do
174
+ sleep zzz / 2.0 # ensure thread 1 tx starts first
175
+ t2 = Time.now
176
+ Person.transaction { yield }
177
+ t3 = Time.now
178
+ end
179
+
180
+ a.join
181
+ b.join
182
+
183
+ assert t1 > t0 + zzz
184
+ assert t2 > t0
185
+ assert t3 > t2
186
+ [t0.to_f..t1.to_f, t2.to_f..t3.to_f]
187
+ end
188
+ end
189
+ end
190
+ end