Thursday, September 3, 2009

Next Stop: SQLite

Actually no, I was thinking about something more ambitious (MySQL). The fact that I have to hunt down other C library files, forces me to consider SQLite. Just drop sqlite3.dll to $LR/bin, sqlite3.h to $LR/include and trim off the 64 bit references in sqlite3.h to make it works.

But simpler solution doesn’t make my life easier, since writing SQLite code (or any db code), in C, that doesn’t leak memory or crashes the db, is fairly hard.

But finally, I get this:
rc = sqlite3_open("test.db", &db);
if (rc) {
lr_output_message("Can't open database: %s", sqlite3_errmsg(db));
sqlite3_close(db);
return -1;
}
exec = "NO RESULT QUERY SUCH AS: DELETE, INSERT”;
isPrepared = 0;
while (!isPrepared) {
rc = sqlite3_prepare(db, exec, -1, &stmt, 0);
if (rc == SQLITE_OK) { //SQLITE_OK == 0
isPrepared = 1;
isExecuted = 0;
while (!isExecuted) {
rc = sqlite3_step(stmt);
/* uncomment this section when exec is a query that return result
while ((rc == SQLITE_ROW)||(rc == SQLITE_BUSY) ) {
if (rc == SQLITE_BUSY ) {
lr_output_message("SQLITE_BUSY - wait for 0.1 seconds");
lr_think_time(0.1); // TODO: tweak the wait time to your need
}
else {
// extract data
rc = sqlite3_step(stmt);
}
}
*/
if (rc == SQLITE_DONE) {
isExecuted = 1;
sqlite3_finalize(stmt);
}
else if (rc == SQLITE_BUSY) { // DB is locked
lr_output_message("SQLITE_BUSY - wait for 0.1 seconds");
lr_think_time(0.1); // TODO: tweak the wait time to your need
}
else { // real bad stuff usually happens here
lr_output_message("Cannot execute step, rc = %d", rc);
lr_output_message("sqlite3_errmsg: %s", sqlite3_errmsg(db));
lr_output_message("sqlite3_extended_errcode, rc = %d", sqlite3_extended_errcode(db));
sqlite3_finalize(stmt);
sqlite3_close(db);
return -1;
}
}
}
else if (rc == SQLITE_BUSY) { // DB is locked
lr_output_message("SQLITE_BUSY - wait for 0.1 seconds");
lr_think_time(0.1); // TODO: tweak the wait time to your need
}
else { // real bad stuff usually happens here
lr_output_message("Could not prepare statement, rc=%d", rc);
lr_output_message("sqlite3_errmsg: %s", sqlite3_errmsg(db));
lr_output_message("sqlite3_extended_errcode, rc = %d", sqlite3_extended_errcode(db));
sqlite3_close(db);
return -1;
}
}
sqlite3_close(db);
Functionally the script works, at 50 virtual users, each running 20 seconds transactions, even the GetUniqueUserName transaction is fairly fast:
  • 75% of population: 0.269 +/- 0.731
  • 90Percentile: 0.655
But, it doesn’t work at 60 virtual users, it also locks the controller. Not good, need to look into MySQL solution.

No comments: