transactd 2.0.1 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/BUILD_UNIX-JA +6 -6
- data/README +16 -16
- data/README-JA +16 -16
- data/bin/common/tdclc_32_2_1.dll +0 -0
- data/bin/common/tdclc_64_2_1.dll +0 -0
- data/build/common/transactd_cl_common.cmake +0 -1
- data/build/common/transactd_common.cmake +28 -38
- data/build/swig/ruby/ruby.swg +36 -30
- data/build/swig/ruby/tdclrb_wrap.cpp +35016 -0
- data/build/swig/tdcl.i +217 -62
- data/build/tdclc/CMakeLists.txt +14 -26
- data/build/tdclc/libtdclcm.map +4 -0
- data/build/tdclc/tdclc.cbproj +1 -1
- data/build/tdclc/tdclc.rc +0 -0
- data/build/tdclcpp/CMakeLists.txt +7 -22
- data/build/tdclcpp/tdclcpp.rc +0 -0
- data/build/tdclcpp/tdclcpp_bc.cbproj +1 -1
- data/build/tdclrb/CMakeLists.txt +7 -49
- data/build/tdclrb/tdclrb.rc +62 -0
- data/source/bzs/db/blobBuffer.h +5 -0
- data/source/bzs/db/blobStructs.h +2 -0
- data/source/bzs/db/engine/mysql/IReadRecords.h +9 -0
- data/source/bzs/db/engine/mysql/database.cpp +391 -169
- data/source/bzs/db/engine/mysql/database.h +178 -40
- data/source/bzs/db/engine/mysql/dbManager.cpp +45 -3
- data/source/bzs/db/engine/mysql/dbManager.h +3 -39
- data/source/bzs/db/engine/mysql/errorMessage.cpp +11 -7
- data/source/bzs/db/engine/mysql/errorMessage.h +1 -1
- data/source/bzs/db/engine/mysql/mydebuglog.cpp +1 -2
- data/source/bzs/db/engine/mysql/mysqlInternal.h +8 -8
- data/source/bzs/db/engine/mysql/mysqlThd.cpp +11 -0
- data/source/bzs/db/protocol/hs/hsCommandExecuter.cpp +1 -1
- data/source/bzs/db/protocol/tdap/client/activeTable.cpp +41 -6
- data/source/bzs/db/protocol/tdap/client/activeTable.h +177 -8
- data/source/bzs/db/protocol/tdap/client/activeTableImple.h +141 -62
- data/source/bzs/db/protocol/tdap/client/client.cpp +39 -35
- data/source/bzs/db/protocol/tdap/client/client.h +52 -25
- data/source/bzs/db/protocol/tdap/client/connectionPool.cpp +17 -0
- data/source/bzs/db/protocol/tdap/client/connectionPool.h +1 -0
- data/source/bzs/db/protocol/tdap/client/database.cpp +5 -1
- data/source/bzs/db/protocol/tdap/client/database.h +1 -1
- data/source/bzs/db/protocol/tdap/client/databaseFactory.cpp +49 -12
- data/source/bzs/db/protocol/tdap/client/databaseManager.h +42 -5
- data/source/bzs/db/protocol/tdap/client/dbDef.cpp +4 -2
- data/source/bzs/db/protocol/tdap/client/dllmain.cpp +71 -41
- data/source/bzs/db/protocol/tdap/client/errorMessage_ja.cpp +49 -49
- data/source/bzs/db/protocol/tdap/client/field.cpp +22 -13
- data/source/bzs/db/protocol/tdap/client/field.h +7 -3
- data/source/bzs/db/protocol/tdap/client/fieldDDF.cpp +1 -1
- data/source/bzs/db/protocol/tdap/client/fieldNameAlias.cpp +0 -1
- data/source/bzs/db/protocol/tdap/client/fieldNameAlias.h +1 -0
- data/source/bzs/db/protocol/tdap/client/fields.h +111 -24
- data/source/bzs/db/protocol/tdap/client/fileDDF.cpp +1 -1
- data/source/bzs/db/protocol/tdap/client/filter.h +687 -310
- data/source/bzs/db/protocol/tdap/client/groupQuery.cpp +12 -4
- data/source/bzs/db/protocol/tdap/client/indexDDF.cpp +1 -1
- data/source/bzs/db/protocol/tdap/client/memRecord.cpp +190 -32
- data/source/bzs/db/protocol/tdap/client/memRecord.h +64 -22
- data/source/bzs/db/protocol/tdap/client/nsDatabase.cpp +4 -4
- data/source/bzs/db/protocol/tdap/client/nsDatabase.h +4 -2
- data/source/bzs/db/protocol/tdap/client/nsTable.cpp +6 -3
- data/source/bzs/db/protocol/tdap/client/nsTable.h +1 -1
- data/source/bzs/db/protocol/tdap/client/pooledDatabaseManager.h +19 -8
- data/source/bzs/db/protocol/tdap/client/recordsetImple.h +194 -87
- data/source/bzs/db/protocol/tdap/client/request.h +84 -26
- data/source/bzs/db/protocol/tdap/client/stringConverter.h +22 -12
- data/source/bzs/db/protocol/tdap/client/table.cpp +494 -286
- data/source/bzs/db/protocol/tdap/client/table.h +48 -5
- data/source/bzs/db/protocol/tdap/client/trdboostapi.h +133 -87
- data/source/bzs/db/protocol/tdap/client/trdboostapiInternal.h +22 -22
- data/source/bzs/db/protocol/tdap/client/trdormapi.h +43 -18
- data/source/bzs/db/protocol/tdap/client/trnsctcl.def +3 -3
- data/source/bzs/db/protocol/tdap/mysql/databaseSchema.cpp +1 -0
- data/source/bzs/db/protocol/tdap/mysql/recordsetReader.h +268 -74
- data/source/bzs/db/protocol/tdap/mysql/request.h +4 -4
- data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.cpp +179 -43
- data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.h +4 -4
- data/source/bzs/db/protocol/tdap/tdapRequest.h +15 -14
- data/source/bzs/db/protocol/tdap/tdapSchema.h +125 -90
- data/source/bzs/db/protocol/tdap/tdapcapi.h +46 -5
- data/source/bzs/db/transactd/appModule.h +1 -1
- data/source/bzs/db/transactd/connManager.cpp +2 -0
- data/source/bzs/db/transactd/transactd.cpp +1 -0
- data/source/bzs/env/compiler.h +10 -0
- data/source/bzs/env/mbcswchrLinux.cpp +42 -6
- data/source/bzs/env/mbcswchrLinux.h +40 -12
- data/source/bzs/example/queryData.cpp +33 -4
- data/source/bzs/netsvc/client/iconnection.h +107 -0
- data/source/bzs/netsvc/client/tcpClient.cpp +15 -1
- data/source/bzs/netsvc/client/tcpClient.h +96 -87
- data/source/bzs/netsvc/server/serverCpt.cpp +5 -6
- data/source/bzs/rtl/benchmark.cpp +2 -2
- data/source/bzs/rtl/stringBuffers.cpp +3 -3
- data/source/bzs/rtl/stringBuffers.h +2 -2
- data/source/bzs/test/tdclatl/bench_query_atl.js +92 -99
- data/source/bzs/test/tdclatl/test_query_atl.js +224 -115
- data/source/bzs/test/tdclphp/bench.php +126 -101
- data/source/bzs/test/tdclphp/transactd_Test.php +1122 -158
- data/source/bzs/test/tdclrb/bench_tdclcpp.rb +12 -14
- data/source/bzs/test/tdclrb/transactd_spec.rb +1127 -142
- data/source/bzs/test/transactdBench/query_bench.cpp +32 -15
- data/source/bzs/test/transactdBench/scaling_bench.cpp +32 -7
- data/source/bzs/test/transactdBench/transactdBench.cpp +1 -1
- data/source/bzs/test/transactdBench/workerBase.h +46 -0
- data/source/bzs/test/transactdBench/workerMySQLImple.h +15 -7
- data/source/bzs/test/transactdBench/workerTransactdImple.h +10 -18
- data/source/bzs/test/trdclengn/test_trdclengn.cpp +1487 -174
- data/source/global/ormsrcgen/main.cpp +2 -0
- data/source/global/tdclatl/Database.cpp +2 -2
- data/source/global/tdclatl/Database.h +1 -1
- data/source/global/tdclatl/FieldDefs.cpp +0 -3
- data/source/global/tdclatl/PooledDbManager.cpp +2 -2
- data/source/global/tdclatl/PooledDbManager.h +1 -1
- data/source/global/tdclatl/PreparedQuery.cpp +53 -0
- data/source/global/tdclatl/PreparedQuery.h +61 -0
- data/source/global/tdclatl/QueryBase.cpp +2 -1
- data/source/global/tdclatl/QueryBase.h +1 -1
- data/source/global/tdclatl/Record.cpp +3 -15
- data/source/global/tdclatl/Recordset.cpp +15 -10
- data/source/global/tdclatl/Recordset.h +3 -0
- data/source/global/tdclatl/Table.cpp +42 -7
- data/source/global/tdclatl/Table.h +3 -1
- data/source/global/tdclatl/activeTable.cpp +264 -76
- data/source/global/tdclatl/activeTable.h +12 -3
- data/source/global/tdclatl/tdclatl.idl +92 -10
- data/source/linux/charsetConvert.h +7 -7
- data/transactd.gemspec +14 -27
- metadata +18 -27
- data/bin/common/tdclc_32_2_0.dll +0 -0
- data/bin/common/tdclc_64_2_0.dll +0 -0
- data/build/swig/php/generate.cmake.in +0 -56
- data/build/swig/php/generate.cmd.in +0 -47
- data/build/swig/php/php.swg +0 -197
- data/build/swig/php/transactd.no_yield.php +0 -4494
- data/build/swig/php/transactd.no_yield.php.git.patch +0 -685
- data/build/swig/php/transactd.no_yield.php.patch +0 -685
- data/build/swig/php/transactd.yield.php +0 -4461
- data/build/swig/php/transactd.yield.php.git.patch +0 -652
- data/build/swig/php/transactd.yield.php.patch +0 -652
- data/build/swig/ruby/generate.cmake.in +0 -35
- data/build/swig/ruby/generate.cmd.in +0 -19
- data/build/tdclc/BUILDNUMBER.txt +0 -1
- data/build/tdclcpp/BUILDNUMBER.txt +0 -1
- data/build/tdclrb/BUILDNUMBER.txt +0 -1
- data/build/tdclrb/GEM_RELEASE_VERSION +0 -1
@@ -21,16 +21,14 @@ mb_internal_encoding('UTF-8');
|
|
21
21
|
|
22
22
|
require_once("transactd.php");
|
23
23
|
use BizStation\Transactd as Bz;
|
24
|
-
|
25
|
-
define('URL', 'tdap://localhost/test_bench?dbfile=test.bdf');
|
26
24
|
define('TABLENAME', 'users');
|
27
25
|
define('FDI_ID', 0);
|
28
26
|
define('FDI_NAME', 1);
|
29
27
|
define('BULKBUFSIZE', 65535 - 1000);
|
30
|
-
|
31
28
|
define('RECORD_COUNT', 20000);
|
32
29
|
define('RECORD_UNIT', 20);
|
33
30
|
|
31
|
+
|
34
32
|
function assertEquals($a, $b, $msg = '') {
|
35
33
|
if ($a !== $b) {
|
36
34
|
echo("$a !== $b $msg");
|
@@ -46,19 +44,19 @@ function assertNotEquals($a, $b, $msg = '') {
|
|
46
44
|
return true;
|
47
45
|
}
|
48
46
|
|
49
|
-
function create($
|
47
|
+
function create($URI) {
|
50
48
|
// create database
|
51
49
|
$db = new Bz\database();
|
52
|
-
$db->create($
|
50
|
+
$db->create($URI);
|
53
51
|
if ($db->stat() == Bz\transactd::STATUS_TABLE_EXISTS_ERROR) {
|
54
|
-
$db->open($
|
52
|
+
$db->open($URI);
|
55
53
|
assertEquals($db->stat(), 0);
|
56
54
|
$db->drop();
|
57
55
|
assertEquals($db->stat(), 0);
|
58
|
-
$db->create($
|
56
|
+
$db->create($URI);
|
59
57
|
}
|
60
58
|
assertEquals($db->stat(), 0);
|
61
|
-
$db->open($
|
59
|
+
$db->open($URI, Bz\transactd::TYPE_SCHEMA_BDF, Bz\transactd::TD_OPEN_NORMAL);
|
62
60
|
assertEquals($db->stat(), 0);
|
63
61
|
// create table
|
64
62
|
$dbdef = $db->dbDef();
|
@@ -124,8 +122,8 @@ function deleteAll($db, $tb) {
|
|
124
122
|
|
125
123
|
function insert($db, $tb) {
|
126
124
|
$tb->setKeyNum(0);
|
125
|
+
$tb->clearBuffer();
|
127
126
|
for ($i = 1; $i <= RECORD_COUNT; $i++) {
|
128
|
-
$tb->clearBuffer();
|
129
127
|
$tb->setFV(FDI_ID, $i);
|
130
128
|
$tb->setFV(FDI_NAME, $i);
|
131
129
|
$tb->insert();
|
@@ -138,15 +136,15 @@ function insert($db, $tb) {
|
|
138
136
|
function insertTransaction($db, $tb) {
|
139
137
|
$tb->setKeyNum(0);
|
140
138
|
$start = 1;
|
139
|
+
$tb->clearBuffer();
|
141
140
|
while ($start < RECORD_COUNT) {
|
142
141
|
$db->beginTrn();
|
143
142
|
for ($i = $start; $i < $start + RECORD_UNIT; $i++) {
|
144
|
-
$tb->clearBuffer();
|
145
143
|
$tb->setFV(FDI_ID, $i);
|
146
144
|
$tb->setFV(FDI_NAME, $i);
|
147
145
|
$tb->insert();
|
148
146
|
if (!assertEquals($tb->stat(), 0, 'insertTransaction')) {
|
149
|
-
$db->
|
147
|
+
$db->abortTrn();
|
150
148
|
return false;
|
151
149
|
}
|
152
150
|
}
|
@@ -159,10 +157,10 @@ function insertTransaction($db, $tb) {
|
|
159
157
|
function insertBulk($db, $tb) {
|
160
158
|
$tb->setKeyNum(0);
|
161
159
|
$start = 1;
|
160
|
+
$tb->clearBuffer();
|
162
161
|
while ($start < RECORD_COUNT) {
|
163
162
|
$tb->beginBulkInsert(BULKBUFSIZE);
|
164
163
|
for ($i = $start; $i < $start + RECORD_UNIT; $i++) {
|
165
|
-
$tb->clearBuffer();
|
166
164
|
$tb->setFV(FDI_ID, $i);
|
167
165
|
$tb->setFV(FDI_NAME, $i);
|
168
166
|
$tb->insert();
|
@@ -179,12 +177,13 @@ function insertBulk($db, $tb) {
|
|
179
177
|
|
180
178
|
function read($db, $tb) {
|
181
179
|
$tb->setKeyNum(0);
|
180
|
+
$tb->clearBuffer();
|
182
181
|
for ($i = 1; $i <= RECORD_COUNT; $i++) {
|
183
|
-
$tb->clearBuffer();
|
184
182
|
$tb->setFV(FDI_ID, $i);
|
185
183
|
$tb->seek();
|
186
|
-
if (
|
187
|
-
|
184
|
+
if (($tb->stat() !==0) || ($tb->getFVint(FDI_ID) !== $i))
|
185
|
+
{
|
186
|
+
echo("seek stat = ".$tb->stat()." value ".$i." = ".$tb->getFVint(FDI_ID));
|
188
187
|
return false;
|
189
188
|
}
|
190
189
|
}
|
@@ -192,17 +191,17 @@ function read($db, $tb) {
|
|
192
191
|
}
|
193
192
|
|
194
193
|
function readSnapshot($db, $tb) {
|
195
|
-
$ret = true;
|
196
194
|
$tb->setKeyNum(0);
|
197
195
|
$db->beginSnapshot();
|
196
|
+
$tb->clearBuffer();
|
198
197
|
for ($i = 1; $i <= RECORD_COUNT; $i++) {
|
199
|
-
$tb->clearBuffer();
|
200
198
|
$tb->setFV(FDI_ID, $i);
|
201
199
|
$tb->seek();
|
202
|
-
if (
|
203
|
-
|
204
|
-
|
205
|
-
|
200
|
+
if (($tb->stat() !==0) || ($tb->getFVint(FDI_ID) !== $i))
|
201
|
+
{
|
202
|
+
echo("seek stat = ".$tb->stat()." value ".$i." = ".$tb->getFVint(FDI_ID));
|
203
|
+
$db->endSnapshot();
|
204
|
+
return false;
|
206
205
|
}
|
207
206
|
}
|
208
207
|
$db->endSnapshot();
|
@@ -210,16 +209,17 @@ function readSnapshot($db, $tb) {
|
|
210
209
|
}
|
211
210
|
|
212
211
|
function readRange($db, $tb) {
|
213
|
-
$tb->setKeyNum(0);
|
214
212
|
$start = 1;
|
213
|
+
$tb->setKeyNum(0);
|
214
|
+
$tb->clearBuffer();
|
215
|
+
$tb->setFilter('*', 1, RECORD_UNIT);
|
216
|
+
$tb->setFV(FDI_ID, $start);
|
217
|
+
$tb->find(Bz\table::findForword);
|
215
218
|
while ($start < RECORD_COUNT) {
|
216
|
-
$tb->clearBuffer();
|
217
|
-
$tb->setFilter('*', 1, RECORD_UNIT);
|
218
|
-
$tb->setFV(FDI_ID, $start);
|
219
|
-
$tb->find(Bz\table::findForword);
|
220
219
|
for ($i = $start; $i < $start + RECORD_UNIT; $i++) {
|
221
|
-
if (
|
222
|
-
|
220
|
+
if (/*($tb->stat() !==0) || */($tb->getFVint(FDI_ID) !== $i))
|
221
|
+
{
|
222
|
+
echo("find stat = ".$tb->stat()." value ".$i." = ".$tb->getFVint(FDI_ID));
|
223
223
|
return false;
|
224
224
|
}
|
225
225
|
$tb->findNext();
|
@@ -230,17 +230,19 @@ function readRange($db, $tb) {
|
|
230
230
|
}
|
231
231
|
|
232
232
|
function readRangeSnapshot($db, $tb) {
|
233
|
+
$start = 1;
|
233
234
|
$tb->setKeyNum(0);
|
235
|
+
$tb->clearBuffer();
|
236
|
+
$tb->setFilter('*', 1, RECORD_UNIT);
|
237
|
+
$tb->setFV(FDI_ID, $start);
|
234
238
|
$db->beginSnapshot();
|
235
|
-
$
|
239
|
+
$tb->find(Bz\table::findForword);
|
236
240
|
while ($start < RECORD_COUNT) {
|
237
|
-
$tb->clearBuffer();
|
238
|
-
$tb->setFilter('*', 1, RECORD_UNIT);
|
239
|
-
$tb->setFV(FDI_ID, $start);
|
240
|
-
$tb->find(Bz\table::findForword);
|
241
241
|
for ($i = $start; $i < $start + RECORD_UNIT; $i++) {
|
242
|
-
if (
|
243
|
-
|
242
|
+
if (/*($tb->stat() !==0) || */($tb->getFVint(FDI_ID) !== $i))
|
243
|
+
{
|
244
|
+
echo("find stat = ".$tb->stat()." value ".$i." = ".$tb->getFVint(FDI_ID));
|
245
|
+
$db->endSnapshot();
|
244
246
|
return false;
|
245
247
|
}
|
246
248
|
$tb->findNext();
|
@@ -253,13 +255,16 @@ function readRangeSnapshot($db, $tb) {
|
|
253
255
|
|
254
256
|
function update($db, $tb) {
|
255
257
|
$tb->setKeyNum(0);
|
258
|
+
$tb->clearBuffer();
|
256
259
|
for ($i = 1; $i <= RECORD_COUNT; $i++) {
|
257
|
-
$tb->clearBuffer();
|
258
260
|
$tb->setFV(FDI_ID, $i);
|
259
261
|
$tb->setFV(FDI_NAME, ($i + 1));
|
260
262
|
$tb->update(Bz\table::changeInKey);
|
261
|
-
if (
|
263
|
+
if ($tb->stat() !==0)
|
264
|
+
{
|
265
|
+
echo("update stat = ".$tb->stat());
|
262
266
|
return false;
|
267
|
+
}
|
263
268
|
}
|
264
269
|
return true;
|
265
270
|
}
|
@@ -267,15 +272,17 @@ function update($db, $tb) {
|
|
267
272
|
function updateTransaction($db, $tb) {
|
268
273
|
$tb->setKeyNum(0);
|
269
274
|
$start = 1;
|
275
|
+
$tb->clearBuffer();
|
270
276
|
while ($start < RECORD_COUNT) {
|
271
277
|
$db->beginTrn();
|
272
278
|
for ($i = $start; $i < $start + RECORD_UNIT; $i++) {
|
273
|
-
$tb->clearBuffer();
|
274
279
|
$tb->setFV(FDI_ID, $i);
|
275
280
|
$tb->setFV(FDI_NAME, ($i + 2));
|
276
281
|
$tb->update(Bz\table::changeInKey);
|
277
|
-
if (
|
278
|
-
|
282
|
+
if ($tb->stat() !==0)
|
283
|
+
{
|
284
|
+
echo("update stat = ".$tb->stat());
|
285
|
+
$db->abortTrn();
|
279
286
|
return false;
|
280
287
|
}
|
281
288
|
}
|
@@ -285,73 +292,91 @@ function updateTransaction($db, $tb) {
|
|
285
292
|
return true;
|
286
293
|
}
|
287
294
|
|
288
|
-
function main($
|
289
|
-
|
290
|
-
|
291
|
-
|
295
|
+
function main($argc, $argv) {
|
296
|
+
if ($argc < 4) {
|
297
|
+
echo("usage: php bench.php databaseUri processNumber functionNumber\n");
|
298
|
+
echo("\t --- functionNumber list ---\n");
|
299
|
+
echo("\t-1: all function\n");
|
300
|
+
echo("\t 0: Insert\n");
|
301
|
+
echo("\t 1: Insert in transaction. 20rec x 1000times\n");
|
302
|
+
echo("\t 2: Insert by bulkmode. 20rec x 1000times\n");
|
303
|
+
echo("\t 3: read each record\n");
|
304
|
+
echo("\t 4: read each record with snapshot\n");
|
305
|
+
echo("\t 5: read range. 20rec x 1000times\n");
|
306
|
+
echo("\t 6: read range with snapshpot. 20rec x 1000times\n");
|
307
|
+
echo("\t 7: update\n");
|
308
|
+
echo("\t 8: update in transaction. 20rec x 1000times\n");
|
309
|
+
echo("example : php bench.php \"tdap://localhost/test?dbfile=test.bdf\" 0 -1\n");
|
310
|
+
return;
|
311
|
+
}
|
312
|
+
|
313
|
+
$URI = $argv[1];
|
314
|
+
// Currenty $proc is ignored.
|
315
|
+
$proc = (int)$argv[2];
|
316
|
+
$funcNum = (int)$argv[3];
|
317
|
+
|
318
|
+
create($URI);
|
319
|
+
echo("CreateDataBase success.\n");
|
320
|
+
echo("Start Bench mark Insert Items = ".RECORD_COUNT."\n");
|
321
|
+
echo(date(DATE_ATOM)."\n");
|
322
|
+
echo($URI."\n");
|
323
|
+
echo("----------------------------------------\n");
|
292
324
|
|
293
325
|
$db = new Bz\database();
|
294
|
-
$db->open($
|
326
|
+
$db->open($URI, Bz\transactd::TYPE_SCHEMA_BDF, Bz\transactd::TD_OPEN_NORMAL);
|
295
327
|
assertEquals($db->stat(), 0);
|
296
328
|
$tb = $db->openTable(TABLENAME);
|
297
329
|
assertEquals($db->stat(), 0);
|
298
330
|
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
echo("--------------------------------\n");
|
307
|
-
|
308
|
-
deleteAll($db, $tb);
|
309
|
-
Bz\benchmark::start();
|
310
|
-
$ret = insertTransaction($db, $tb);
|
311
|
-
Bz\benchmark::showTimeSec($ret, ': insertTransaction ' . RECORD_COUNT . ' with transaction per ' . RECORD_UNIT);
|
312
|
-
|
313
|
-
echo("--------------------------------\n");
|
314
|
-
|
315
|
-
deleteAll($db, $tb);
|
316
|
-
Bz\benchmark::start();
|
317
|
-
$ret = insertBulk($db, $tb);
|
318
|
-
Bz\benchmark::showTimeSec($ret, ': insertBulk ' . RECORD_COUNT . ' with bulkmode per ' . RECORD_UNIT);
|
319
|
-
|
320
|
-
echo("--------------------------------\n");
|
321
|
-
|
322
|
-
Bz\benchmark::start();
|
323
|
-
$ret = read($db, $tb);
|
324
|
-
Bz\benchmark::showTimeSec($ret, ': read ' . RECORD_COUNT);
|
325
|
-
|
326
|
-
echo("--------------------------------\n");
|
327
|
-
|
328
|
-
Bz\benchmark::start();
|
329
|
-
$ret = readSnapshot($db, $tb);
|
330
|
-
Bz\benchmark::showTimeSec($ret, ': read with snapshot ' . RECORD_COUNT);
|
331
|
-
|
332
|
-
echo("--------------------------------\n");
|
333
|
-
|
334
|
-
Bz\benchmark::start();
|
335
|
-
$ret = readRange($db, $tb);
|
336
|
-
Bz\benchmark::showTimeSec($ret, ': read ' . RECORD_COUNT . ' with range per ' . RECORD_UNIT);
|
337
|
-
|
338
|
-
echo("--------------------------------\n");
|
339
|
-
|
340
|
-
Bz\benchmark::start();
|
341
|
-
$ret = readRangeSnapshot($db, $tb);
|
342
|
-
Bz\benchmark::showTimeSec($ret, ': read ' . RECORD_COUNT . ' with snapshot and range per ' . RECORD_UNIT);
|
343
|
-
|
344
|
-
echo("--------------------------------\n");
|
345
|
-
|
346
|
-
Bz\benchmark::start();
|
347
|
-
$ret = update($db, $tb);
|
348
|
-
Bz\benchmark::showTimeSec($ret, ': update ' . RECORD_COUNT);
|
331
|
+
if (($funcNum === -1) || ($funcNum === 0)) {
|
332
|
+
deleteAll($db, $tb);
|
333
|
+
Bz\benchmark::start();
|
334
|
+
$ret = insert($db, $tb);
|
335
|
+
Bz\benchmark::showTimeSec($ret, ': insert ' . RECORD_COUNT);
|
336
|
+
}
|
349
337
|
|
350
|
-
|
338
|
+
if (($funcNum === -1) || ($funcNum === 1)) {
|
339
|
+
deleteAll($db, $tb);
|
340
|
+
Bz\benchmark::start();
|
341
|
+
$ret = insertTransaction($db, $tb);
|
342
|
+
Bz\benchmark::showTimeSec($ret, ': insertTransaction ' . RECORD_COUNT . ' with transaction per ' . RECORD_UNIT);
|
343
|
+
}
|
351
344
|
|
352
|
-
|
353
|
-
|
354
|
-
|
345
|
+
if (($funcNum === -1) || ($funcNum === 2)) {
|
346
|
+
deleteAll($db, $tb);
|
347
|
+
Bz\benchmark::start();
|
348
|
+
$ret = insertBulk($db, $tb);
|
349
|
+
Bz\benchmark::showTimeSec($ret, ': insertBulk ' . RECORD_COUNT . ' with bulkmode per ' . RECORD_UNIT);
|
350
|
+
}
|
351
|
+
if (($funcNum === -1) || ($funcNum === 3)) {
|
352
|
+
Bz\benchmark::start();
|
353
|
+
$ret = read($db, $tb);
|
354
|
+
Bz\benchmark::showTimeSec($ret, ': read ' . RECORD_COUNT);
|
355
|
+
}
|
356
|
+
if (($funcNum === -1) || ($funcNum === 4)) {
|
357
|
+
Bz\benchmark::start();
|
358
|
+
$ret = readSnapshot($db, $tb);
|
359
|
+
Bz\benchmark::showTimeSec($ret, ': read with snapshot ' . RECORD_COUNT);
|
360
|
+
}
|
361
|
+
if (($funcNum === -1) || ($funcNum === 5)) {
|
362
|
+
Bz\benchmark::start();
|
363
|
+
$ret = readRange($db, $tb);
|
364
|
+
Bz\benchmark::showTimeSec($ret, ': read ' . RECORD_COUNT . ' with range per ' . RECORD_UNIT);
|
365
|
+
}
|
366
|
+
if (($funcNum === -1) || ($funcNum === 6)) {
|
367
|
+
Bz\benchmark::start();
|
368
|
+
$ret = readRangeSnapshot($db, $tb);
|
369
|
+
Bz\benchmark::showTimeSec($ret, ': read ' . RECORD_COUNT . ' with snapshot and range per ' . RECORD_UNIT);
|
370
|
+
}
|
371
|
+
if (($funcNum === -1) || ($funcNum === 7)) {
|
372
|
+
Bz\benchmark::start();
|
373
|
+
$ret = update($db, $tb);
|
374
|
+
Bz\benchmark::showTimeSec($ret, ': update ' . RECORD_COUNT);
|
375
|
+
}
|
376
|
+
if (($funcNum === -1) || ($funcNum === 8)) {
|
377
|
+
Bz\benchmark::start();
|
378
|
+
$ret = updateTransaction($db, $tb);
|
379
|
+
Bz\benchmark::showTimeSec($ret, ': updateTransaction ' . RECORD_COUNT . ' with transaction per ' . RECORD_UNIT);
|
380
|
+
}
|
355
381
|
}
|
356
|
-
|
357
|
-
main(URL);
|
382
|
+
main($argc, $argv);
|
@@ -44,9 +44,6 @@ define("TEST_COUNT", 20000);
|
|
44
44
|
define("FIVE_PERCENT_OF_TEST_COUNT", TEST_COUNT / 20);
|
45
45
|
define("ALLOWABLE_ERROR_DISTANCE_IN_ESTIMATE_COUNT", TEST_COUNT / 4);
|
46
46
|
|
47
|
-
define("ISOLATION_READ_COMMITTED", true);
|
48
|
-
define("ISOLATION_REPEATABLE_READ", false);
|
49
|
-
|
50
47
|
class transactdTest extends PHPUnit_Framework_TestCase
|
51
48
|
{
|
52
49
|
private function dropDatabase($db)
|
@@ -84,8 +81,7 @@ class transactdTest extends PHPUnit_Framework_TestCase
|
|
84
81
|
$td->setFileName(TABLENAME . '.dat');
|
85
82
|
// Set table default charaset index
|
86
83
|
// - default charset for field VALUE
|
87
|
-
|
88
|
-
//
|
84
|
+
$td->charsetIndex = Bz\transactd::charsetIndex(Bz\transactd::CP_UTF8);
|
89
85
|
$tableid = 1;
|
90
86
|
$td->id = $tableid;
|
91
87
|
$td->pageSize = 2048;
|
@@ -93,14 +89,14 @@ class transactdTest extends PHPUnit_Framework_TestCase
|
|
93
89
|
$this->assertEquals($dbdef->stat(), 0);
|
94
90
|
|
95
91
|
$fd = $dbdef->insertField($tableid, 0);
|
96
|
-
$fd->setName(
|
92
|
+
$fd->setName('id');
|
97
93
|
$fd->type = Bz\transactd::ft_integer;
|
98
94
|
$fd->len = 4;
|
99
95
|
$dbdef->updateTableDef($tableid);
|
100
96
|
$this->assertEquals($dbdef->stat(), 0);
|
101
97
|
|
102
98
|
$fd = $dbdef->insertField($tableid, 1);
|
103
|
-
$fd->setName(
|
99
|
+
$fd->setName('name');
|
104
100
|
$fd->type = Bz\transactd::ft_zstring;
|
105
101
|
$fd->len = 33;
|
106
102
|
$dbdef->updateTableDef($tableid);
|
@@ -110,24 +106,58 @@ class transactdTest extends PHPUnit_Framework_TestCase
|
|
110
106
|
// $fd->setCharsetIndex(Bz\transactd::charsetIndex(Bz\transactd::CP_UTF8))
|
111
107
|
|
112
108
|
$fd = $dbdef->insertField($tableid, 2);
|
113
|
-
$fd->setName(
|
109
|
+
$fd->setName('select');
|
114
110
|
$fd->type = Bz\transactd::ft_integer;
|
115
111
|
$fd->len = 4;
|
116
112
|
$dbdef->updateTableDef($tableid);
|
117
113
|
$this->assertEquals($dbdef->stat(), 0);
|
118
114
|
|
119
115
|
$fd = $dbdef->insertField($tableid, 3);
|
120
|
-
$fd->setName(
|
116
|
+
$fd->setName('in');
|
117
|
+
$fd->type = Bz\transactd::ft_integer;
|
118
|
+
$fd->len = 4;
|
119
|
+
$dbdef->updateTableDef($tableid);
|
120
|
+
$this->assertEquals($dbdef->stat(), 0);
|
121
|
+
|
122
|
+
$kd = $dbdef->insertKey($tableid, 0);
|
123
|
+
$kd->segment(0)->fieldNum = 0;
|
124
|
+
$kd->segment(0)->flags->bit8 = 1;
|
125
|
+
$kd->segment(0)->flags->bit1 = 1;
|
126
|
+
$kd->segmentCount = 1;
|
127
|
+
$dbdef->updateTableDef($tableid);
|
128
|
+
$this->assertEquals($dbdef->stat(), 0);
|
129
|
+
|
130
|
+
// group table
|
131
|
+
$td = new Bz\tabledef();
|
132
|
+
$td->schemaCodePage = Bz\transactd::CP_UTF8;
|
133
|
+
$td->setTableName('group');
|
134
|
+
$td->setFileName('group.dat');
|
135
|
+
$tableid = 2;
|
136
|
+
$td->id = $tableid;
|
137
|
+
$td->pageSize = 2048;
|
138
|
+
$dbdef->insertTable($td);
|
139
|
+
$this->assertEquals($dbdef->stat(), 0);
|
140
|
+
|
141
|
+
$fd = $dbdef->insertField($tableid, 0);
|
142
|
+
$fd->setName('id');
|
121
143
|
$fd->type = Bz\transactd::ft_integer;
|
122
144
|
$fd->len = 4;
|
123
145
|
$dbdef->updateTableDef($tableid);
|
124
146
|
$this->assertEquals($dbdef->stat(), 0);
|
125
147
|
|
148
|
+
$fd = $dbdef->insertField($tableid, 1);
|
149
|
+
$fd->setName('name');
|
150
|
+
$fd->type = Bz\transactd::ft_zstring;
|
151
|
+
$fd->len = 33;
|
152
|
+
$dbdef->updateTableDef($tableid);
|
153
|
+
$this->assertEquals($dbdef->stat(), 0);
|
154
|
+
|
126
155
|
$kd = $dbdef->insertKey($tableid, 0);
|
127
156
|
$kd->segment(0)->fieldNum = 0;
|
128
157
|
$kd->segment(0)->flags->bit8 = 1;
|
129
158
|
$kd->segment(0)->flags->bit1 = 1;
|
130
159
|
$kd->segmentCount = 1;
|
160
|
+
|
131
161
|
$dbdef->updateTableDef($tableid);
|
132
162
|
$this->assertEquals($dbdef->stat(), 0);
|
133
163
|
}
|
@@ -285,6 +315,8 @@ class transactdTest extends PHPUnit_Framework_TestCase
|
|
285
315
|
while ($i < TEST_COUNT)
|
286
316
|
{
|
287
317
|
$this->assertEquals($tb->stat(), 0);
|
318
|
+
if ($tb->stat() != 0)
|
319
|
+
break;
|
288
320
|
$this->assertEquals($tb->getFVint(FDI_ID), $i);
|
289
321
|
$tb->findNext(true); // 11 - 19
|
290
322
|
$i = $i + 1;
|
@@ -298,6 +330,8 @@ class transactdTest extends PHPUnit_Framework_TestCase
|
|
298
330
|
while ($i >= 10)
|
299
331
|
{
|
300
332
|
$this->assertEquals($tb->stat(), 0);
|
333
|
+
if ($tb->stat() != 0)
|
334
|
+
break;
|
301
335
|
$this->assertEquals($tb->getFVint(FDI_ID), $i);
|
302
336
|
$tb->findPrev(true); // 11 - 19
|
303
337
|
$i = $i - 1;
|
@@ -324,6 +358,8 @@ class transactdTest extends PHPUnit_Framework_TestCase
|
|
324
358
|
for ($i = $v + 1; $i <= (TEST_COUNT - 1); $i++)
|
325
359
|
{
|
326
360
|
$tb->findNext(true); // 11 - 19
|
361
|
+
if ($tb->stat() != 0)
|
362
|
+
break;
|
327
363
|
$this->assertEquals($tb->stat(), 0);
|
328
364
|
$this->assertEquals($tb->getFVint(FDI_ID), $i);
|
329
365
|
}
|
@@ -370,10 +406,9 @@ class transactdTest extends PHPUnit_Framework_TestCase
|
|
370
406
|
$this->assertEquals($tb->stat(), Bz\transactd::STATUS_EOF);
|
371
407
|
|
372
408
|
// Many params
|
373
|
-
$
|
374
|
-
for($i = 2; $i <= 10000; $i++)
|
409
|
+
for($i = 1; $i <= 10000; $i++)
|
375
410
|
{
|
376
|
-
$q->addSeekKeyValue(strval($i));
|
411
|
+
$q->addSeekKeyValue(strval($i), ($i == 1)); // reset
|
377
412
|
}
|
378
413
|
$tb->setQuery($q);
|
379
414
|
$this->assertEquals($tb->stat(), 0);
|
@@ -459,6 +494,8 @@ class transactdTest extends PHPUnit_Framework_TestCase
|
|
459
494
|
{
|
460
495
|
$tb->seekNext();
|
461
496
|
$this->assertEquals($tb->getFVint(FDI_ID), $i);
|
497
|
+
if ($i != $tb->getFVint(FDI_ID))
|
498
|
+
break;
|
462
499
|
}
|
463
500
|
$db->endSnapshot();
|
464
501
|
}
|
@@ -477,10 +514,27 @@ class transactdTest extends PHPUnit_Framework_TestCase
|
|
477
514
|
{
|
478
515
|
$tb->seekPrev();
|
479
516
|
$this->assertEquals($tb->getFVint(FDI_ID), $i);
|
517
|
+
if ($i != $tb->getFVint(FDI_ID))
|
518
|
+
break;
|
480
519
|
}
|
481
520
|
$tb->seekPrev();
|
482
521
|
$this->assertEquals($tb->getFVstr(FDI_NAME), 'kosaka');
|
483
522
|
$db->endSnapshot();
|
523
|
+
// without snapshot
|
524
|
+
$vv = TEST_COUNT + 1;
|
525
|
+
$tb->clearBuffer();
|
526
|
+
$tb->setFV(FDI_ID, $vv);
|
527
|
+
$tb->seek();
|
528
|
+
$this->assertEquals($tb->getFVint(FDI_ID), $vv);
|
529
|
+
for ($i = TEST_COUNT; $i > 1; $i--)
|
530
|
+
{
|
531
|
+
$tb->seekPrev();
|
532
|
+
$this->assertEquals($tb->getFVint(FDI_ID), $i);
|
533
|
+
if ($i != $tb->getFVint(FDI_ID))
|
534
|
+
break;
|
535
|
+
}
|
536
|
+
$tb->seekPrev();
|
537
|
+
$this->assertEquals($tb->getFVstr(FDI_NAME), 'kosaka');
|
484
538
|
}
|
485
539
|
public function testGetGreater()
|
486
540
|
{
|
@@ -627,53 +681,117 @@ class transactdTest extends PHPUnit_Framework_TestCase
|
|
627
681
|
$tb->seek();
|
628
682
|
$this->assertEquals($tb->getFVstr(FDI_NAME), 'ABC');
|
629
683
|
}
|
630
|
-
public function
|
684
|
+
public function testSnapshot()
|
631
685
|
{
|
632
686
|
$db = new Bz\database();
|
633
|
-
$db2 = new Bz\database();
|
634
|
-
$db2->connect(PROTOCOL . HOSTNAME . DBNAME, true);
|
635
|
-
$this->assertEquals($db2->stat(), 0);
|
636
687
|
$tb = $this->openTable($db);
|
637
688
|
$this->assertNotEquals($tb, NULL);
|
689
|
+
$tbg = $db->openTable('group');
|
690
|
+
$this->assertEquals($db->stat(), 0);
|
691
|
+
$this->assertNotEquals($tbg, NULL);
|
692
|
+
$db2 = new Bz\database();
|
693
|
+
$this->assertEquals($db2->stat(), 0);
|
694
|
+
$db2->connect(PROTOCOL . HOSTNAME . DBNAME, true);
|
638
695
|
$tb2 = $this->openTable($db2);
|
639
696
|
$this->assertNotEquals($tb2, NULL);
|
640
|
-
$
|
697
|
+
$tbg2 = $db2->openTable('group');
|
698
|
+
$this->assertEquals($db2->stat(), 0);
|
699
|
+
$this->assertNotEquals($tbg2, NULL);
|
700
|
+
|
701
|
+
// No locking repeatable read
|
702
|
+
// ----------------------------------------------------
|
703
|
+
$db->beginSnapshot(); // CONSISTENT_READ is default
|
641
704
|
$this->assertEquals($db->stat(), 0);
|
705
|
+
$db->beginTrn();
|
706
|
+
$this->assertEquals($db->stat(), Bz\transactd::STATUS_ALREADY_INSNAPSHOT);
|
707
|
+
|
642
708
|
$tb->setKeyNum(0);
|
643
709
|
$tb->seekFirst();
|
644
710
|
$this->assertEquals($tb->stat(), 0);
|
645
711
|
$firstValue = $tb->getFVstr(FDI_NAME);
|
646
712
|
$tb->seekNext();
|
647
|
-
|
648
|
-
|
713
|
+
$this->assertEquals($tb->stat(), 0);
|
714
|
+
$this->assertEquals($tb->getFVint(FDI_ID), 2);
|
715
|
+
$tbg->seekFirst();
|
716
|
+
$this->assertEquals($tbg->stat(), Bz\transactd::STATUS_EOF);
|
717
|
+
$this->assertEquals($tbg->recordCount(false), 0);
|
718
|
+
|
719
|
+
// Change data on 2 tables by another connection
|
649
720
|
$tb2->setKeyNum(0);
|
650
721
|
$tb2->seekFirst();
|
651
722
|
$this->assertEquals($tb2->stat(), 0);
|
652
723
|
$tb2->setFV(FDI_NAME, $tb2->getFVint(FDI_ID) + 1);
|
653
|
-
$tb2->update();
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
724
|
+
$tb2->update(); //Change success
|
725
|
+
$this->assertEquals($tb2->stat(), 0);
|
726
|
+
$tbg2->setFV(FDI_ID, 1);
|
727
|
+
$tbg2->setFV(FDI_NAME, 'ABC');
|
728
|
+
$tbg2->insert();
|
729
|
+
$this->assertEquals($tbg2->stat(), 0);
|
730
|
+
|
731
|
+
// in-snapshot repeatable read check same value
|
659
732
|
$tb->seekFirst();
|
660
733
|
$secondValue = $tb->getFVstr(FDI_NAME);
|
661
734
|
$this->assertEquals($tb->stat(), 0);
|
735
|
+
$this->assertEquals($secondValue, $firstValue, "$firstValue != $secondValue");
|
736
|
+
|
737
|
+
$tbg->seekFirst();
|
738
|
+
$this->assertEquals($tbg->stat(), Bz\transactd::STATUS_EOF);
|
739
|
+
$this->assertEquals($tbg->recordCount(false), 0);
|
740
|
+
|
741
|
+
// in-snapshot update
|
742
|
+
$tb->update();
|
743
|
+
$this->assertEquals($tb->stat(), Bz\transactd::STATUS_INVALID_LOCKTYPE);
|
744
|
+
|
745
|
+
// in-snapshot insert
|
746
|
+
$tb->setFV(FDI_ID, 0);
|
747
|
+
$tb->insert();
|
748
|
+
$this->assertEquals($tb->stat(), Bz\transactd::STATUS_INVALID_LOCKTYPE);
|
749
|
+
|
750
|
+
// phantom read
|
751
|
+
$tb2->setFV(FDI_ID, 29999);
|
752
|
+
$tb2->insert();
|
753
|
+
$this->assertEquals($tb2->stat(), 0);
|
754
|
+
$tb->setFV(FDI_ID, 29999);
|
755
|
+
$tb->seek();
|
756
|
+
$this->assertEquals($tb->stat(), Bz\transactd::STATUS_NOT_FOUND_TI);
|
757
|
+
|
758
|
+
// clean up
|
759
|
+
$tb2->del();
|
760
|
+
$this->assertEquals($tb2->stat(), 0);
|
761
|
+
|
662
762
|
$db->endSnapshot();
|
763
|
+
$this->assertEquals($db->stat(), 0);
|
764
|
+
|
765
|
+
// After snapshot, db can read new versions.
|
766
|
+
$tb->seekFirst();
|
663
767
|
$this->assertEquals($tb->stat(), 0);
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
768
|
+
$this->assertEquals($tb->getFVint(FDI_ID), 1);
|
769
|
+
$tbg->seekFirst();
|
770
|
+
$this->assertEquals($tbg->stat(), 0);
|
771
|
+
$this->assertEquals($tbg->recordCount(false), 1);
|
772
|
+
|
773
|
+
// gap lock
|
774
|
+
$db->beginSnapshot(Bz\transactd::MULTILOCK_GAP_SHARE);
|
775
|
+
$tb->seekLast(); // id = 30000
|
776
|
+
$this->assertEquals($tb->stat(), 0);
|
777
|
+
$tb->seekPrev(); // id = 20002
|
778
|
+
$this->assertEquals($tb->stat(), 0);
|
779
|
+
$tb->seekPrev(); // id = 20001
|
780
|
+
$this->assertEquals($tb->stat(), 0);
|
781
|
+
|
782
|
+
$tb2->setFV(FDI_ID, 29999);
|
783
|
+
$tb2->insert();
|
784
|
+
$this->assertEquals($tb2->stat(), Bz\transactd::STATUS_LOCK_ERROR);
|
785
|
+
|
786
|
+
$db->endSnapshot();
|
669
787
|
}
|
670
788
|
public function testConflict()
|
671
789
|
{
|
672
790
|
$db = new Bz\database();
|
791
|
+
$tb = $this->openTable($db);
|
673
792
|
$db2 = new Bz\database();
|
674
793
|
$db2->connect(PROTOCOL . HOSTNAME . DBNAME, true);
|
675
794
|
$this->assertEquals($db2->stat(), 0);
|
676
|
-
$tb = $this->openTable($db);
|
677
795
|
$this->assertNotEquals($tb, NULL);
|
678
796
|
$tb2 = $this->openTable($db2);
|
679
797
|
$this->assertNotEquals($tb2, NULL);
|
@@ -717,93 +835,584 @@ class transactdTest extends PHPUnit_Framework_TestCase
|
|
717
835
|
unset($db2);
|
718
836
|
unset($db);
|
719
837
|
}
|
720
|
-
|
838
|
+
// isoration Level ISO_REPEATABLE_READ
|
839
|
+
public function testTransactionLockRepeatable()
|
721
840
|
{
|
722
841
|
$db = new Bz\database();
|
842
|
+
$tb = $this->openTable($db);
|
843
|
+
$this->assertNotEquals($tb, NULL);
|
723
844
|
$db2 = new Bz\database();
|
724
845
|
$db2->connect(PROTOCOL . HOSTNAME . DBNAME, true);
|
725
846
|
$this->assertEquals($db2->stat(), 0);
|
726
|
-
$tb = $this->openTable($db);
|
727
|
-
$this->assertNotEquals($tb, NULL);
|
728
847
|
$tb2 = $this->openTable($db2);
|
729
848
|
$this->assertNotEquals($tb2, NULL);
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
$
|
849
|
+
|
850
|
+
$db->beginTrn(Bz\transactd::MULTILOCK_REPEATABLE_READ);
|
851
|
+
$this->assertEquals($db->stat(), 0);
|
852
|
+
// Test Invalid operation
|
853
|
+
$db->beginSnapshot();
|
854
|
+
$this->assertEquals($db->stat(), Bz\transactd::STATUS_ALREADY_INTRANSACTION);
|
855
|
+
|
856
|
+
// ------------------------------------------------------
|
857
|
+
// Test Read with lock
|
858
|
+
// ------------------------------------------------------
|
859
|
+
// lock(X) the first record
|
735
860
|
$tb->seekFirst();
|
736
861
|
$this->assertEquals($tb->stat(), 0);
|
737
|
-
|
862
|
+
|
863
|
+
// Add lock(X) the second record
|
738
864
|
$tb->seekNext();
|
865
|
+
|
866
|
+
// No transaction user can read allways. Use consistent_read
|
739
867
|
$tb2->seekFirst();
|
740
868
|
$this->assertEquals($tb2->stat(), 0);
|
869
|
+
|
870
|
+
$tb2->seekNext();
|
871
|
+
$this->assertEquals($tb2->stat(), 0);
|
872
|
+
|
873
|
+
// The second transaction user can not lock same record.
|
741
874
|
$db2->beginTrn();
|
742
875
|
$tb2->setKeyNum(0);
|
876
|
+
|
877
|
+
// Try lock(X)
|
878
|
+
$tb2->seekFirst();
|
879
|
+
$this->assertEquals($tb2->stat(), Bz\transactd::STATUS_LOCK_ERROR);
|
880
|
+
$db2->endTrn();
|
881
|
+
$db->endTrn();
|
882
|
+
|
883
|
+
// ------------------------------------------------------
|
884
|
+
// Test single record lock and Transaction lock
|
885
|
+
// ------------------------------------------------------
|
886
|
+
// lock(X) non-transaction
|
887
|
+
$tb2->seekFirst(Bz\transactd::ROW_LOCK_X);
|
888
|
+
|
889
|
+
$db->beginTrn(Bz\transactd::MULTILOCK_REPEATABLE_READ);
|
890
|
+
$this->assertEquals($db->stat(), 0);
|
891
|
+
|
892
|
+
// Try lock(X)
|
893
|
+
$tb->seekFirst();
|
894
|
+
$this->assertEquals($tb->stat(), Bz\transactd::STATUS_LOCK_ERROR);
|
895
|
+
|
896
|
+
// Remove lock(X)
|
897
|
+
$tb2->seekFirst();
|
898
|
+
|
899
|
+
// Retry lock(X)
|
900
|
+
$tb->seekFirst();
|
901
|
+
$this->assertEquals($tb->stat(), 0);
|
902
|
+
|
903
|
+
$tb->setFV(FDI_NAME, 'ABC');
|
904
|
+
$tb->update();
|
905
|
+
$this->assertEquals($tb->stat(), 0);
|
906
|
+
|
907
|
+
// No transaction user can read allways. Use consistent_read
|
743
908
|
$tb2->seekFirst();
|
744
909
|
$this->assertEquals($tb2->stat(), 0);
|
910
|
+
$this->assertNotEquals($tb2->getFVstr(FDI_NAME), 'ABC');
|
911
|
+
|
912
|
+
// ------------------------------------------------------
|
913
|
+
// Test Transaction lock and Transaction lock
|
914
|
+
// ------------------------------------------------------
|
915
|
+
$db2->beginTrn();
|
916
|
+
$this->assertEquals($db2->stat(), 0);
|
917
|
+
|
918
|
+
// try lock(X)
|
919
|
+
$tb2->seekFirst();
|
920
|
+
$this->assertEquals($tb2->stat(), Bz\transactd::STATUS_LOCK_ERROR);
|
921
|
+
|
922
|
+
// Try unlock updated record. Can not unlock updated record.
|
923
|
+
$tb->unlock();
|
924
|
+
|
925
|
+
// try lock(X)
|
926
|
+
$tb2->seekFirst();
|
927
|
+
$this->assertEquals($tb2->stat(), Bz\transactd::STATUS_LOCK_ERROR);
|
928
|
+
|
745
929
|
$db2->endTrn();
|
746
930
|
$db->endTrn();
|
931
|
+
|
747
932
|
// ----------------------------------------------------
|
748
|
-
//
|
933
|
+
// Test phantom read
|
749
934
|
// ----------------------------------------------------
|
750
|
-
$db->beginTrn(Bz\transactd::
|
751
|
-
$
|
935
|
+
$db->beginTrn(Bz\transactd::MULTILOCK_REPEATABLE_READ);
|
936
|
+
$this->assertEquals($db->stat(), 0);
|
937
|
+
|
938
|
+
// read last row
|
939
|
+
$tb->seekLast(); // lock(X) last id = 30000
|
940
|
+
$this->assertEquals($tb->stat(), 0);
|
941
|
+
$tb->seekPrev(); // Add lock(X)
|
942
|
+
$this->assertEquals($tb->stat(), 0);
|
943
|
+
$last2 = $tb->getFVint(FDI_ID);
|
944
|
+
|
945
|
+
// insert test row
|
946
|
+
$tb2->setFV(FDI_ID, 29999);
|
947
|
+
$tb2->insert(); // Can not insert by gap lock
|
948
|
+
$this->assertEquals($tb2->stat(), Bz\transactd::STATUS_LOCK_ERROR);
|
949
|
+
|
950
|
+
$tb->seekLast();
|
951
|
+
$this->assertEquals($tb->stat(), 0);
|
952
|
+
$tb->seekPrev();
|
953
|
+
$this->assertEquals($tb->stat(), 0);
|
954
|
+
$this->assertEquals($tb->getFVint(FDI_ID), $last2);
|
955
|
+
$db->endTrn();
|
956
|
+
|
957
|
+
// ----------------------------------------------------
|
958
|
+
// Test Abort
|
959
|
+
// ----------------------------------------------------
|
960
|
+
$db->beginTrn(Bz\transactd::MULTILOCK_REPEATABLE_READ);
|
961
|
+
$this->assertEquals($db->stat(), 0);
|
962
|
+
|
963
|
+
// lock(X)
|
752
964
|
$tb->seekFirst();
|
753
965
|
$this->assertEquals($tb->stat(), 0);
|
966
|
+
$tb->setFV(FDI_NAME, 'EFG');
|
967
|
+
$tb->update();
|
968
|
+
$this->assertEquals($tb->stat(), 0);
|
969
|
+
|
754
970
|
// move from first record.
|
755
971
|
$tb->seekNext();
|
756
|
-
|
972
|
+
$db->abortTrn();
|
973
|
+
|
974
|
+
$tb2->setKeyNum(0);
|
975
|
+
$tb2->seekFirst();
|
976
|
+
$this->assertEquals($tb2->getFVstr(FDI_NAME), 'ABC');
|
977
|
+
|
978
|
+
// ----------------------------------------------------
|
979
|
+
// Test Query and locks Multi record lock
|
980
|
+
// ----------------------------------------------------
|
981
|
+
$db->beginTrn(Bz\transactd::MULTILOCK_REPEATABLE_READ);
|
982
|
+
$this->assertEquals($db->stat(), 0);
|
983
|
+
|
984
|
+
// Test find records are lock.
|
985
|
+
$q = new Bz\query();
|
986
|
+
$q->where('id', '<=', 15)->and_('id', '<>', 13)->reject(0xFFFF);
|
987
|
+
$tb->setQuery($q);
|
988
|
+
$tb->setFV(FDI_ID, 12);
|
989
|
+
$tb->find();
|
990
|
+
while ($tb->stat() == 0)
|
991
|
+
$tb->findNext();
|
992
|
+
$this->assertEquals($tb->getFVint(FDI_ID), 15);
|
993
|
+
|
994
|
+
// all records locked
|
995
|
+
for ($i = 12; $i <= 16; $i++)
|
996
|
+
{
|
997
|
+
$tb2->setFV(FDI_ID, $i);
|
998
|
+
$tb2->seek(Bz\transactd::ROW_LOCK_X);
|
999
|
+
$this->assertEquals($tb2->stat(), Bz\transactd::STATUS_LOCK_ERROR);
|
1000
|
+
}
|
1001
|
+
$db->endTrn();
|
1002
|
+
}
|
1003
|
+
public function testTransactionLockReadCommited()
|
1004
|
+
{
|
1005
|
+
$db = new Bz\database();
|
1006
|
+
$tb = $this->openTable($db);
|
1007
|
+
$this->assertNotEquals($tb, NULL);
|
1008
|
+
$db2 = new Bz\database();
|
1009
|
+
$db2->connect(PROTOCOL . HOSTNAME . DBNAME, true);
|
1010
|
+
$this->assertEquals($db2->stat(), 0);
|
1011
|
+
$tb2 = $this->openTable($db2);
|
1012
|
+
$this->assertNotEquals($tb2, NULL);
|
1013
|
+
|
1014
|
+
// ------------------------------------------------------
|
1015
|
+
// Test single record lock Transaction and read
|
1016
|
+
// ------------------------------------------------------
|
1017
|
+
$db->beginTrn(Bz\transactd::SINGLELOCK_READ_COMMITED);
|
1018
|
+
$this->assertEquals($db->stat(), 0);
|
1019
|
+
// Test Invalid operation
|
1020
|
+
$db->beginSnapshot();
|
1021
|
+
$this->assertEquals($db->stat(), Bz\transactd::STATUS_ALREADY_INTRANSACTION);
|
1022
|
+
|
1023
|
+
$tb->setKeyNum(0);
|
1024
|
+
$tb->seekFirst(); // lock(X)
|
1025
|
+
$this->assertEquals($tb->stat(), 0);
|
1026
|
+
|
1027
|
+
// Try lock(X)
|
1028
|
+
$tb2->seekFirst(Bz\transactd::ROW_LOCK_X);
|
1029
|
+
$this->assertEquals($tb2->stat(), Bz\transactd::STATUS_LOCK_ERROR);
|
1030
|
+
|
1031
|
+
// consistent read
|
1032
|
+
$tb2->seekFirst();
|
1033
|
+
$this->assertEquals($tb2->stat(), 0);
|
1034
|
+
|
1035
|
+
// Unlock first record. And lock(X) second record
|
1036
|
+
$tb->seekNext();
|
1037
|
+
|
1038
|
+
// test unlocked first record
|
757
1039
|
$tb2->seekFirst();
|
1040
|
+
$this->assertEquals($tb2->stat(), 0);
|
1041
|
+
$tb2->update();
|
1042
|
+
$this->assertEquals($tb2->stat(), 0);
|
1043
|
+
|
1044
|
+
// The second record, consistent read
|
1045
|
+
$tb2->seekNext();
|
1046
|
+
$this->assertEquals($tb2->stat(), 0);
|
1047
|
+
// Try lock(X) whith lock(IX)
|
1048
|
+
$tb2->update();
|
758
1049
|
$this->assertEquals($tb2->stat(), Bz\transactd::STATUS_LOCK_ERROR);
|
759
|
-
|
1050
|
+
|
1051
|
+
// ------------------------------------------------------
|
1052
|
+
// Test single record lock Transaction and Transaction lock
|
1053
|
+
// ------------------------------------------------------
|
760
1054
|
$db2->beginTrn();
|
761
|
-
|
1055
|
+
// Try lock(X)
|
762
1056
|
$tb2->seekFirst();
|
1057
|
+
$this->assertEquals($tb2->stat(), 0);
|
1058
|
+
// Try lock(X)
|
1059
|
+
$tb2->seekNext();
|
763
1060
|
$this->assertEquals($tb2->stat(), Bz\transactd::STATUS_LOCK_ERROR);
|
764
1061
|
$db2->endTrn();
|
765
1062
|
$db->endTrn();
|
766
|
-
|
767
|
-
//
|
768
|
-
//
|
769
|
-
|
770
|
-
$
|
1063
|
+
|
1064
|
+
// ------------------------------------------------------
|
1065
|
+
// Test multi record lock Transaction and non-transaction read
|
1066
|
+
// ------------------------------------------------------
|
1067
|
+
$db->beginTrn(Bz\transactd::MULTILOCK_READ_COMMITED);
|
1068
|
+
$this->assertEquals($db->stat(), 0);
|
1069
|
+
|
1070
|
+
// lock(X) the first record
|
1071
|
+
$tb->seekFirst();
|
1072
|
+
$this->assertEquals($tb->stat(), 0);
|
1073
|
+
|
1074
|
+
// Add lock(X) the second record
|
1075
|
+
$tb->seekNext();
|
1076
|
+
|
1077
|
+
// No transaction user read can read allways. Use consistent_read
|
1078
|
+
$tb2->seekFirst();
|
1079
|
+
$this->assertEquals($tb2->stat(), 0);
|
1080
|
+
|
1081
|
+
$tb2->seekNext();
|
1082
|
+
$this->assertEquals($tb2->stat(), 0);
|
1083
|
+
|
1084
|
+
// ------------------------------------------------------
|
1085
|
+
// Test unlock
|
1086
|
+
// ------------------------------------------------------
|
1087
|
+
$tb2->seekFirst();
|
1088
|
+
$tb2->seekNext(Bz\transactd::ROW_LOCK_X);
|
1089
|
+
$this->assertEquals($tb2->stat(), Bz\transactd::STATUS_LOCK_ERROR);
|
1090
|
+
|
1091
|
+
$tb->unlock();
|
1092
|
+
// retry seekNext. Before operation is failed but do not lost currency.
|
1093
|
+
$tb2->seekNext(Bz\transactd::ROW_LOCK_X);
|
1094
|
+
$this->assertEquals($tb2->stat(), 0);
|
1095
|
+
$tb2->seekNext();
|
1096
|
+
// ------------------------------------------------------
|
1097
|
+
// Test undate record unlock
|
1098
|
+
// ------------------------------------------------------
|
1099
|
+
$tb->seekFirst();
|
1100
|
+
$this->assertEquals($tb->stat(), 0);
|
1101
|
+
$tb->seekNext();
|
1102
|
+
$this->assertEquals($tb->stat(), 0);
|
1103
|
+
$tb->update();
|
1104
|
+
$this->assertEquals($tb->stat(), 0);
|
1105
|
+
$tb->unlock(); // Can not unlock updated record
|
1106
|
+
$this->assertEquals($tb->stat(), 0);
|
1107
|
+
$tb2->seekFirst();
|
1108
|
+
$tb2->seekNext(Bz\transactd::ROW_LOCK_X);
|
1109
|
+
$this->assertEquals($tb2->stat(), Bz\transactd::STATUS_LOCK_ERROR);
|
1110
|
+
|
1111
|
+
// ------------------------------------------------------
|
1112
|
+
// Test multi record lock Transaction and Transaction
|
1113
|
+
// ------------------------------------------------------
|
1114
|
+
$db2->beginTrn();
|
1115
|
+
$this->assertEquals($db2->stat(), 0);
|
1116
|
+
|
1117
|
+
// Try lock(X)
|
1118
|
+
$tb2->seekFirst();
|
1119
|
+
$this->assertEquals($tb2->stat(), Bz\transactd::STATUS_LOCK_ERROR);
|
1120
|
+
$db2->endTrn();
|
1121
|
+
$db->endTrn();
|
1122
|
+
|
1123
|
+
// ------------------------------------------------------
|
1124
|
+
// Test multi record lock Transaction and non-transaction record lock
|
1125
|
+
// ------------------------------------------------------
|
1126
|
+
// lock(X) non-transaction
|
1127
|
+
$tb2->seekFirst(Bz\transactd::ROW_LOCK_X);
|
1128
|
+
|
1129
|
+
$db->beginTrn(Bz\transactd::SINGLELOCK_READ_COMMITED);
|
1130
|
+
$this->assertEquals($db->stat(), 0);
|
1131
|
+
|
1132
|
+
// Try lock(X)
|
1133
|
+
$tb->seekFirst();
|
1134
|
+
$this->assertEquals($tb->stat(), Bz\transactd::STATUS_LOCK_ERROR);
|
1135
|
+
|
1136
|
+
// Remove lock(X)
|
1137
|
+
$tb2->seekFirst();
|
1138
|
+
|
1139
|
+
// Retry lock(X)
|
771
1140
|
$tb->seekFirst();
|
772
1141
|
$this->assertEquals($tb->stat(), 0);
|
1142
|
+
|
1143
|
+
// update in transaction
|
773
1144
|
$tb->setFV(FDI_NAME, 'ABC');
|
774
1145
|
$tb->update();
|
775
1146
|
$this->assertEquals($tb->stat(), 0);
|
776
|
-
|
777
|
-
|
778
|
-
$
|
779
|
-
|
1147
|
+
|
1148
|
+
// move from first record.
|
1149
|
+
$tb->seekNext();
|
1150
|
+
|
1151
|
+
// No transaction read can read allways. Use consistent_read
|
1152
|
+
$tb2->seekFirst();
|
1153
|
+
$this->assertEquals($tb2->stat(), 0);
|
1154
|
+
$tb2->update();
|
1155
|
+
$this->assertEquals($tb2->stat(), Bz\transactd::STATUS_LOCK_ERROR);
|
1156
|
+
|
1157
|
+
$db->endTrn();
|
1158
|
+
// ------------------------------------------------------
|
1159
|
+
// Test phantom read
|
1160
|
+
// ------------------------------------------------------
|
1161
|
+
$db->beginTrn(Bz\transactd::MULTILOCK_READ_COMMITED);
|
1162
|
+
$this->assertEquals($db->stat(), 0);
|
1163
|
+
|
1164
|
+
// read last row
|
1165
|
+
$tb->seekLast(); // lock(X) last id = 30000
|
1166
|
+
$this->assertEquals($tb->stat(), 0);
|
1167
|
+
$tb->seekPrev(); // Add lock(X)
|
1168
|
+
$this->assertEquals($tb->stat(), 0);
|
1169
|
+
$last2 = $tb->getFVint(FDI_ID);
|
1170
|
+
|
1171
|
+
//insert test row
|
1172
|
+
$tb2->setFV(FDI_ID, 29999);
|
1173
|
+
$tb2->insert();
|
1174
|
+
$this->assertEquals($tb2->stat(), 0);
|
1175
|
+
|
1176
|
+
$tb->seekLast();
|
1177
|
+
$this->assertEquals($tb->stat(), 0);
|
1178
|
+
$tb->seekPrev();
|
1179
|
+
$this->assertEquals($tb->stat(), 0);
|
1180
|
+
$this->assertNotEquals($tb->getFVint(FDI_ID), $last2);
|
1181
|
+
$db->endTrn();
|
1182
|
+
|
1183
|
+
// cleanup
|
1184
|
+
$tb2->del(); // last id = 29999
|
1185
|
+
$this->assertEquals($tb->stat(), 0);
|
1186
|
+
|
1187
|
+
// ------------------------------------------------------
|
1188
|
+
// Test use shared lock option
|
1189
|
+
// ------------------------------------------------------
|
1190
|
+
$db->beginTrn(Bz\transactd::MULTILOCK_REPEATABLE_READ);
|
1191
|
+
$this->assertEquals($db->stat(), 0);
|
1192
|
+
|
1193
|
+
$db2->beginTrn(Bz\transactd::MULTILOCK_REPEATABLE_READ);
|
1194
|
+
$this->assertEquals($db2->stat(), 0);
|
1195
|
+
|
1196
|
+
$tb->seekLast(Bz\transactd::ROW_LOCK_S);
|
1197
|
+
$this->assertEquals($tb->stat(), 0);
|
1198
|
+
$tb2->seekLast(Bz\transactd::ROW_LOCK_S);
|
1199
|
+
$this->assertEquals($tb2->stat(), 0);
|
1200
|
+
|
1201
|
+
$tb->seekPrev(); // Lock(X)
|
1202
|
+
$this->assertEquals($tb->stat(), 0);
|
1203
|
+
|
1204
|
+
$tb2->seekPrev(Bz\transactd::ROW_LOCK_S);
|
1205
|
+
$this->assertEquals($tb2->stat(), Bz\transactd::STATUS_LOCK_ERROR);
|
1206
|
+
|
1207
|
+
$tb->seekPrev(Bz\transactd::ROW_LOCK_S);
|
1208
|
+
$this->assertEquals($tb->stat(), 0);
|
1209
|
+
$id = $tb->getFVint(FDI_ID);
|
1210
|
+
|
1211
|
+
$tb2->setFV(FDI_ID, $id);
|
1212
|
+
$tb2->seek(Bz\transactd::ROW_LOCK_S);
|
1213
|
+
$this->assertEquals($tb2->stat(), 0);
|
1214
|
+
|
1215
|
+
$db2->endTrn();
|
1216
|
+
$db->endTrn();
|
1217
|
+
|
1218
|
+
// ------------------------------------------------------
|
1219
|
+
// Abort test
|
1220
|
+
// ------------------------------------------------------
|
1221
|
+
$db->beginTrn(Bz\transactd::SINGLELOCK_READ_COMMITED);
|
1222
|
+
$this->assertEquals($db->stat(), 0);
|
1223
|
+
|
1224
|
+
$tb->seekFirst();
|
1225
|
+
$this->assertEquals($tb->stat(), 0);
|
1226
|
+
$tb->setFV(FDI_NAME, 'EFG');
|
1227
|
+
$tb->update();
|
1228
|
+
$this->assertEquals($tb->stat(), 0);
|
1229
|
+
|
1230
|
+
$tb->seekNext();
|
1231
|
+
$db->abortTrn();
|
1232
|
+
$tb2->setKeyNum(0);
|
1233
|
+
$tb2->seekFirst();
|
1234
|
+
$this->assertEquals($tb2->getFVstr(FDI_NAME), 'ABC');
|
1235
|
+
|
1236
|
+
// ------------------------------------------------------
|
1237
|
+
// Test Query and locks Single record lock
|
1238
|
+
// ------------------------------------------------------
|
1239
|
+
$db->beginTrn(Bz\transactd::SINGLELOCK_READ_COMMITED);
|
1240
|
+
$this->assertEquals($db->stat(), 0);
|
1241
|
+
|
1242
|
+
// Test find last record locked
|
1243
|
+
$q = new Bz\query();
|
1244
|
+
$q->where('id', '<=', '100');
|
1245
|
+
$tb->setQuery($q);
|
1246
|
+
$tb->setFV(FDI_ID, 1);
|
1247
|
+
$tb->find();
|
1248
|
+
while ($tb->stat() == 0)
|
1249
|
+
$tb->findNext();
|
1250
|
+
$this->assertEquals($tb->getFVint(FDI_ID), 100);
|
1251
|
+
|
1252
|
+
// find read last is record of id = 101.
|
1253
|
+
// Would be difficult to identify the last
|
1254
|
+
// access to records at SINGLELOCK_READ_COMMITED.
|
1255
|
+
// No match records are unlocked.
|
1256
|
+
$tb2->setFV(FDI_ID, 100);
|
1257
|
+
$tb2->seek(Bz\transactd::ROW_LOCK_X);
|
1258
|
+
$this->assertEquals($tb2->stat(), 0);
|
1259
|
+
$tb2->unlock();
|
1260
|
+
$db->endTrn();
|
1261
|
+
|
1262
|
+
// ------------------------------------------------------
|
1263
|
+
// Test Query and locks Multi record lock
|
1264
|
+
// ------------------------------------------------------
|
1265
|
+
$db->beginTrn(Bz\transactd::MULTILOCK_READ_COMMITED);
|
1266
|
+
$this->assertEquals($db->stat(), 0);
|
1267
|
+
|
1268
|
+
// Test find records are lock.
|
1269
|
+
$q->reset()->where('id', '<=', 15)->and_('id', '<>', 13)->reject(0xFFFF);
|
1270
|
+
$tb->setQuery($q);
|
1271
|
+
$tb->setFV(FDI_ID, 12);
|
1272
|
+
$tb->find();
|
1273
|
+
while ($tb->stat() == 0)
|
1274
|
+
$tb->findNext();
|
1275
|
+
$this->assertEquals($tb->getFVint(FDI_ID), 15);
|
1276
|
+
|
1277
|
+
for ($i = 12; $i <= 16; $i++)
|
1278
|
+
{
|
1279
|
+
$tb2->setFV(FDI_ID, $i);
|
1280
|
+
$tb2->seek(Bz\transactd::ROW_LOCK_X);
|
1281
|
+
if (($i == 16) || ($i == 13))
|
1282
|
+
$this->assertEquals($tb2->stat(), 0);
|
1283
|
+
else
|
1284
|
+
$this->assertEquals($tb2->stat(), Bz\transactd::STATUS_LOCK_ERROR);
|
1285
|
+
}
|
1286
|
+
$db->endTrn();
|
1287
|
+
}
|
1288
|
+
public function testRecordLock()
|
1289
|
+
{
|
1290
|
+
$db = new Bz\database();
|
1291
|
+
$tb = $this->openTable($db);
|
1292
|
+
$this->assertNotEquals($tb, NULL);
|
1293
|
+
$db2 = new Bz\database();
|
1294
|
+
$db2->connect(PROTOCOL . HOSTNAME . DBNAME, true);
|
1295
|
+
$this->assertEquals($db2->stat(), 0);
|
1296
|
+
$tb2 = $this->openTable($db2);
|
1297
|
+
$this->assertNotEquals($tb2, NULL);
|
1298
|
+
|
1299
|
+
$tb->setKeyNum(0);
|
1300
|
+
$tb2->setKeyNum(0);
|
1301
|
+
|
1302
|
+
// Single record lock
|
1303
|
+
$tb->seekFirst(Bz\transactd::ROW_LOCK_X); // lock(X)
|
1304
|
+
$this->assertEquals($tb->stat(), 0);
|
1305
|
+
$tb2->seekFirst(); // Use consistent_read
|
1306
|
+
$this->assertEquals($tb2->stat(), 0);
|
1307
|
+
|
1308
|
+
$tb2->seekFirst(Bz\transactd::ROW_LOCK_X); // Try lock(X) single
|
1309
|
+
$this->assertEquals($tb2->stat(), Bz\transactd::STATUS_LOCK_ERROR);
|
1310
|
+
|
1311
|
+
// try consistent_read. Check ended that before auto transaction
|
1312
|
+
$tb2->seekFirst();
|
1313
|
+
$this->assertEquals($tb2->stat(), 0);
|
1314
|
+
|
1315
|
+
$tb2->seekNext(Bz\transactd::ROW_LOCK_X); // lock(X) second
|
1316
|
+
$this->assertEquals($tb2->stat(), 0);
|
1317
|
+
|
1318
|
+
$tb2->seekNext(Bz\transactd::ROW_LOCK_X); // lock(X) third, second lock freed
|
1319
|
+
$this->assertEquals($tb2->stat(), 0);
|
1320
|
+
|
1321
|
+
$tb->seekNext(); // nobody lock second.
|
1322
|
+
$this->assertEquals($tb->stat(), 0);
|
1323
|
+
$tb->seekNext(Bz\transactd::ROW_LOCK_X); // Try lock(X) third
|
1324
|
+
$this->assertEquals($tb->stat(), Bz\transactd::STATUS_LOCK_ERROR);
|
1325
|
+
|
1326
|
+
// Update test change third with lock(X)
|
1327
|
+
$tb2->setFV(FDI_NAME, 'The 3rd');
|
1328
|
+
$tb2->update(); // auto trn commit and unlock all locks
|
1329
|
+
$this->assertEquals($tb2->stat(), 0);
|
1330
|
+
$tb2->seekNext(Bz\transactd::ROW_LOCK_X); // lock(X) 4th
|
1331
|
+
$this->assertEquals($tb2->stat(), 0);
|
1332
|
+
$tb2->setFV(FDI_NAME, 'The 4th');
|
1333
|
+
$tb2->update(); // auto trn commit and unlock all locks
|
1334
|
+
|
1335
|
+
// Test unlock all locks, after update
|
1336
|
+
$tb->seekFirst(Bz\transactd::ROW_LOCK_X); // lock(X) first
|
1337
|
+
$this->assertEquals($tb2->stat(), 0);
|
1338
|
+
$tb->seekNext(Bz\transactd::ROW_LOCK_X); // lock(X) second
|
1339
|
+
$this->assertEquals($tb2->stat(), 0);
|
1340
|
+
$tb->seekNext(Bz\transactd::ROW_LOCK_X); // lock(X) third
|
1341
|
+
$this->assertEquals($tb2->stat(), 0);
|
1342
|
+
$this->assertEquals($tb->getFVstr(FDI_NAME), 'The 3rd');
|
1343
|
+
|
1344
|
+
// Test Insert, After record lock operation
|
1345
|
+
$tb->setFV(FDI_ID, 21000);
|
1346
|
+
$tb->insert();
|
1347
|
+
$this->assertEquals($tb->stat(), 0);
|
1348
|
+
$tb->del();
|
1349
|
+
$this->assertEquals($tb->stat(), 0);
|
1350
|
+
|
1351
|
+
// --------- Unlock test ----------------------------
|
1352
|
+
// 1 unlock()
|
1353
|
+
$tb->seekFirst(Bz\transactd::ROW_LOCK_X);
|
1354
|
+
$this->assertEquals($tb->stat(), 0);
|
1355
|
+
|
1356
|
+
$tb->unlock();
|
1357
|
+
|
1358
|
+
$tb2->seekFirst(Bz\transactd::ROW_LOCK_X);
|
1359
|
+
$this->assertEquals($tb2->stat(), 0);
|
1360
|
+
$tb2->unlock();
|
1361
|
+
|
1362
|
+
// 2 auto tran ended
|
1363
|
+
$tb3 = $this->openTable($db2);
|
1364
|
+
$tb2->seekFirst(Bz\transactd::ROW_LOCK_X);
|
1365
|
+
$this->assertEquals($tb2->stat(), 0);
|
1366
|
+
|
1367
|
+
$tb3->seekLast(); //This operation is another table handle, then auto tran ended
|
1368
|
+
$this->assertEquals($tb3->stat(), 0);
|
1369
|
+
|
1370
|
+
$tb->seekFirst(Bz\transactd::ROW_LOCK_X);
|
1371
|
+
$this->assertEquals($tb->stat(), 0);
|
1372
|
+
$tb->unlock();
|
1373
|
+
|
1374
|
+
// begin trn
|
1375
|
+
$tb3->seekFirst(Bz\transactd::ROW_LOCK_X);
|
1376
|
+
$this->assertEquals($tb3->stat(), 0);
|
1377
|
+
|
1378
|
+
$tb->seekFirst(Bz\transactd::ROW_LOCK_X);
|
1379
|
+
$this->assertEquals($tb->stat(), Bz\transactd::STATUS_LOCK_ERROR);
|
780
1380
|
$db2->beginTrn();
|
781
|
-
|
782
|
-
$
|
783
|
-
$this->assertEquals($
|
1381
|
+
|
1382
|
+
$tb->seekFirst(Bz\transactd::ROW_LOCK_X);
|
1383
|
+
$this->assertEquals($tb->stat(), 0);
|
784
1384
|
$db2->endTrn();
|
785
|
-
$
|
786
|
-
//
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
$tb->
|
791
|
-
$tb->
|
1385
|
+
$tb->unlock();
|
1386
|
+
// begin snapshot
|
1387
|
+
$tb3->seekFirst(Bz\transactd::ROW_LOCK_X);
|
1388
|
+
$this->assertEquals($tb3->stat(), 0);
|
1389
|
+
|
1390
|
+
$tb->seekFirst(Bz\transactd::ROW_LOCK_X);
|
1391
|
+
$this->assertEquals($tb->stat(), Bz\transactd::STATUS_LOCK_ERROR);
|
1392
|
+
$db2->beginSnapshot();
|
1393
|
+
$tb->seekFirst(Bz\transactd::ROW_LOCK_X);
|
792
1394
|
$this->assertEquals($tb->stat(), 0);
|
793
|
-
$
|
794
|
-
$tb->
|
1395
|
+
$db2->endSnapshot();
|
1396
|
+
$tb->unlock();
|
1397
|
+
// close Table
|
1398
|
+
$tb->seekFirst(Bz\transactd::ROW_LOCK_X);
|
795
1399
|
$this->assertEquals($tb->stat(), 0);
|
796
|
-
|
797
|
-
$
|
798
|
-
$
|
799
|
-
$
|
800
|
-
$tb2->seekFirst();
|
801
|
-
$this->assertEquals($tb2->
|
1400
|
+
|
1401
|
+
$tb2->seekFirst(Bz\transactd::ROW_LOCK_X);
|
1402
|
+
$this->assertEquals($tb2->stat(), Bz\transactd::STATUS_LOCK_ERROR);
|
1403
|
+
$tb->release();
|
1404
|
+
$tb2->seekFirst(Bz\transactd::ROW_LOCK_X);
|
1405
|
+
$this->assertEquals($tb2->stat(), 0);
|
1406
|
+
$tb2->unlock();
|
1407
|
+
// --------- End Unlock test ----------------------------
|
802
1408
|
}
|
803
1409
|
public function testExclusive()
|
804
1410
|
{
|
805
1411
|
// db mode exclusive
|
806
1412
|
$db = new Bz\database();
|
1413
|
+
// ------------------------------------------------------
|
1414
|
+
// database WRITE EXCLUSIVE
|
1415
|
+
// ------------------------------------------------------
|
807
1416
|
$db->open(URL, Bz\transactd::TYPE_SCHEMA_BDF, Bz\transactd::TD_OPEN_EXCLUSIVE);
|
808
1417
|
$this->assertEquals($db->stat(), 0);
|
809
1418
|
$tb = $db->openTable(TABLENAME);
|
@@ -815,71 +1424,167 @@ class transactdTest extends PHPUnit_Framework_TestCase
|
|
815
1424
|
$this->assertEquals($db2->stat(), 0);
|
816
1425
|
$db2->open(URL, Bz\transactd::TYPE_SCHEMA_BDF);
|
817
1426
|
$this->assertEquals($db2->stat(), Bz\transactd::STATUS_CANNOT_LOCK_TABLE);
|
818
|
-
|
819
|
-
$tb2 = $db->openTable(TABLENAME);
|
820
|
-
$this->assertEquals($db->stat(), 0);
|
821
|
-
|
822
|
-
$tb->setKeyNum(0);
|
823
|
-
$tb->seekFirst();
|
824
|
-
$this->assertEquals($tb->stat(), 0);
|
825
|
-
|
826
|
-
$tb->setFV(FDI_NAME, 'ABC123');
|
827
|
-
$tb->update();
|
828
|
-
$this->assertEquals($tb->stat(), 0);
|
829
|
-
|
830
|
-
$tb2->setKeyNum(0);
|
831
|
-
$tb2->seekFirst();
|
832
|
-
$this->assertEquals($tb2->stat(), 0);
|
833
|
-
$tb2->setFV(FDI_NAME, 'ABC124');
|
834
|
-
$tb2->update();
|
835
|
-
$this->assertEquals($tb2->stat(), 0);
|
836
|
-
|
837
1427
|
$tb->close();
|
838
|
-
$tb2->close();
|
839
1428
|
$db->close();
|
840
1429
|
$db2->close();
|
841
1430
|
|
1431
|
+
// ------------------------------------------------------
|
1432
|
+
// database WRITE EXCLUSIVE
|
1433
|
+
// ------------------------------------------------------
|
842
1434
|
// table mode exclusive
|
843
1435
|
$db = new Bz\database();
|
844
|
-
$db->open(URL, Bz\transactd::TYPE_SCHEMA_BDF, Bz\transactd::
|
1436
|
+
$db->open(URL, Bz\transactd::TYPE_SCHEMA_BDF, Bz\transactd::TD_OPEN_READONLY_EXCLUSIVE);
|
845
1437
|
$this->assertEquals($db->stat(), 0);
|
846
|
-
$tb = $db->openTable(TABLENAME, Bz\transactd::
|
1438
|
+
$tb = $db->openTable(TABLENAME, Bz\transactd::TD_OPEN_READONLY_EXCLUSIVE);
|
847
1439
|
$this->assertEquals($db->stat(), 0);
|
848
1440
|
|
1441
|
+
// Read only open
|
849
1442
|
$db2 = new Bz\database();
|
850
|
-
$db2->connect(PROTOCOL . HOSTNAME . DBNAME, true);
|
851
|
-
$this->assertEquals($db2->stat(), 0);
|
852
1443
|
$db2->open(URL, Bz\transactd::TYPE_SCHEMA_BDF);
|
853
1444
|
$this->assertEquals($db2->stat(), 0);
|
1445
|
+
$db2->close();
|
854
1446
|
|
855
|
-
//
|
856
|
-
$
|
857
|
-
$
|
1447
|
+
// Normal open
|
1448
|
+
$db2->connect(PROTOCOL . HOSTNAME . DBNAME, true);
|
1449
|
+
$db2->open(URL, Bz\transactd::TYPE_SCHEMA_BDF, Bz\transactd::TD_OPEN_NORMAL);
|
1450
|
+
$this->assertEquals($db2->stat(), 0);
|
1451
|
+
$db2->close();
|
858
1452
|
|
859
|
-
//
|
860
|
-
$
|
861
|
-
$this->assertEquals($
|
1453
|
+
// Write Exclusive open
|
1454
|
+
$db2->open(URL, Bz\transactd::TYPE_SCHEMA_BDF, Bz\transactd::TD_OPEN_EXCLUSIVE);
|
1455
|
+
$this->assertEquals($db2->stat(), Bz\transactd::STATUS_CANNOT_LOCK_TABLE);
|
1456
|
+
$db2->close();
|
862
1457
|
|
863
|
-
|
864
|
-
|
865
|
-
$
|
866
|
-
$db->close();
|
1458
|
+
// Read Exclusive open
|
1459
|
+
$db2->open(URL, Bz\transactd::TYPE_SCHEMA_BDF, Bz\transactd::TD_OPEN_READONLY_EXCLUSIVE);
|
1460
|
+
$this->assertEquals($db2->stat(), 0);
|
867
1461
|
$db2->close();
|
1462
|
+
$db->close();
|
868
1463
|
|
869
|
-
//
|
870
|
-
|
871
|
-
|
1464
|
+
// ------------------------------------------------------
|
1465
|
+
// Normal and Exclusive open tables mix use
|
1466
|
+
// ------------------------------------------------------
|
1467
|
+
$db->open(URL, Bz\transactd::TYPE_SCHEMA_BDF, Bz\transactd::TD_OPEN_NORMAL);
|
872
1468
|
$this->assertEquals($db->stat(), 0);
|
873
|
-
$tb = $db->openTable(TABLENAME);
|
1469
|
+
$tb = $db->openTable(TABLENAME, Bz\transactd::TD_OPEN_NORMAL);
|
874
1470
|
$this->assertEquals($db->stat(), 0);
|
1471
|
+
$db2->open(URL, Bz\transactd::TYPE_SCHEMA_BDF);
|
1472
|
+
$this->assertEquals($db2->stat(), 0);
|
875
1473
|
|
876
|
-
$
|
1474
|
+
$tb2 = $db->openTable('group', Bz\transactd::TD_OPEN_EXCLUSIVE);
|
1475
|
+
$this->assertEquals($db->stat(), 0);
|
1476
|
+
// Check tb2 Exclusive
|
1477
|
+
$tb3 = $db2->openTable('group', Bz\transactd::TD_OPEN_NORMAL);
|
1478
|
+
$this->assertEquals($db2->stat(), Bz\transactd::STATUS_CANNOT_LOCK_TABLE);
|
1479
|
+
|
1480
|
+
for ($i = 1; $i < 5; $i++)
|
1481
|
+
{
|
1482
|
+
$tb2->setFV(FDI_ID, $i + 1);
|
1483
|
+
$tb2->setFV(FDI_NAME, $i + 1);
|
1484
|
+
$tb2->insert();
|
1485
|
+
$this->assertEquals($tb2->stat(), 0);
|
1486
|
+
}
|
1487
|
+
$tb2->seekFirst();
|
1488
|
+
$this->assertEquals($tb2->stat(), 0);
|
1489
|
+
$tb->seekFirst();
|
1490
|
+
$this->assertEquals($tb->stat(), 0);
|
1491
|
+
$tb2->seekLast();
|
1492
|
+
$this->assertEquals($tb2->stat(), 0);
|
1493
|
+
$tb->seekLast();
|
1494
|
+
$this->assertEquals($tb->stat(), 0);
|
1495
|
+
// Normal close first
|
1496
|
+
$tb->close();
|
1497
|
+
$tb2->seekLast();
|
1498
|
+
$this->assertEquals($tb2->stat(), 0);
|
1499
|
+
$tb2->seekFirst();
|
1500
|
+
$this->assertEquals($tb2->stat(), 0);
|
1501
|
+
|
1502
|
+
// Reopen Normal
|
1503
|
+
$tb = $db->openTable('user');
|
1504
|
+
$tb2->seekFirst();
|
1505
|
+
$this->assertEquals($tb2->stat(), 0);
|
1506
|
+
$tb->seekFirst();
|
1507
|
+
$this->assertEquals($tb->stat(), 0);
|
1508
|
+
$tb2->seekLast();
|
1509
|
+
$this->assertEquals($tb2->stat(), 0);
|
1510
|
+
$tb->seekLast();
|
1511
|
+
$this->assertEquals($tb->stat(), 0);
|
1512
|
+
// Exclusive close first
|
1513
|
+
$tb2->close();
|
1514
|
+
$tb->seekFirst();
|
1515
|
+
$this->assertEquals($tb->stat(), 0);
|
1516
|
+
$tb->seekLast();
|
1517
|
+
$this->assertEquals($tb->stat(), 0);
|
1518
|
+
|
1519
|
+
// ------------------------------------------------------
|
1520
|
+
// Normal and Exclusive opend tables mix transaction
|
1521
|
+
// ------------------------------------------------------
|
1522
|
+
$tb2 = $db->openTable('group', Bz\transactd::TD_OPEN_EXCLUSIVE);
|
1523
|
+
$this->assertEquals($tb2->stat(), 0);
|
1524
|
+
// Check tb2 Exclusive
|
1525
|
+
$tb3 = $db2->openTable('group', Bz\transactd::TD_OPEN_NORMAL);
|
1526
|
+
$this->assertEquals($db2->stat(), Bz\transactd::STATUS_CANNOT_LOCK_TABLE);
|
1527
|
+
|
1528
|
+
$db->beginTrn();
|
877
1529
|
$tb->seekFirst();
|
878
1530
|
$this->assertEquals($tb->stat(), 0);
|
1531
|
+
$tb->setFV(FDI_NAME, 'mix trn');
|
1532
|
+
$tb->update();
|
1533
|
+
$this->assertEquals($tb->stat(), 0);
|
1534
|
+
|
1535
|
+
$tb2->seekFirst();
|
1536
|
+
$this->assertEquals($tb2->stat(), 0);
|
1537
|
+
$tb2->setFV(FDI_NAME, 'first mix trn tb2');
|
1538
|
+
$tb2->update();
|
1539
|
+
$this->assertEquals($tb2->stat(), 0);
|
1540
|
+
|
1541
|
+
$tb2->seekNext();
|
1542
|
+
$tb2->setFV(FDI_NAME, 'second mix trn tb2');
|
1543
|
+
$tb2->update();
|
1544
|
+
$this->assertEquals($tb2->stat(), 0);
|
1545
|
+
$db->endTrn();
|
1546
|
+
$tb2->seekFirst();
|
1547
|
+
$v = $tb2->getFVstr(FDI_NAME);
|
1548
|
+
$this->assertEquals($v, 'first mix trn tb2');
|
1549
|
+
$tb2->seekNext();
|
1550
|
+
$v = $tb2->getFVstr(FDI_NAME);
|
1551
|
+
$this->assertEquals($v, 'second mix trn tb2');
|
1552
|
+
|
1553
|
+
$tb2->close();
|
1554
|
+
$tb->close();
|
1555
|
+
}
|
1556
|
+
public function testMultiDatabase()
|
1557
|
+
{
|
1558
|
+
$db = new Bz\database();
|
1559
|
+
$tb = $this->openTable($db);
|
1560
|
+
$this->assertNotEquals($tb, NULL);
|
1561
|
+
$db2 = new Bz\database();
|
1562
|
+
$this->openDatabase($db2);
|
1563
|
+
$tb2 = $db2->openTable('group');
|
1564
|
+
$this->assertEquals($db2->stat(), 0);
|
1565
|
+
$this->assertNotEquals($tb2, NULL);
|
1566
|
+
|
1567
|
+
$db->beginTrn();
|
1568
|
+
$db2->beginTrn();
|
879
1569
|
|
880
|
-
$tb->
|
1570
|
+
$tb->seekFirst();
|
1571
|
+
$this->assertEquals($tb->stat(), 0);
|
1572
|
+
$v = $tb->getFVstr(FDI_NAME);
|
1573
|
+
$tb->setFV(FDI_NAME, 'MultiDatabase');
|
881
1574
|
$tb->update();
|
1575
|
+
|
1576
|
+
$tb2->seekFirst();
|
1577
|
+
$this->assertEquals($tb2->stat(), 0);
|
1578
|
+
$tb2->setFV(FDI_NAME, 'MultiDatabase');
|
1579
|
+
$tb2->update();
|
1580
|
+
$this->assertEquals($tb2->stat(), 0);
|
1581
|
+
$db2->endTrn();
|
1582
|
+
$db->abortTrn();
|
1583
|
+
|
1584
|
+
$tb->seekFirst();
|
882
1585
|
$this->assertEquals($tb->stat(), 0);
|
1586
|
+
$v2 = $tb->getFVstr(FDI_NAME);
|
1587
|
+
$this->assertEquals($v, $v2);
|
883
1588
|
}
|
884
1589
|
public function testInsert2()
|
885
1590
|
{
|
@@ -976,8 +1681,9 @@ class transactdTest extends PHPUnit_Framework_TestCase
|
|
976
1681
|
{
|
977
1682
|
// second connection
|
978
1683
|
$db2 = new Bz\database();
|
979
|
-
$db2->connect(PROTOCOL . HOSTNAME
|
980
|
-
$this->assertEquals($
|
1684
|
+
$db2->connect(PROTOCOL . HOSTNAME, true);
|
1685
|
+
$this->assertEquals($db2->stat(), 0);
|
1686
|
+
unset($db2);
|
981
1687
|
$db->disconnect(PROTOCOL . HOSTNAME);
|
982
1688
|
$this->assertEquals($db->stat(), 0);
|
983
1689
|
}
|
@@ -1188,103 +1894,103 @@ class transactdTest extends PHPUnit_Framework_TestCase
|
|
1188
1894
|
//}
|
1189
1895
|
// Set Ansi Get Wide
|
1190
1896
|
// too long string
|
1191
|
-
$tb->
|
1897
|
+
$tb->setFV(FDI_NAME, '1234567');
|
1192
1898
|
if ($varCharField)
|
1193
|
-
$this->assertEquals($tb->
|
1899
|
+
$this->assertEquals($tb->getFVstr(FDI_NAME), '123');
|
1194
1900
|
else
|
1195
|
-
$this->assertEquals($tb->
|
1901
|
+
$this->assertEquals($tb->getFVstr(FDI_NAME), '123456');
|
1196
1902
|
//if ($this->isWindows())
|
1197
1903
|
// $this->assertEquals($tb->getFVWstr(FDI_GROUP), '68');
|
1198
1904
|
//else
|
1199
|
-
$this->assertEquals($tb->
|
1905
|
+
$this->assertEquals($tb->getFVstr(FDI_GROUP), '68');
|
1200
1906
|
// short string
|
1201
|
-
$tb->
|
1202
|
-
$this->assertEquals($tb->
|
1907
|
+
$tb->setFV(FDI_NAME, '13 ');
|
1908
|
+
$this->assertEquals($tb->getFVstr(FDI_NAME), '13 ');
|
1203
1909
|
//if ($this->isWindows())
|
1204
1910
|
// $this->assertEquals($tb->getFVWstr(FDI_GROUP), '68');
|
1205
1911
|
//else
|
1206
|
-
$this->assertEquals($tb->
|
1912
|
+
$this->assertEquals($tb->getFVstr(FDI_GROUP), '68');
|
1207
1913
|
// too long kanji
|
1208
1914
|
if ($unicodeField)
|
1209
1915
|
{
|
1210
1916
|
if ($this->isWindows())
|
1211
1917
|
{
|
1212
|
-
$tb->
|
1918
|
+
$tb->setFV(FDI_NAME, 'あいうえお𩸽'); // hiragana 'aiueo' kanji 'hokke'
|
1213
1919
|
if ($varCharField)
|
1214
|
-
$this->assertEquals($tb->
|
1920
|
+
$this->assertEquals($tb->getFVstr(FDI_NAME), 'あいう');
|
1215
1921
|
else
|
1216
|
-
$this->assertEquals($tb->
|
1922
|
+
$this->assertEquals($tb->getFVstr(FDI_NAME), 'あいうえお');
|
1217
1923
|
}
|
1218
1924
|
}
|
1219
1925
|
else
|
1220
1926
|
{
|
1221
|
-
$tb->
|
1222
|
-
$is_valid_value = ($tb->
|
1927
|
+
$tb->setFV(FDI_NAME, '0松本市'); // numeric '0' kanji 'matumostoshi'
|
1928
|
+
$is_valid_value = ($tb->getFVstr(FDI_NAME) == '0松本');
|
1223
1929
|
$this->assertTrue($is_valid_value);
|
1224
1930
|
if (! $is_valid_value)
|
1225
|
-
print_r($tb->
|
1931
|
+
print_r($tb->getFVstr(FDI_NAME));
|
1226
1932
|
}
|
1227
|
-
$this->assertEquals($tb->
|
1933
|
+
$this->assertEquals($tb->getFVstr(FDI_GROUP), '68');
|
1228
1934
|
//// Set Wide Get Ansi
|
1229
1935
|
//if ($this->isWindows())
|
1230
1936
|
//{
|
1231
1937
|
// // too long string
|
1232
1938
|
// $tb->setFVW(FDI_NAME, '1234567');
|
1233
1939
|
// if ($varCharField)
|
1234
|
-
// $this->assertEquals($tb->
|
1940
|
+
// $this->assertEquals($tb->getFVstr(FDI_NAME), '123');
|
1235
1941
|
// else
|
1236
|
-
// $this->assertEquals($tb->
|
1942
|
+
// $this->assertEquals($tb->getFVstr(FDI_NAME), '123456');
|
1237
1943
|
// $this->assertEquals($tb->getFVWstr(FDI_GROUP), '68');
|
1238
1944
|
// // short string
|
1239
1945
|
// $tb->setFVW(1, '23 ');
|
1240
|
-
// $this->assertEquals($tb->
|
1946
|
+
// $this->assertEquals($tb->getFVstr(FDI_NAME), '23 ');
|
1241
1947
|
// $this->assertEquals($tb->getFVWstr(FDI_GROUP), '68');
|
1242
1948
|
// // too long kanji
|
1243
1949
|
// if ($unicodeField)
|
1244
1950
|
// {
|
1245
1951
|
// $tb->setFVW(FDI_NAME, 'あいうえお𩸽'); // hiragana 'aiueo' kanji 'hokke'
|
1246
1952
|
// if ($varCharField)
|
1247
|
-
// $this->assertEquals($tb->
|
1953
|
+
// $this->assertEquals($tb->getFVstr(FDI_NAME), 'あいう');
|
1248
1954
|
// else
|
1249
|
-
// $this->assertEquals($tb->
|
1955
|
+
// $this->assertEquals($tb->getFVstr(FDI_NAME), 'あいうえお');
|
1250
1956
|
// }
|
1251
1957
|
// else
|
1252
1958
|
// {
|
1253
1959
|
// $tb->setFVW(FDI_NAME, '0松本市'); // numeric '0' kanji 'matumostoshi'
|
1254
|
-
// $this->assertEquals($tb->
|
1960
|
+
// $this->assertEquals($tb->getFVstr(FDI_NAME), '0松本');
|
1255
1961
|
// }
|
1256
1962
|
// $this->assertEquals($tb->getFVWstr(FDI_GROUP), '68');
|
1257
1963
|
//}
|
1258
1964
|
// Set Ansi Get Ansi
|
1259
1965
|
// too long string
|
1260
|
-
$tb->
|
1966
|
+
$tb->setFV(FDI_NAME, '1234567');
|
1261
1967
|
if ($varCharField)
|
1262
|
-
$this->assertEquals($tb->
|
1968
|
+
$this->assertEquals($tb->getFVstr(FDI_NAME), '123');
|
1263
1969
|
else
|
1264
|
-
$this->assertEquals($tb->
|
1265
|
-
$this->assertEquals($tb->
|
1970
|
+
$this->assertEquals($tb->getFVstr(FDI_NAME), '123456');
|
1971
|
+
$this->assertEquals($tb->getFVstr(FDI_GROUP), '68');
|
1266
1972
|
// short string
|
1267
|
-
$tb->
|
1268
|
-
$this->assertEquals($tb->
|
1269
|
-
$this->assertEquals($tb->
|
1973
|
+
$tb->setFV(FDI_NAME, '13 ');
|
1974
|
+
$this->assertEquals($tb->getFVstr(FDI_NAME), '13 ');
|
1975
|
+
$this->assertEquals($tb->getFVstr(FDI_GROUP), '68');
|
1270
1976
|
// too long lanji
|
1271
1977
|
if ($unicodeField)
|
1272
1978
|
{
|
1273
1979
|
if ($this->isWindows())
|
1274
1980
|
{
|
1275
|
-
$tb->
|
1981
|
+
$tb->setFV(FDI_NAME, 'あいうえお𩸽'); // hiragana 'aiueo' kanji 'hokke'
|
1276
1982
|
if ($varCharField)
|
1277
|
-
$this->assertEquals($tb->
|
1983
|
+
$this->assertEquals($tb->getFVstr(FDI_NAME), 'あいう');
|
1278
1984
|
else
|
1279
|
-
$this->assertEquals($tb->
|
1985
|
+
$this->assertEquals($tb->getFVstr(FDI_NAME), 'あいうえお');
|
1280
1986
|
}
|
1281
1987
|
}
|
1282
1988
|
else
|
1283
1989
|
{
|
1284
|
-
$tb->
|
1285
|
-
$this->assertEquals($tb->
|
1990
|
+
$tb->setFV(FDI_NAME, '0松本市'); // numeric '0' kanji 'matumostoshi'
|
1991
|
+
$this->assertEquals($tb->getFVstr(FDI_NAME), '0松本');
|
1286
1992
|
}
|
1287
|
-
$this->assertEquals($tb->
|
1993
|
+
$this->assertEquals($tb->getFVstr(FDI_GROUP), '68');
|
1288
1994
|
}
|
1289
1995
|
public function testVarField()
|
1290
1996
|
{
|
@@ -1318,7 +2024,6 @@ class transactdTest extends PHPUnit_Framework_TestCase
|
|
1318
2024
|
$this->assertEquals($db->stat(), 0);
|
1319
2025
|
// utf8 varchar
|
1320
2026
|
$this->setGetVar($tb, true, true);
|
1321
|
-
$tb->close();
|
1322
2027
|
}
|
1323
2028
|
private function doVarInsert($db, $name, $codePage, $str, $startid, $endid, $bulk)
|
1324
2029
|
{
|
@@ -1934,7 +2639,7 @@ class transactdTest extends PHPUnit_Framework_TestCase
|
|
1934
2639
|
$td->id = $id;
|
1935
2640
|
$td->pageSize = 2048;
|
1936
2641
|
$td->schemaCodePage = Bz\transactd::CP_UTF8;
|
1937
|
-
$td->charsetIndex = Bz\transactd::
|
2642
|
+
$td->charsetIndex = Bz\transactd::CHARSET_UTF8;
|
1938
2643
|
$dbdef->insertTable($td);
|
1939
2644
|
$this->assertEquals($dbdef->stat(), 0);
|
1940
2645
|
// id field
|
@@ -1990,7 +2695,7 @@ class transactdTest extends PHPUnit_Framework_TestCase
|
|
1990
2695
|
$td->id = $id;
|
1991
2696
|
$td->pageSize = 2048;
|
1992
2697
|
$td->schemaCodePage = Bz\transactd::CP_UTF8;
|
1993
|
-
$td->charsetIndex = Bz\transactd::
|
2698
|
+
$td->charsetIndex = Bz\transactd::CHARSET_UTF8;
|
1994
2699
|
$dbdef->insertTable($td);
|
1995
2700
|
$this->assertEquals($dbdef->stat(), 0);
|
1996
2701
|
// code field
|
@@ -2029,7 +2734,7 @@ class transactdTest extends PHPUnit_Framework_TestCase
|
|
2029
2734
|
$td->id = $id;
|
2030
2735
|
$td->pageSize = 2048;
|
2031
2736
|
$td->schemaCodePage = Bz\transactd::CP_UTF8;
|
2032
|
-
$td->charsetIndex = Bz\transactd::
|
2737
|
+
$td->charsetIndex = Bz\transactd::CHARSET_UTF8;
|
2033
2738
|
$dbdef->insertTable($td);
|
2034
2739
|
$this->assertEquals($dbdef->stat(), 0);
|
2035
2740
|
// id field
|
@@ -2042,6 +2747,11 @@ class transactdTest extends PHPUnit_Framework_TestCase
|
|
2042
2747
|
$fd->setName('comment');
|
2043
2748
|
$fd->type = Bz\transactd::ft_myvarchar;
|
2044
2749
|
$fd->setLenByCharnum(60);
|
2750
|
+
// blob field
|
2751
|
+
$fd = $dbdef->insertField($id, 2);
|
2752
|
+
$fd->setName('blob');
|
2753
|
+
$fd->type = Bz\transactd::ft_myblob;
|
2754
|
+
$fd->len = 10;
|
2045
2755
|
// key 0 (primary) id
|
2046
2756
|
$kd = $dbdef->insertKey($id, 0);
|
2047
2757
|
$kd->segment(0)->fieldNum = 0;
|
@@ -2094,10 +2804,10 @@ class transactdTest extends PHPUnit_Framework_TestCase
|
|
2094
2804
|
{
|
2095
2805
|
$tb->setFV(0, $i);
|
2096
2806
|
$tb->setFV(1, "$i comment");
|
2807
|
+
$tb->setFV(2, "$i blob");
|
2097
2808
|
$tb->insert();
|
2098
2809
|
$this->assertEquals($tb->stat(), 0);
|
2099
2810
|
}
|
2100
|
-
$tb->close();
|
2101
2811
|
$db->endTrn();
|
2102
2812
|
}
|
2103
2813
|
|
@@ -2106,10 +2816,21 @@ class transactdTest extends PHPUnit_Framework_TestCase
|
|
2106
2816
|
$db = new Bz\database();
|
2107
2817
|
// check database existence
|
2108
2818
|
$db->open(URL_QT, Bz\transactd::TYPE_SCHEMA_BDF, Bz\transactd::TD_OPEN_NORMAL);
|
2109
|
-
if ($db->stat()
|
2110
|
-
|
2819
|
+
if ($db->stat() !== 0)
|
2820
|
+
echo("\nDatabase " . DBNAME_QT . " not found");
|
2821
|
+
else
|
2822
|
+
{
|
2823
|
+
$def = $db->dbDef();
|
2824
|
+
$td = $def->tableDefs(3);
|
2825
|
+
if ($td != NULL && $td->fieldCount === 3) {
|
2826
|
+
$tb = $db->openTable('extention');
|
2827
|
+
if ($db->stat() === 0 && $tb->recordCount(false) === TEST_COUNT)
|
2828
|
+
return;
|
2829
|
+
$tb->close();
|
2830
|
+
}
|
2831
|
+
$db->drop();
|
2111
2832
|
}
|
2112
|
-
echo("\
|
2833
|
+
echo("\nCreate database " . DBNAME_QT . "\n");
|
2113
2834
|
$db->create(URL_QT);
|
2114
2835
|
$this->assertEquals($db->stat(), 0);
|
2115
2836
|
$db->open(URL_QT, Bz\transactd::TYPE_SCHEMA_BDF, Bz\transactd::TD_OPEN_NORMAL);
|
@@ -2276,15 +2997,22 @@ class transactdTest extends PHPUnit_Framework_TestCase
|
|
2276
2997
|
$q->select('id', 'name', 'group')->where('id', '<=', 15000);
|
2277
2998
|
$rs = $atu->index(0)->keyValue(1)->read($q);
|
2278
2999
|
$this->assertEquals($rs->size(), 15000);
|
3000
|
+
$this->assertEquals($rs->fieldDefs()->size(), 3);
|
2279
3001
|
|
2280
3002
|
// Join extention::comment
|
2281
3003
|
$q->reset();
|
2282
|
-
$
|
2283
|
-
|
3004
|
+
$this->assertEquals($q->selectCount(), 0);
|
3005
|
+
|
3006
|
+
$q->select('comment')->optimize(Bz\queryBase::joinHasOneOrHasMany);
|
3007
|
+
$this->assertEquals($q->selectCount(), 1);
|
3008
|
+
$ate->index(0)->join($rs, $q, 'id');
|
3009
|
+
$this->assertEquals($q->selectCount(), 1);
|
2284
3010
|
$this->assertEquals($rs->size(), 15000);
|
3011
|
+
$this->assertEquals($rs->fieldDefs()->size(), 4);
|
2285
3012
|
|
2286
3013
|
// reverse and get first (so it means 'get last')
|
2287
3014
|
$last = $rs->reverse()->first();
|
3015
|
+
$this->assertEquals($rs->size(), 15000);
|
2288
3016
|
$this->assertEquals($last['id'], 15000);
|
2289
3017
|
$this->assertEquals($last['comment'], '15000 comment');
|
2290
3018
|
|
@@ -2350,9 +3078,13 @@ class transactdTest extends PHPUnit_Framework_TestCase
|
|
2350
3078
|
|
2351
3079
|
// clone
|
2352
3080
|
$rsv = clone $rs;
|
3081
|
+
$this->assertEquals($rsv->size(), 16000);
|
2353
3082
|
$gq->reset();
|
2354
3083
|
$count3 = new Bz\count('count3');
|
2355
3084
|
$gq->addFunction($count3)->keyField('group');
|
3085
|
+
$this->assertEquals($gq->functionCount(), 1);
|
3086
|
+
$this->assertEquals($gq->getKeyFields()->count(), 1);
|
3087
|
+
|
2356
3088
|
$rs->groupBy($gq);
|
2357
3089
|
$this->assertEquals($rs->size(), 5);
|
2358
3090
|
$this->assertEquals($rsv->size(), 16000);
|
@@ -2387,6 +3119,238 @@ class transactdTest extends PHPUnit_Framework_TestCase
|
|
2387
3119
|
$q3->keyField('group', 'id');
|
2388
3120
|
unset($q3);
|
2389
3121
|
}
|
3122
|
+
public function testPrepareJoin()
|
3123
|
+
{
|
3124
|
+
$db = new Bz\database();
|
3125
|
+
$db->open(URL_QT);
|
3126
|
+
$this->assertEquals($db->stat(), 0);
|
3127
|
+
|
3128
|
+
$atu = new Bz\ActiveTable($db, 'user');
|
3129
|
+
$atu->alias('名前', 'name');
|
3130
|
+
$atg = new Bz\ActiveTable($db, 'groups');
|
3131
|
+
$atg->alias('name', 'group_name');
|
3132
|
+
$ate = new Bz\ActiveTable($db, 'extention');
|
3133
|
+
$q = new Bz\query();
|
3134
|
+
|
3135
|
+
$q->select('id', 'name', 'group')->where('id', '<=', '?');
|
3136
|
+
$pq = $atu->prepare($q);
|
3137
|
+
|
3138
|
+
// int value
|
3139
|
+
$rs = $atu->index(0)->keyValue(1)->read($pq, 15000);
|
3140
|
+
$this->assertEquals($rs->size(), 15000);
|
3141
|
+
$this->assertEquals($rs->fieldDefs()->size(), 3);
|
3142
|
+
// string value
|
3143
|
+
$rs = $atu->index(0)->keyValue(1)->read($pq, '15000');
|
3144
|
+
$this->assertEquals($rs->size(), 15000);
|
3145
|
+
$this->assertEquals($rs->fieldDefs()->size(), 3);
|
3146
|
+
// double value
|
3147
|
+
$rs = $atu->index(0)->keyValue(1)->read($pq, 15000.000);
|
3148
|
+
$this->assertEquals($rs->size(), 15000);
|
3149
|
+
$this->assertEquals($rs->fieldDefs()->size(), 3);
|
3150
|
+
// Using supply value
|
3151
|
+
$pq->supplyValue(0, 15000);
|
3152
|
+
$rs = $atu->index(0)->keyValue(1)->read($pq);
|
3153
|
+
$this->assertEquals($rs->size(), 15000);
|
3154
|
+
$this->assertEquals($rs->fieldDefs()->size(), 3);
|
3155
|
+
|
3156
|
+
// Join extention::comment
|
3157
|
+
$q->reset();
|
3158
|
+
$this->assertEquals($q->selectCount(), 0);
|
3159
|
+
$q->select('comment')->optimize(Bz\queryBase::joinHasOneOrHasMany);
|
3160
|
+
$this->assertEquals($q->selectCount(), 1);
|
3161
|
+
$pq = $ate->prepare($q);
|
3162
|
+
|
3163
|
+
$ate->index(0)->join($rs, $pq, 'id');
|
3164
|
+
$this->assertEquals($q->selectCount(), 1);
|
3165
|
+
$this->assertEquals($rs->size(), 15000);
|
3166
|
+
$this->assertEquals($rs->fieldDefs()->size(), 4);
|
3167
|
+
// reverse and get first (so it means 'get last')
|
3168
|
+
$last = $rs->reverse()->first();
|
3169
|
+
$this->assertEquals($rs->size(), 15000);
|
3170
|
+
$this->assertEquals($last['id'], 15000);
|
3171
|
+
$this->assertEquals($last['comment'], '15000 comment');
|
3172
|
+
|
3173
|
+
// Join group::name
|
3174
|
+
$q->reset()->select('group_name');
|
3175
|
+
$pq = $atg->prepare($q);
|
3176
|
+
$atg->index(0)->join($rs, $pq, 'group');
|
3177
|
+
$this->assertEquals($rs->size(), 15000);
|
3178
|
+
|
3179
|
+
// get last (the rs is reversed, so it means 'get first')
|
3180
|
+
$first = $rs->last();
|
3181
|
+
$this->assertEquals($first['id'], 1);
|
3182
|
+
$this->assertEquals($first['comment'], '1 comment');
|
3183
|
+
$this->assertEquals($first['group_name'], '1 group');
|
3184
|
+
|
3185
|
+
// row in rs[15000 - 9]
|
3186
|
+
$rec = $rs[15000 - 9];
|
3187
|
+
$this->assertEquals($rec['group_name'], '4 group');
|
3188
|
+
}
|
3189
|
+
public function testServerPrepareJoin()
|
3190
|
+
{
|
3191
|
+
define('NO_RECORD_ID', 5);
|
3192
|
+
$db = new Bz\database();
|
3193
|
+
$db->open(URL_QT);
|
3194
|
+
$this->assertEquals($db->stat(), 0);
|
3195
|
+
|
3196
|
+
$atu = new Bz\ActiveTable($db, 'user');
|
3197
|
+
$atu->alias('名前', 'name');
|
3198
|
+
$atg = new Bz\ActiveTable($db, 'groups');
|
3199
|
+
$atg->alias('name', 'group_name');
|
3200
|
+
$ate = new Bz\ActiveTable($db, 'extention');
|
3201
|
+
$q = new Bz\query();
|
3202
|
+
|
3203
|
+
$q->select('id', 'name', 'group')->where('id', '<=', '?');
|
3204
|
+
$stmt1 = $atu->prepare($q, true);
|
3205
|
+
$this->assertNotEquals($stmt1, NULL);
|
3206
|
+
|
3207
|
+
$q->reset()->select('comment')->optimize(Bz\queryBase::joinHasOneOrHasMany);
|
3208
|
+
$stmt2 = $ate->prepare($q, true);
|
3209
|
+
$this->assertNotEquals($stmt2, NULL);
|
3210
|
+
|
3211
|
+
$q->reset()->select('group_name');
|
3212
|
+
$stmt3 = $atg->prepare($q, true);
|
3213
|
+
$this->assertNotEquals($stmt3, NULL);
|
3214
|
+
|
3215
|
+
$rs = $atu->index(0)->keyValue(1)->read($stmt1, 15000);
|
3216
|
+
$this->assertEquals($rs->size(), 15000);
|
3217
|
+
|
3218
|
+
// Join extention::comment
|
3219
|
+
$ate->index(0)->join($rs, $stmt2, 'id');
|
3220
|
+
$this->assertEquals($rs->size(), 15000);
|
3221
|
+
|
3222
|
+
// test reverse
|
3223
|
+
$last = $rs->reverse()->first();
|
3224
|
+
$this->assertEquals($last['id'], 15000);
|
3225
|
+
$this->assertEquals($last['comment'], '15000 comment');
|
3226
|
+
|
3227
|
+
// Join group::name
|
3228
|
+
$atg->index(0)->join($rs, $stmt3, 'group');
|
3229
|
+
$this->assertEquals($rs->size(), 15000);
|
3230
|
+
$first = $rs->last();
|
3231
|
+
|
3232
|
+
$this->assertEquals($first['id'], 1);
|
3233
|
+
$this->assertEquals($first['comment'], '1 comment');
|
3234
|
+
$this->assertEquals($first['group_name'], '1 group');
|
3235
|
+
|
3236
|
+
// $rs[15000 - 9];
|
3237
|
+
$rec = $rs[15000 - 9];
|
3238
|
+
$this->assertEquals($rec['group_name'], '4 group');
|
3239
|
+
|
3240
|
+
// Test orderby
|
3241
|
+
$rs->orderBy('group_name');
|
3242
|
+
// $rs[0];
|
3243
|
+
$this->assertEquals($rs[0]['group_name'], '1 group');
|
3244
|
+
|
3245
|
+
/*
|
3246
|
+
sortFields orderRv;
|
3247
|
+
orderRv.add('group_name', false);
|
3248
|
+
rs.orderBy(orderRv);
|
3249
|
+
|
3250
|
+
sortFields order;
|
3251
|
+
order.add('group_name', true);
|
3252
|
+
rs.orderBy(order);
|
3253
|
+
BOOST_CHECK_MESSAGE(_tstring(rs[(size_t)0]['group_name'].c_str()) ==
|
3254
|
+
_tstring('1 group'),
|
3255
|
+
"group_name = 1 group "
|
3256
|
+
<< string(rs[(size_t)0]['group_name'].a_str()));
|
3257
|
+
*/
|
3258
|
+
// All fields
|
3259
|
+
$rs->clear();
|
3260
|
+
$q->reset()->all();
|
3261
|
+
$q->where('id', '<=', '?');
|
3262
|
+
$stmt1 = $atu->prepare($q, true);
|
3263
|
+
$rs = $atu->keyValue(1)->read($stmt1, 15000);
|
3264
|
+
$this->assertEquals($rs->size(), 15000);
|
3265
|
+
if ($rs->size() == 15000)
|
3266
|
+
{
|
3267
|
+
for ($i = 0; $i < 15000; $i++)
|
3268
|
+
$this->assertEquals($rs[$i]['id'], $i + 1);
|
3269
|
+
}
|
3270
|
+
|
3271
|
+
$ate->join($rs, $stmt2, 'id');
|
3272
|
+
$this->assertEquals($rs->size(), 15000);
|
3273
|
+
$atg->join($rs, $stmt3, 'group');
|
3274
|
+
$this->assertEquals($rs->size(), 15000);
|
3275
|
+
|
3276
|
+
// OuterJoin
|
3277
|
+
$tb = $ate->table();
|
3278
|
+
$tb->setFV('id', NO_RECORD_ID);
|
3279
|
+
$tb->seek();
|
3280
|
+
$this->assertEquals($tb->stat(), 0);
|
3281
|
+
if ($tb->stat() == 0)
|
3282
|
+
$tb->del();
|
3283
|
+
$this->assertEquals($tb->stat(), 0);
|
3284
|
+
$q->reset()->select('comment', 'blob')->optimize(Bz\queryBase::joinHasOneOrHasMany);
|
3285
|
+
$stmt2 = $ate->prepare($q, true);
|
3286
|
+
|
3287
|
+
// Join is remove record(s) no join target record.
|
3288
|
+
$rs->clear();
|
3289
|
+
$rs = $atu->keyValue(1)->read($stmt1, 15000);
|
3290
|
+
$ate->join($rs, $stmt2, 'id');
|
3291
|
+
$this->assertEquals($rs->size(), 14999);
|
3292
|
+
$this->assertEquals($rs[NO_RECORD_ID - 1]['id'], NO_RECORD_ID + 1);
|
3293
|
+
$this->assertEquals($rs[NO_RECORD_ID - 1]['comment'], '' . (NO_RECORD_ID + 1) . ' comment');
|
3294
|
+
$this->assertEquals($rs[NO_RECORD_ID - 1]['blob'], '' . (NO_RECORD_ID + 1) . ' blob');
|
3295
|
+
|
3296
|
+
// OuterJoin is no remove record(s) no join target record.
|
3297
|
+
$rs->clear();
|
3298
|
+
$rs = $atu->keyValue(1)->read($stmt1, 15000);
|
3299
|
+
$ate->outerJoin($rs, $stmt2, 'id');
|
3300
|
+
$this->assertEquals($rs->size(), 15000);
|
3301
|
+
$atg->outerJoin($rs, $stmt3, 'group');
|
3302
|
+
$this->assertEquals($rs->size(), 15000);
|
3303
|
+
|
3304
|
+
$this->assertEquals($rs[NO_RECORD_ID - 1]->isInvalidRecord(), true);
|
3305
|
+
$this->assertEquals($rs[NO_RECORD_ID]['comment'], '' . (NO_RECORD_ID + 1) . ' comment');
|
3306
|
+
$this->assertEquals($rs[NO_RECORD_ID]['blob'], '' . (NO_RECORD_ID + 1) . ' blob');
|
3307
|
+
|
3308
|
+
// OuterJoin All Join fields
|
3309
|
+
$q->reset()->optimize(Bz\queryBase::joinHasOneOrHasMany)->all();
|
3310
|
+
$stmt2 = $ate->prepare($q, true);
|
3311
|
+
$rs->clear();
|
3312
|
+
$rs = $atu->keyValue(1)->read($stmt1, 15000);
|
3313
|
+
$ate->outerJoin($rs, $stmt2, 'id');
|
3314
|
+
$this->assertEquals($rs->size(), 15000);
|
3315
|
+
$this->assertEquals($rs[NO_RECORD_ID - 1]->isInvalidRecord(), true);
|
3316
|
+
$this->assertEquals($rs[NO_RECORD_ID]['comment'], '' . (NO_RECORD_ID + 1) . ' comment');
|
3317
|
+
$this->assertEquals($rs[NO_RECORD_ID]['blob'], '' . (NO_RECORD_ID + 1) . ' blob');
|
3318
|
+
|
3319
|
+
// Test clone blob field
|
3320
|
+
$rs2 = clone($rs);
|
3321
|
+
$this->assertEquals($rs2->size(), 15000);
|
3322
|
+
$this->assertEquals($rs2[NO_RECORD_ID - 1]->isInvalidRecord(), true);
|
3323
|
+
$this->assertEquals($rs2[NO_RECORD_ID]['comment'], '' . (NO_RECORD_ID + 1) . ' comment');
|
3324
|
+
$this->assertEquals($rs2[NO_RECORD_ID]['blob'], '' . (NO_RECORD_ID + 1) . ' blob');
|
3325
|
+
|
3326
|
+
// hasManyJoin inner
|
3327
|
+
$rs->clear();
|
3328
|
+
$q->reset()->reject(0xFFFF)->limit(0)->all();
|
3329
|
+
$rs = $atg->keyValue(1)->read($q);
|
3330
|
+
$this->assertEquals($rs->size(), 100);
|
3331
|
+
$q->all()->optimize(Bz\queryBase::joinHasOneOrHasMany);
|
3332
|
+
$atu->index(1)->join($rs, $q, 'code');
|
3333
|
+
$this->assertEquals($rs->size(), 20000);
|
3334
|
+
|
3335
|
+
// hasManyJoin outer
|
3336
|
+
$rs->clear();
|
3337
|
+
$q->reset()->reject(0xFFFF)->limit(0)->all();
|
3338
|
+
$rs = $atg->keyValue(1)->read($q);
|
3339
|
+
$this->assertEquals($rs->size(), 100);
|
3340
|
+
$q->all()->optimize(Bz\queryBase::joinHasOneOrHasMany);
|
3341
|
+
$atu->index(1)->outerJoin($rs, $q, 'code');
|
3342
|
+
$this->assertEquals($rs->size(), 20095);
|
3343
|
+
|
3344
|
+
// restore record
|
3345
|
+
$tb->clearBuffer();
|
3346
|
+
$tb->setFV('id', NO_RECORD_ID);
|
3347
|
+
$tb->setFV('comment', '5 comment');
|
3348
|
+
$tb->setFV('blob', '5 blob');
|
3349
|
+
$tb->insert();
|
3350
|
+
$this->assertEquals($tb->stat(), 0);
|
3351
|
+
if ($tb->stat() != 0)
|
3352
|
+
$db->drop();
|
3353
|
+
}
|
2390
3354
|
public function testWritableRecord()
|
2391
3355
|
{
|
2392
3356
|
$db = new Bz\database();
|