transactd 2.1.0 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bin/common/tdclc_32_2_2.dll +0 -0
- data/bin/common/tdclc_64_2_2.dll +0 -0
- data/build/swig/ruby/generate.cmd +45 -0
- data/build/swig/ruby/generate.sh +40 -0
- data/build/swig/ruby/tdclrb_wrap.cpp +406 -969
- data/build/swig/tdcl.i +88 -0
- data/build/tdclc/CMakeLists.txt +5 -1
- data/build/tdclc/tdclc.cbproj +1 -1
- data/build/tdclc/tdclc.rc +4 -4
- data/build/tdclcpp/tdclcpp.rc +4 -4
- data/build/tdclcpp/tdclcpp_bc.cbproj +1 -1
- data/build/tdclrb/tdclrb.rc +4 -4
- data/source/bzs/db/engine/mysql/database.cpp +165 -74
- data/source/bzs/db/engine/mysql/database.h +19 -5
- data/source/bzs/db/engine/mysql/dbManager.cpp +33 -11
- data/source/bzs/db/engine/mysql/dbManager.h +6 -1
- data/source/bzs/db/engine/mysql/mydebuglog.h +12 -0
- data/source/bzs/db/engine/mysql/mysqlInternal.h +10 -3
- data/source/bzs/db/engine/mysql/mysqlThd.cpp +20 -8
- data/source/bzs/db/protocol/hs/hsCommandExecuter.cpp +12 -7
- data/source/bzs/db/protocol/hs/hsCommandExecuter.h +1 -1
- data/source/bzs/db/protocol/tdap/client/activeTableImple.h +1 -0
- data/source/bzs/db/protocol/tdap/client/client.cpp +17 -15
- data/source/bzs/db/protocol/tdap/client/client.h +102 -30
- data/source/bzs/db/protocol/tdap/client/connectionPool.cpp +1 -1
- data/source/bzs/db/protocol/tdap/client/database.cpp +32 -10
- data/source/bzs/db/protocol/tdap/client/database.h +1 -0
- data/source/bzs/db/protocol/tdap/client/databaseFactory.cpp +0 -2
- data/source/bzs/db/protocol/tdap/client/dbDef.cpp +2 -0
- data/source/bzs/db/protocol/tdap/client/dllmain.cpp +47 -42
- data/source/bzs/db/protocol/tdap/client/fields.h +3 -1
- data/source/bzs/db/protocol/tdap/client/filter.h +3 -3
- data/source/bzs/db/protocol/tdap/client/nsDatabase.cpp +18 -2
- data/source/bzs/db/protocol/tdap/client/nsDatabase.h +3 -2
- data/source/bzs/db/protocol/tdap/client/nsTable.cpp +14 -6
- data/source/bzs/db/protocol/tdap/client/nsTable.h +12 -12
- data/source/bzs/db/protocol/tdap/client/recordsetImple.h +6 -3
- data/source/bzs/db/protocol/tdap/client/request.h +1 -0
- data/source/bzs/db/protocol/tdap/client/sqlBuilder.cpp +101 -64
- data/source/bzs/db/protocol/tdap/client/sqlBuilder.h +3 -0
- data/source/bzs/db/protocol/tdap/client/stringConverter.h +9 -13
- data/source/bzs/db/protocol/tdap/client/table.cpp +73 -56
- data/source/bzs/db/protocol/tdap/client/table.h +8 -8
- data/source/bzs/db/protocol/tdap/client/trdboostapi.h +52 -100
- data/source/bzs/db/protocol/tdap/mysql/databaseSchema.cpp +8 -1
- data/source/bzs/db/protocol/tdap/mysql/request.h +6 -0
- data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.cpp +349 -189
- data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.h +28 -12
- data/source/bzs/db/protocol/tdap/tdapRequest.h +5 -4
- data/source/bzs/db/protocol/tdap/tdapSchema.h +6 -1
- data/source/bzs/db/protocol/tdap/tdapcapi.h +29 -4
- data/source/bzs/db/protocol/tdap/uri.h +297 -0
- data/source/bzs/db/transactd/appModule.cpp +41 -16
- data/source/bzs/db/transactd/appModule.h +1 -2
- data/source/bzs/db/transactd/transactd.cpp +37 -14
- data/source/bzs/env/crosscompile.h +1 -3
- data/source/bzs/example/queryData.cpp +2 -2
- data/source/bzs/netsvc/client/iconnection.h +3 -1
- data/source/bzs/netsvc/client/tcpClient.cpp +75 -28
- data/source/bzs/netsvc/client/tcpClient.h +94 -62
- data/source/bzs/netsvc/server/IAppModule.h +2 -2
- data/source/bzs/netsvc/server/serverCpt.cpp +17 -10
- data/source/bzs/netsvc/server/serverPipe.cpp +26 -19
- data/source/bzs/netsvc/server/serverTpool.cpp +8 -2
- data/source/bzs/rtl/debuglog.cpp +21 -5
- data/source/bzs/rtl/debuglog.h +1 -1
- data/source/bzs/test/tdclphp/transactd_Test.php +183 -37
- data/source/bzs/test/tdclphp/transactd_pool_Test.php +1 -2
- data/source/bzs/test/tdclrb/transactd_spec.rb +183 -39
- data/source/bzs/test/transactdBench/scaling_bench.cpp +3 -3
- data/source/bzs/test/trdclengn/test_trdclengn.cpp +172 -57
- data/source/global/boost/sha1.hpp +223 -0
- data/source/global/tdclatl/ConnectParams.cpp +2 -2
- data/source/global/tdclatl/ConnectParams.h +1 -1
- data/source/global/tdclatl/Database.cpp +18 -0
- data/source/global/tdclatl/Database.h +5 -0
- data/source/global/tdclatl/tdclatl.idl +23 -1
- data/source/linux/linuxTypes.h +2 -0
- metadata +8 -6
- data/bin/common/tdclc_32_2_1.dll +0 -0
- data/bin/common/tdclc_64_2_1.dll +0 -0
- data/source/bzs/db/protocol/tdap/client/memRecordset.cpp +0 -448
- data/source/bzs/db/protocol/tdap/client/memRecordset.h +0 -159
|
@@ -47,7 +47,7 @@ namespace cpt // connection per thread
|
|
|
47
47
|
unsigned int g_connections = 0;
|
|
48
48
|
unsigned int g_waitThread = 0;
|
|
49
49
|
// ---------------------------------------------------------------------------
|
|
50
|
-
//
|
|
50
|
+
// connection
|
|
51
51
|
// ---------------------------------------------------------------------------
|
|
52
52
|
#define READBUF_SIZE 66000
|
|
53
53
|
#define WRITEBUF_SIZE 66000
|
|
@@ -85,9 +85,15 @@ class connection : public iconnection, private boost::noncopyable
|
|
|
85
85
|
m_optionalBuffes.clear();
|
|
86
86
|
vecBuffer vbuf(m_result);
|
|
87
87
|
bzs::netsvc::server::IResultBuffer& buf = vbuf;
|
|
88
|
-
|
|
89
|
-
|
|
88
|
+
int ret = m_module->execute(buf, size, &m_optionalBuffes);
|
|
89
|
+
if (ret == EXECUTE_RESULT_QUIT)
|
|
90
90
|
return;
|
|
91
|
+
else if(ret == EXECUTE_RESULT_ACCESS_DNIED)
|
|
92
|
+
{
|
|
93
|
+
boost::asio::write(m_socket, buffer(&m_result[0], size),
|
|
94
|
+
boost::asio::transfer_all());
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
91
97
|
else
|
|
92
98
|
{
|
|
93
99
|
m_readLen = 0;
|
|
@@ -200,6 +206,7 @@ public:
|
|
|
200
206
|
m_socket.set_option(
|
|
201
207
|
boost::asio::socket_base::send_buffer_size(1024 * 1024 * 10), ec);
|
|
202
208
|
|
|
209
|
+
//send handshake packet
|
|
203
210
|
size_t n = m_module->onAccept(&m_result[0], WRITEBUF_SIZE);
|
|
204
211
|
if (n)
|
|
205
212
|
boost::asio::write(m_socket, buffer(&m_result[0], n),
|
|
@@ -235,7 +242,7 @@ std::vector<connection*> connection::connections;
|
|
|
235
242
|
mutex connection::m_mutex;
|
|
236
243
|
|
|
237
244
|
// ---------------------------------------------------------------------------
|
|
238
|
-
//
|
|
245
|
+
// worker
|
|
239
246
|
// ---------------------------------------------------------------------------
|
|
240
247
|
|
|
241
248
|
class worker : private boost::noncopyable
|
|
@@ -323,7 +330,7 @@ public:
|
|
|
323
330
|
((IAppModuleBuilder*)app)->createSessionModule(
|
|
324
331
|
endpoint, m_connection.get(), SERVER_TYPE_CPT));
|
|
325
332
|
m_connection->setModule(mod);
|
|
326
|
-
if (mod->checkHost(hostCheckName))
|
|
333
|
+
if (mod->checkHost(hostCheckName, NULL, 0))
|
|
327
334
|
{
|
|
328
335
|
m_connection->sendConnectAccept();
|
|
329
336
|
m_connection->start(); // It does not return, unless a
|
|
@@ -372,7 +379,7 @@ std::vector<boost::shared_ptr<boost::thread> > worker::m_threads;
|
|
|
372
379
|
std::vector<worker*> worker::m_workers;
|
|
373
380
|
|
|
374
381
|
// ---------------------------------------------------------------------------
|
|
375
|
-
//
|
|
382
|
+
// listener
|
|
376
383
|
// ---------------------------------------------------------------------------
|
|
377
384
|
|
|
378
385
|
class listener
|
|
@@ -429,13 +436,13 @@ public:
|
|
|
429
436
|
};
|
|
430
437
|
|
|
431
438
|
// ---------------------------------------------------------------------------
|
|
432
|
-
//
|
|
439
|
+
// server
|
|
433
440
|
// ---------------------------------------------------------------------------
|
|
434
441
|
inotifyHandler* server::erh = NULL;
|
|
435
442
|
|
|
436
443
|
/** server
|
|
437
|
-
*
|
|
438
|
-
*
|
|
444
|
+
* If it starts, a server will create the exclusive thread for accpter
|
|
445
|
+
* and will go into an infinite loop.
|
|
439
446
|
*/
|
|
440
447
|
server::server(std::size_t max_connections, const char* hostCheckName)
|
|
441
448
|
: m_timer(m_ios), m_maxConnections(max_connections), m_stopped(false)
|
|
@@ -467,7 +474,7 @@ bool server::checkConnections()
|
|
|
467
474
|
{
|
|
468
475
|
while (connection::connections.size() > m_maxConnections)
|
|
469
476
|
{
|
|
470
|
-
Sleep(100
|
|
477
|
+
Sleep(100);
|
|
471
478
|
if (m_stopped)
|
|
472
479
|
return false;
|
|
473
480
|
}
|
|
@@ -92,14 +92,10 @@ void acceptor::accept(platform_stream& pipe)
|
|
|
92
92
|
m_fd = CreateNamedPipe(pipeName, // pipe name
|
|
93
93
|
PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
|
|
94
94
|
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
|
|
95
|
-
PIPE_UNLIMITED_INSTANCES // max. instances
|
|
96
|
-
,
|
|
97
|
-
BUFSIZE //
|
|
98
|
-
,
|
|
99
|
-
BUFSIZE // input buffer size
|
|
100
|
-
,
|
|
101
|
-
0 // client time-out
|
|
102
|
-
,
|
|
95
|
+
PIPE_UNLIMITED_INSTANCES, // max. instances
|
|
96
|
+
BUFSIZE, // output buffer size
|
|
97
|
+
BUFSIZE, // input buffer size
|
|
98
|
+
0, // client time-out
|
|
103
99
|
&sa); // default security attribute
|
|
104
100
|
if (m_fd == INVALID_HANDLE_VALUE)
|
|
105
101
|
THROW_BZS_ERROR_WITH_MSG(getWindowsErrMsg(GetLastError()));
|
|
@@ -190,9 +186,10 @@ public:
|
|
|
190
186
|
return true;
|
|
191
187
|
DWORD ExitCode;
|
|
192
188
|
if (m_procHandle && GetExitCodeProcess(m_procHandle, &ExitCode))
|
|
193
|
-
|
|
189
|
+
{
|
|
194
190
|
if (STILL_ACTIVE != ExitCode)
|
|
195
191
|
return true;
|
|
192
|
+
}
|
|
196
193
|
if (m_module && m_module->isShutDown())
|
|
197
194
|
return true;
|
|
198
195
|
return false;
|
|
@@ -235,11 +232,13 @@ public:
|
|
|
235
232
|
|
|
236
233
|
bool recv(int checkTimeSpan, IExitCheckHandler* handler)
|
|
237
234
|
{
|
|
238
|
-
DWORD wait;
|
|
235
|
+
DWORD wait = WAIT_TIMEOUT;
|
|
239
236
|
do
|
|
240
237
|
{
|
|
238
|
+
if (wait == WAIT_ABANDONED)
|
|
239
|
+
return false;
|
|
241
240
|
if (m_cancel || (handler && (handler->isExit())))
|
|
242
|
-
return
|
|
241
|
+
return false;
|
|
243
242
|
} while (WAIT_OBJECT_0 !=
|
|
244
243
|
(wait = WaitForSingleObject(m_recv, checkTimeSpan)));
|
|
245
244
|
m_sent = false;
|
|
@@ -341,19 +340,23 @@ class connection : public iconnection, private noncopyable
|
|
|
341
340
|
return;
|
|
342
341
|
bool complete = false;
|
|
343
342
|
m_readLen = *((unsigned int*)m_sharedMem->readBuffer());
|
|
343
|
+
//When readLen = 0 , close connection
|
|
344
344
|
if (m_readLen == 0)
|
|
345
345
|
return;
|
|
346
346
|
m_module->onRead(m_sharedMem->readBuffer(), m_readLen, complete);
|
|
347
347
|
if (complete)
|
|
348
348
|
{
|
|
349
349
|
size_t size = 0;
|
|
350
|
-
|
|
351
|
-
|
|
350
|
+
int ret = m_module->execute(sharedMemBuffer(*m_sharedMem), size, NULL);
|
|
351
|
+
if (ret == EXECUTE_RESULT_QUIT)
|
|
352
352
|
return;
|
|
353
353
|
else
|
|
354
354
|
m_readLen = 0;
|
|
355
355
|
|
|
356
356
|
sentResult = m_comm->send();
|
|
357
|
+
//When named pipe, dissconnect from local client.
|
|
358
|
+
//if (ret == EXECUTE_RESULT_ACCESS_DNIED)
|
|
359
|
+
// return;
|
|
357
360
|
m_module->cleanup();
|
|
358
361
|
}
|
|
359
362
|
}
|
|
@@ -434,10 +437,15 @@ public:
|
|
|
434
437
|
m_exitHandler.reset(new exitCheckHnadler(clinetProcessID));
|
|
435
438
|
if (m_module)
|
|
436
439
|
m_exitHandler->setModule(m_module.get());
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
440
|
+
tmp[0] = 0x00; // signe of handshakable
|
|
441
|
+
memcpy(tmp + 3, &m_shareMemSize, sizeof(unsigned int));// sharemem size
|
|
442
|
+
//asio::write(m_socket, buffer(tmp, 7), e);
|
|
443
|
+
//len = asio::read(m_socket, buffer(buf, 9), e);
|
|
444
|
+
//if (len != 9)
|
|
445
|
+
// THROW_BZS_ERROR_WITH_MSG("handshake error");
|
|
446
|
+
//send handshake packet
|
|
447
|
+
m_module->onAccept(m_sharedMem->writeBuffer(), m_sharedMem->size());
|
|
448
|
+
m_comm->send();
|
|
441
449
|
asio::write(m_socket, buffer(tmp, 7), e);
|
|
442
450
|
run();
|
|
443
451
|
}
|
|
@@ -522,7 +530,6 @@ public:
|
|
|
522
530
|
*/
|
|
523
531
|
static worker* worker::get(const IAppModuleBuilder* app)
|
|
524
532
|
{
|
|
525
|
-
|
|
526
533
|
worker* p = findWaitThread();
|
|
527
534
|
if (p == NULL)
|
|
528
535
|
{
|
|
@@ -565,7 +572,7 @@ public:
|
|
|
565
572
|
((IAppModuleBuilder*)app)->createSessionModule(
|
|
566
573
|
endpoint, m_connection.get(), SERVER_TYPE_CPT));
|
|
567
574
|
m_connection->setModule(mod);
|
|
568
|
-
if (mod->checkHost(hostCheckName))
|
|
575
|
+
if (mod->checkHost(hostCheckName, NULL, 0))
|
|
569
576
|
m_connection->start(); // It does not return, unless a
|
|
570
577
|
// connection is close.
|
|
571
578
|
m_connection.reset();
|
|
@@ -153,6 +153,12 @@ class connection : public boost::enable_shared_from_this<connection>,
|
|
|
153
153
|
|
|
154
154
|
if (ret == EXECUTE_RESULT_QUIT)
|
|
155
155
|
return;
|
|
156
|
+
else if(ret == EXECUTE_RESULT_ACCESS_DNIED)
|
|
157
|
+
{
|
|
158
|
+
boost::asio::write(m_socket, buffer(&m_result[0], size),
|
|
159
|
+
boost::asio::transfer_all());
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
156
162
|
|
|
157
163
|
m_optionalBuffes.insert(m_optionalBuffes.begin(),
|
|
158
164
|
buffer(&m_result[0], size));
|
|
@@ -170,7 +176,6 @@ class connection : public boost::enable_shared_from_this<connection>,
|
|
|
170
176
|
boost::bind(&connection::handle_write,
|
|
171
177
|
shared_from_this(),
|
|
172
178
|
boost::asio::placeholders::error));
|
|
173
|
-
|
|
174
179
|
return;
|
|
175
180
|
}
|
|
176
181
|
|
|
@@ -231,6 +236,7 @@ public:
|
|
|
231
236
|
|
|
232
237
|
void sendConnectAccept()
|
|
233
238
|
{
|
|
239
|
+
//send handshake packet
|
|
234
240
|
size_t n = m_module->onAccept(&m_result[0], WRITEBUF_SIZE);
|
|
235
241
|
if (n)
|
|
236
242
|
boost::asio::write(m_socket, buffer(&m_result[0], n),
|
|
@@ -313,7 +319,7 @@ public:
|
|
|
313
319
|
boost::shared_ptr<IAppModule> mod(m_app->createSessionModule(
|
|
314
320
|
endpoint, m_newConnection.get(), SERVER_TYPE_TPOOL));
|
|
315
321
|
m_newConnection->setModule(mod);
|
|
316
|
-
if (mod->checkHost(m_srv->hostCheckName()))
|
|
322
|
+
if (mod->checkHost(m_srv->hostCheckName(), NULL, 0))
|
|
317
323
|
{
|
|
318
324
|
m_newConnection->sendConnectAccept();
|
|
319
325
|
m_newConnection->start();
|
data/source/bzs/rtl/debuglog.cpp
CHANGED
|
@@ -74,12 +74,26 @@ void debuglog::dump(FILE* fp, const char* p, int size, int limit)
|
|
|
74
74
|
size = std::min<int>(size, limit);
|
|
75
75
|
for (int i = 0; i < size; i += 16)
|
|
76
76
|
{
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
77
|
+
const char* pp = p + i;
|
|
78
|
+
int max = std::min<int>(size - i, 16);
|
|
79
|
+
for (int j = 0; j < max; j++)
|
|
80
|
+
fprintf(fp, "%02X ", *((unsigned char*)(pp + j)));
|
|
81
|
+
|
|
82
|
+
if (max != 16)
|
|
83
|
+
{
|
|
84
|
+
for (int j = 0; j < 16 - max; j++)
|
|
85
|
+
fprintf(fp, " ");
|
|
86
|
+
}
|
|
87
|
+
|
|
80
88
|
fprintf(fp, " ");
|
|
81
|
-
for (int j = 0; j <
|
|
82
|
-
|
|
89
|
+
for (int j = 0; j < max; j++)
|
|
90
|
+
{
|
|
91
|
+
const char* p1 = pp + j;
|
|
92
|
+
if (*p1 >= ' ' && *p1 <= '~')
|
|
93
|
+
fprintf(fp, "%c", *p1);
|
|
94
|
+
else
|
|
95
|
+
fprintf(fp, " ");
|
|
96
|
+
}
|
|
83
97
|
fprintf(fp, "\n");
|
|
84
98
|
}
|
|
85
99
|
fprintf(fp, "\n");
|
|
@@ -91,6 +105,8 @@ void debuglog::writeDump(const char* msg, const char* ptr, int size)
|
|
|
91
105
|
FILE* fp = fileOpen(logfilename, "a+");
|
|
92
106
|
if (fp)
|
|
93
107
|
{
|
|
108
|
+
fputs(dateTime(), fp);
|
|
109
|
+
fputs(" ", fp);
|
|
94
110
|
fputs(msg, fp);
|
|
95
111
|
fputs("\n", fp);
|
|
96
112
|
dump(fp, ptr, size, INT_MAX);
|
data/source/bzs/rtl/debuglog.h
CHANGED
|
@@ -61,7 +61,7 @@ public:
|
|
|
61
61
|
#define DEBUG_WRITELOG(MSG)
|
|
62
62
|
#endif // DEBUG_LOG
|
|
63
63
|
|
|
64
|
-
#if defined(DEBUG_PROFILE) || defined(DEBUG_LOG)
|
|
64
|
+
#if defined(DEBUG_PROFILE) || defined(DEBUG_LOG) || defined(DEBUG_LOG_ERR)
|
|
65
65
|
#define DEBUG_PROFILE_INIT() bzs::rtl::debuglog::get()->init();
|
|
66
66
|
#define DEBUG_PROFILE_DEINIT() bzs::rtl::debuglog::get()->stop();
|
|
67
67
|
#else
|
|
@@ -42,7 +42,32 @@ define("FDI_NAMEW", 2);
|
|
|
42
42
|
define("BULKBUFSIZE", 65535 - 1000);
|
|
43
43
|
define("TEST_COUNT", 20000);
|
|
44
44
|
define("FIVE_PERCENT_OF_TEST_COUNT", TEST_COUNT / 20);
|
|
45
|
-
|
|
45
|
+
|
|
46
|
+
// multi thread test if `php_pthreads` exists.
|
|
47
|
+
if(class_exists('Thread')){
|
|
48
|
+
class SeekLessThanWorker extends Thread
|
|
49
|
+
{
|
|
50
|
+
public function __construct()
|
|
51
|
+
{
|
|
52
|
+
$this->value = -1;
|
|
53
|
+
}
|
|
54
|
+
public function run()
|
|
55
|
+
{
|
|
56
|
+
$dbm = new Bz\pooledDbManager(new Bz\connectParams(URL));
|
|
57
|
+
$tb = $dbm->table('user');
|
|
58
|
+
$tb->setFV(FDI_ID, 300000);
|
|
59
|
+
$tb->seekLessThan(false, Bz\transactd::ROW_LOCK_X);
|
|
60
|
+
$this->value = $tb->getFVint(FDI_ID);
|
|
61
|
+
$tb->unlock();
|
|
62
|
+
$tb->close();
|
|
63
|
+
$dbm->unUse();
|
|
64
|
+
}
|
|
65
|
+
public function getResult()
|
|
66
|
+
{
|
|
67
|
+
return $this->value;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
46
71
|
|
|
47
72
|
class transactdTest extends PHPUnit_Framework_TestCase
|
|
48
73
|
{
|
|
@@ -263,8 +288,9 @@ class transactdTest extends PHPUnit_Framework_TestCase
|
|
|
263
288
|
$this->assertEquals($client_ver->majorVersion, Bz\transactd::CPP_INTERFACE_VER_MAJOR);
|
|
264
289
|
$this->assertEquals($client_ver->minorVersion, Bz\transactd::CPP_INTERFACE_VER_MINOR);
|
|
265
290
|
$this->assertEquals(chr($client_ver->type), 'N');
|
|
266
|
-
$
|
|
267
|
-
$
|
|
291
|
+
$my5x = ($server_ver->majorVersion == 5) && ($server_ver->minorVersion >= 5);
|
|
292
|
+
$maria10 = ($server_ver->majorVersion == 10) && ($server_ver->minorVersion == 0);
|
|
293
|
+
$this->assertTrue($my5x || $maria10);
|
|
268
294
|
$this->assertEquals(chr($server_ver->type), 'M');
|
|
269
295
|
$this->assertEquals($engine_ver->majorVersion, Bz\transactd::TRANSACTD_VER_MAJOR);
|
|
270
296
|
$this->assertEquals($engine_ver->minorVersion, Bz\transactd::TRANSACTD_VER_MINOR);
|
|
@@ -756,6 +782,9 @@ class transactdTest extends PHPUnit_Framework_TestCase
|
|
|
756
782
|
$this->assertEquals($tb->stat(), Bz\transactd::STATUS_NOT_FOUND_TI);
|
|
757
783
|
|
|
758
784
|
// clean up
|
|
785
|
+
$tb2->setFV(FDI_ID, 29999);
|
|
786
|
+
$tb2->seek();
|
|
787
|
+
$this->assertEquals($tb2->stat(), 0);
|
|
759
788
|
$tb2->del();
|
|
760
789
|
$this->assertEquals($tb2->stat(), 0);
|
|
761
790
|
|
|
@@ -784,6 +813,24 @@ class transactdTest extends PHPUnit_Framework_TestCase
|
|
|
784
813
|
$this->assertEquals($tb2->stat(), Bz\transactd::STATUS_LOCK_ERROR);
|
|
785
814
|
|
|
786
815
|
$db->endSnapshot();
|
|
816
|
+
|
|
817
|
+
// gap lock
|
|
818
|
+
$db->beginSnapshot(Bz\transactd::MULTILOCK_NOGAP_SHARE);
|
|
819
|
+
$tb->seekLast(); // id = 30000
|
|
820
|
+
$this->assertEquals($tb->stat(), 0);
|
|
821
|
+
$tb->seekPrev(); // id = 20002
|
|
822
|
+
$this->assertEquals($tb->stat(), 0);
|
|
823
|
+
$tb->seekPrev(); // id = 20001
|
|
824
|
+
$this->assertEquals($tb->stat(), 0);
|
|
825
|
+
|
|
826
|
+
$tb2->setFV(FDI_ID, 20002);
|
|
827
|
+
$tb2->seek(Bz\transactd::ROW_LOCK_X);
|
|
828
|
+
$this->assertEquals($tb2->stat(), Bz\transactd::STATUS_LOCK_ERROR);
|
|
829
|
+
|
|
830
|
+
$tb2->seekLast(Bz\transactd::ROW_LOCK_X);
|
|
831
|
+
$this->assertEquals($tb2->stat(), Bz\transactd::STATUS_LOCK_ERROR);
|
|
832
|
+
|
|
833
|
+
$db->endSnapshot();
|
|
787
834
|
}
|
|
788
835
|
public function testConflict()
|
|
789
836
|
{
|
|
@@ -954,6 +1001,37 @@ class transactdTest extends PHPUnit_Framework_TestCase
|
|
|
954
1001
|
$this->assertEquals($tb->getFVint(FDI_ID), $last2);
|
|
955
1002
|
$db->endTrn();
|
|
956
1003
|
|
|
1004
|
+
// ----------------------------------------------------
|
|
1005
|
+
// Test use shared lock option
|
|
1006
|
+
// ----------------------------------------------------
|
|
1007
|
+
$db->beginTrn(Bz\transactd::MULTILOCK_REPEATABLE_READ);
|
|
1008
|
+
$this->assertEquals(0, $db->stat());
|
|
1009
|
+
|
|
1010
|
+
$db2->beginTrn(Bz\transactd::MULTILOCK_REPEATABLE_READ);
|
|
1011
|
+
$this->assertEquals(0, $db2->stat());
|
|
1012
|
+
|
|
1013
|
+
$tb->seekLast(Bz\transactd::ROW_LOCK_S);
|
|
1014
|
+
$this->assertEquals(0, $tb->stat());
|
|
1015
|
+
$tb2->seekLast(Bz\transactd::ROW_LOCK_S);
|
|
1016
|
+
$this->assertEquals(0, $tb2->stat());
|
|
1017
|
+
|
|
1018
|
+
$tb->seekPrev(); // Lock(X)
|
|
1019
|
+
$this->assertEquals(0, $tb->stat());
|
|
1020
|
+
|
|
1021
|
+
$tb2->seekPrev(Bz\transactd::ROW_LOCK_S);
|
|
1022
|
+
$this->assertEquals(Bz\transactd::STATUS_LOCK_ERROR, $tb2->stat());
|
|
1023
|
+
|
|
1024
|
+
$tb->seekPrev(Bz\transactd::ROW_LOCK_S);
|
|
1025
|
+
$this->assertEquals(0, $tb->stat());
|
|
1026
|
+
$id = $tb->getFVint(FDI_ID);
|
|
1027
|
+
|
|
1028
|
+
$tb2->setFV(FDI_ID, $id);
|
|
1029
|
+
$tb2->seek(Bz\transactd::ROW_LOCK_S);
|
|
1030
|
+
$this->assertEquals(0, $tb2->stat());
|
|
1031
|
+
|
|
1032
|
+
$db2->endTrn();
|
|
1033
|
+
$db->endTrn();
|
|
1034
|
+
|
|
957
1035
|
// ----------------------------------------------------
|
|
958
1036
|
// Test Abort
|
|
959
1037
|
// ----------------------------------------------------
|
|
@@ -1255,6 +1333,9 @@ class transactdTest extends PHPUnit_Framework_TestCase
|
|
|
1255
1333
|
// No match records are unlocked.
|
|
1256
1334
|
$tb2->setFV(FDI_ID, 100);
|
|
1257
1335
|
$tb2->seek(Bz\transactd::ROW_LOCK_X);
|
|
1336
|
+
$this->assertEquals(0, $tb2->stat());
|
|
1337
|
+
$tb2->setFV(FDI_ID, 101);
|
|
1338
|
+
$tb2->seek(Bz\transactd::ROW_LOCK_X);
|
|
1258
1339
|
$this->assertEquals($tb2->stat(), 0);
|
|
1259
1340
|
$tb2->unlock();
|
|
1260
1341
|
$db->endTrn();
|
|
@@ -1318,8 +1399,11 @@ class transactdTest extends PHPUnit_Framework_TestCase
|
|
|
1318
1399
|
$tb2->seekNext(Bz\transactd::ROW_LOCK_X); // lock(X) third, second lock freed
|
|
1319
1400
|
$this->assertEquals($tb2->stat(), 0);
|
|
1320
1401
|
|
|
1321
|
-
$tb->seekNext(); // nobody lock second.
|
|
1322
|
-
|
|
1402
|
+
$tb->seekNext(); // nobody lock second. But REPEATABLE_READ tb2 lock all(no unlock)
|
|
1403
|
+
if ($db->trxIsolationServer() == Bz\transactd::SRV_ISO_REPEATABLE_READ)
|
|
1404
|
+
$this->assertEquals($tb->stat(), Bz\transactd::STATUS_LOCK_ERROR);
|
|
1405
|
+
else
|
|
1406
|
+
$this->assertEquals($tb->stat(), 0);
|
|
1323
1407
|
$tb->seekNext(Bz\transactd::ROW_LOCK_X); // Try lock(X) third
|
|
1324
1408
|
$this->assertEquals($tb->stat(), Bz\transactd::STATUS_LOCK_ERROR);
|
|
1325
1409
|
|
|
@@ -1345,10 +1429,15 @@ class transactdTest extends PHPUnit_Framework_TestCase
|
|
|
1345
1429
|
$tb->setFV(FDI_ID, 21000);
|
|
1346
1430
|
$tb->insert();
|
|
1347
1431
|
$this->assertEquals($tb->stat(), 0);
|
|
1432
|
+
|
|
1433
|
+
//cleanup
|
|
1434
|
+
$tb->setFV(FDI_ID, 21000);
|
|
1435
|
+
$tb->seek();
|
|
1436
|
+
$this->assertEquals($tb->stat(), 0);
|
|
1348
1437
|
$tb->del();
|
|
1349
1438
|
$this->assertEquals($tb->stat(), 0);
|
|
1350
1439
|
|
|
1351
|
-
// ---------
|
|
1440
|
+
// --------- Unlock test ---------------------------
|
|
1352
1441
|
// 1 unlock()
|
|
1353
1442
|
$tb->seekFirst(Bz\transactd::ROW_LOCK_X);
|
|
1354
1443
|
$this->assertEquals($tb->stat(), 0);
|
|
@@ -1404,7 +1493,11 @@ class transactdTest extends PHPUnit_Framework_TestCase
|
|
|
1404
1493
|
$tb2->seekFirst(Bz\transactd::ROW_LOCK_X);
|
|
1405
1494
|
$this->assertEquals($tb2->stat(), 0);
|
|
1406
1495
|
$tb2->unlock();
|
|
1407
|
-
// ---------
|
|
1496
|
+
// --------- End Unlock test -----------------------
|
|
1497
|
+
|
|
1498
|
+
// --------- Invalid lock type test ----------------
|
|
1499
|
+
$tb2->seekFirst(Bz\transactd::ROW_LOCK_S);
|
|
1500
|
+
$this->assertEquals(Bz\transactd::STATUS_INVALID_LOCKTYPE, $tb2->stat());
|
|
1408
1501
|
}
|
|
1409
1502
|
public function testExclusive()
|
|
1410
1503
|
{
|
|
@@ -1423,23 +1516,21 @@ class transactdTest extends PHPUnit_Framework_TestCase
|
|
|
1423
1516
|
$db2->connect(PROTOCOL . HOSTNAME . DBNAME, true);
|
|
1424
1517
|
$this->assertEquals($db2->stat(), 0);
|
|
1425
1518
|
$db2->open(URL, Bz\transactd::TYPE_SCHEMA_BDF);
|
|
1519
|
+
// database open error. Check database::stat()
|
|
1426
1520
|
$this->assertEquals($db2->stat(), Bz\transactd::STATUS_CANNOT_LOCK_TABLE);
|
|
1427
1521
|
$tb->close();
|
|
1428
1522
|
$db->close();
|
|
1429
1523
|
$db2->close();
|
|
1430
1524
|
|
|
1431
1525
|
// ------------------------------------------------------
|
|
1432
|
-
// database
|
|
1526
|
+
// database READ EXCLUSIVE
|
|
1433
1527
|
// ------------------------------------------------------
|
|
1434
|
-
// table mode exclusive
|
|
1435
|
-
$db = new Bz\database();
|
|
1436
1528
|
$db->open(URL, Bz\transactd::TYPE_SCHEMA_BDF, Bz\transactd::TD_OPEN_READONLY_EXCLUSIVE);
|
|
1437
1529
|
$this->assertEquals($db->stat(), 0);
|
|
1438
1530
|
$tb = $db->openTable(TABLENAME, Bz\transactd::TD_OPEN_READONLY_EXCLUSIVE);
|
|
1439
1531
|
$this->assertEquals($db->stat(), 0);
|
|
1440
1532
|
|
|
1441
1533
|
// Read only open
|
|
1442
|
-
$db2 = new Bz\database();
|
|
1443
1534
|
$db2->open(URL, Bz\transactd::TYPE_SCHEMA_BDF);
|
|
1444
1535
|
$this->assertEquals($db2->stat(), 0);
|
|
1445
1536
|
$db2->close();
|
|
@@ -1459,6 +1550,7 @@ class transactdTest extends PHPUnit_Framework_TestCase
|
|
|
1459
1550
|
$db2->open(URL, Bz\transactd::TYPE_SCHEMA_BDF, Bz\transactd::TD_OPEN_READONLY_EXCLUSIVE);
|
|
1460
1551
|
$this->assertEquals($db2->stat(), 0);
|
|
1461
1552
|
$db2->close();
|
|
1553
|
+
$tb->close();
|
|
1462
1554
|
$db->close();
|
|
1463
1555
|
|
|
1464
1556
|
// ------------------------------------------------------
|
|
@@ -1473,10 +1565,10 @@ class transactdTest extends PHPUnit_Framework_TestCase
|
|
|
1473
1565
|
|
|
1474
1566
|
$tb2 = $db->openTable('group', Bz\transactd::TD_OPEN_EXCLUSIVE);
|
|
1475
1567
|
$this->assertEquals($db->stat(), 0);
|
|
1568
|
+
|
|
1476
1569
|
// Check tb2 Exclusive
|
|
1477
1570
|
$tb3 = $db2->openTable('group', Bz\transactd::TD_OPEN_NORMAL);
|
|
1478
1571
|
$this->assertEquals($db2->stat(), Bz\transactd::STATUS_CANNOT_LOCK_TABLE);
|
|
1479
|
-
|
|
1480
1572
|
for ($i = 1; $i < 5; $i++)
|
|
1481
1573
|
{
|
|
1482
1574
|
$tb2->setFV(FDI_ID, $i + 1);
|
|
@@ -1517,10 +1609,10 @@ class transactdTest extends PHPUnit_Framework_TestCase
|
|
|
1517
1609
|
$this->assertEquals($tb->stat(), 0);
|
|
1518
1610
|
|
|
1519
1611
|
// ------------------------------------------------------
|
|
1520
|
-
// Normal and Exclusive
|
|
1612
|
+
// Normal and Exclusive open tables mix transaction
|
|
1521
1613
|
// ------------------------------------------------------
|
|
1522
1614
|
$tb2 = $db->openTable('group', Bz\transactd::TD_OPEN_EXCLUSIVE);
|
|
1523
|
-
$this->assertEquals($
|
|
1615
|
+
$this->assertEquals($db->stat(), 0);
|
|
1524
1616
|
// Check tb2 Exclusive
|
|
1525
1617
|
$tb3 = $db2->openTable('group', Bz\transactd::TD_OPEN_NORMAL);
|
|
1526
1618
|
$this->assertEquals($db2->stat(), Bz\transactd::STATUS_CANNOT_LOCK_TABLE);
|
|
@@ -1586,6 +1678,70 @@ class transactdTest extends PHPUnit_Framework_TestCase
|
|
|
1586
1678
|
$v2 = $tb->getFVstr(FDI_NAME);
|
|
1587
1679
|
$this->assertEquals($v, $v2);
|
|
1588
1680
|
}
|
|
1681
|
+
public function testMissingUpdate()
|
|
1682
|
+
{
|
|
1683
|
+
if(! class_exists('Thread'))
|
|
1684
|
+
{
|
|
1685
|
+
echo(' * class Thread not found! * ');
|
|
1686
|
+
return;
|
|
1687
|
+
}
|
|
1688
|
+
$db = new Bz\database();
|
|
1689
|
+
$tb = $this->openTable($db);
|
|
1690
|
+
Bz\pooledDbManager::setMaxConnections(3);
|
|
1691
|
+
// Lock last record and insert to next of it
|
|
1692
|
+
$w = new SeekLessThanWorker();
|
|
1693
|
+
$tb->setFV(FDI_ID, 300000);
|
|
1694
|
+
$tb->seekLessThan(false, Bz\transactd::ROW_LOCK_X);
|
|
1695
|
+
$this->assertEquals($tb->stat(), 0);
|
|
1696
|
+
if ($tb->stat() == 0)
|
|
1697
|
+
{
|
|
1698
|
+
// Get lock(X) same record in parallel.
|
|
1699
|
+
$w->start();
|
|
1700
|
+
usleep(5000);
|
|
1701
|
+
$v = $tb->getFVint(FDI_ID);
|
|
1702
|
+
$tb->setFV(FDI_ID, ++$v);
|
|
1703
|
+
$tb->insert();
|
|
1704
|
+
$this->assertEquals($tb->stat(), 0);
|
|
1705
|
+
$w->join();
|
|
1706
|
+
$v2 = $w->getResult();
|
|
1707
|
+
|
|
1708
|
+
if ($db->trxIsolationServer() == Bz\transactd::SRV_ISO_REPEATABLE_READ)
|
|
1709
|
+
{ // $tb can not insert because $tb2 got gap lock with SRV_ISO_REPEATABLE_READ.
|
|
1710
|
+
// It is deadlock!
|
|
1711
|
+
$this->assertEquals($tb->stat(), Bz\transactd::STATUS_LOCK_ERROR);
|
|
1712
|
+
}
|
|
1713
|
+
else
|
|
1714
|
+
{ // When SRV_ISO_READ_COMMITED set, $tb2 get lock after $tb->insert.
|
|
1715
|
+
// But this is not READ_COMMITED !
|
|
1716
|
+
$this->assertEquals($tb->stat(), 0);
|
|
1717
|
+
$this->assertEquals($v2, $v - 1);
|
|
1718
|
+
// cleanup
|
|
1719
|
+
$tb->setFV(FDI_ID, $v);
|
|
1720
|
+
$tb->seek();
|
|
1721
|
+
$this->assertEquals($tb->stat(), 0);
|
|
1722
|
+
$tb->del();
|
|
1723
|
+
$this->assertEquals($tb->stat(), 0);
|
|
1724
|
+
}
|
|
1725
|
+
}
|
|
1726
|
+
// Lock last record and delete it
|
|
1727
|
+
$w = new SeekLessThanWorker();
|
|
1728
|
+
$tb->setFV(FDI_ID, 300000);
|
|
1729
|
+
$tb->seekLessThan(false, Bz\transactd::ROW_LOCK_X);
|
|
1730
|
+
$this->assertEquals($tb->stat(), 0);
|
|
1731
|
+
if ($tb->stat() == 0)
|
|
1732
|
+
{
|
|
1733
|
+
// Get lock(X) same record in parallel.
|
|
1734
|
+
$w->start();
|
|
1735
|
+
usleep(5000);
|
|
1736
|
+
$v = $tb->getFVint(FDI_ID);
|
|
1737
|
+
$tb->del();
|
|
1738
|
+
$this->assertEquals($tb->stat(), 0);
|
|
1739
|
+
$w->join();
|
|
1740
|
+
$v2 = $w->getResult();
|
|
1741
|
+
$this->assertNotEquals($v, $v2);
|
|
1742
|
+
}
|
|
1743
|
+
(new Bz\pooledDbManager())->reset(0);
|
|
1744
|
+
}
|
|
1589
1745
|
public function testInsert2()
|
|
1590
1746
|
{
|
|
1591
1747
|
$db = new Bz\database();
|
|
@@ -1611,13 +1767,16 @@ class transactdTest extends PHPUnit_Framework_TestCase
|
|
|
1611
1767
|
$db = new Bz\database();
|
|
1612
1768
|
$tb = $this->openTable($db);
|
|
1613
1769
|
$this->assertNotEquals($tb, NULL);
|
|
1770
|
+
$expected_count = 20003;
|
|
1771
|
+
if(! class_exists('Thread'))
|
|
1772
|
+
$expected_count = $expected_count + 1;
|
|
1614
1773
|
// estimate count
|
|
1615
1774
|
$count = $tb->recordCount(true);
|
|
1616
|
-
$is_valid_count = (abs($count -
|
|
1775
|
+
$is_valid_count = (abs($count - $expected_count) < 5000);
|
|
1617
1776
|
$this->assertTrue($is_valid_count);
|
|
1618
1777
|
if (! $is_valid_count)
|
|
1619
|
-
print("true record count = " .
|
|
1620
|
-
$this->assertEquals($tb->recordCount(false),
|
|
1778
|
+
print("true record count = " . $expected_count . " and estimate recordCount count = " . $count);
|
|
1779
|
+
$this->assertEquals($tb->recordCount(false), $expected_count); // true count
|
|
1621
1780
|
$vv = TEST_COUNT * 3 / 4 + 1;
|
|
1622
1781
|
$tb->clearBuffer();
|
|
1623
1782
|
$tb->setFV(FDI_ID, $vv);
|
|
@@ -1684,7 +1843,7 @@ class transactdTest extends PHPUnit_Framework_TestCase
|
|
|
1684
1843
|
$db2->connect(PROTOCOL . HOSTNAME, true);
|
|
1685
1844
|
$this->assertEquals($db2->stat(), 0);
|
|
1686
1845
|
unset($db2);
|
|
1687
|
-
$db->disconnect(
|
|
1846
|
+
$db->disconnect();
|
|
1688
1847
|
$this->assertEquals($db->stat(), 0);
|
|
1689
1848
|
}
|
|
1690
1849
|
// invalid host name
|
|
@@ -1696,24 +1855,24 @@ class transactdTest extends PHPUnit_Framework_TestCase
|
|
|
1696
1855
|
print('bad host $db->stat() = ' . $db->stat());
|
|
1697
1856
|
$this->createDatabase($db);
|
|
1698
1857
|
$this->createTable($db);
|
|
1699
|
-
$db->
|
|
1858
|
+
$db->close();
|
|
1700
1859
|
$this->assertEquals($db->stat(), 0);
|
|
1701
1860
|
// true database name
|
|
1702
1861
|
$db->connect(PROTOCOL . HOSTNAME . DBNAME);
|
|
1703
1862
|
$this->assertEquals($db->stat(), 0);
|
|
1704
1863
|
if ($db->stat() == 0)
|
|
1705
1864
|
{
|
|
1706
|
-
$db->disconnect(
|
|
1865
|
+
$db->disconnect();
|
|
1707
1866
|
$this->assertEquals($db->stat(), 0);
|
|
1708
1867
|
}
|
|
1709
1868
|
// invalid database name
|
|
1710
1869
|
$this->dropDatabase($db);
|
|
1711
|
-
$db->disconnect(
|
|
1870
|
+
$db->disconnect();
|
|
1712
1871
|
$this->assertEquals($db->stat(), 0);
|
|
1713
1872
|
$db->connect(PROTOCOL . HOSTNAME . DBNAME);
|
|
1714
|
-
$this->assertEquals($db->stat(),
|
|
1715
|
-
$db->disconnect(
|
|
1716
|
-
$this->assertEquals($db->stat(),
|
|
1873
|
+
$this->assertEquals($db->stat(), Bz\transactd::ERROR_NO_DATABASE);
|
|
1874
|
+
$db->disconnect();
|
|
1875
|
+
$this->assertEquals($db->stat(), 1);
|
|
1717
1876
|
}
|
|
1718
1877
|
|
|
1719
1878
|
/* -----------------------------------------------------
|
|
@@ -3242,19 +3401,6 @@ class transactdTest extends PHPUnit_Framework_TestCase
|
|
|
3242
3401
|
// $rs[0];
|
|
3243
3402
|
$this->assertEquals($rs[0]['group_name'], '1 group');
|
|
3244
3403
|
|
|
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
3404
|
// All fields
|
|
3259
3405
|
$rs->clear();
|
|
3260
3406
|
$q->reset()->all();
|
|
@@ -90,7 +90,6 @@ class transactdPoolTest extends PHPUnit_Framework_TestCase
|
|
|
90
90
|
$dbm = new Bz\pooledDbManager($cp);
|
|
91
91
|
$atu = new Bz\ActiveTable($dbm, 'user');
|
|
92
92
|
$q = new Bz\query();
|
|
93
|
-
$rs = new Bz\RecordSet();
|
|
94
93
|
$atu->alias('名前', 'name');
|
|
95
94
|
$q->select('id', 'name', 'group')->where('id', '<=', 15000);
|
|
96
95
|
$rs = $atu->index(0)->keyValue(1)->read($q);
|
|
@@ -105,7 +104,7 @@ class transactdPoolTest extends PHPUnit_Framework_TestCase
|
|
|
105
104
|
public function testMultiThreads()
|
|
106
105
|
{
|
|
107
106
|
if(! class_exists('Thread')){
|
|
108
|
-
echo(' * class
|
|
107
|
+
echo(' * class Thread not found! * ');
|
|
109
108
|
return;
|
|
110
109
|
}
|
|
111
110
|
Bz\pooledDbManager::setMaxConnections(5);
|