#include "acl_cpp/lib_acl.hpp" #include #include const char* CREATE_TBL = "create table tbl_test\r\n" "(key varchar(128) not null,\r\n" " value varchar(128) not null,\r\n" " primary key(key))\r\n"; class dbthread : public acl::thread { public: dbthread(const char* dbpath, const char* action, int max, acl::atomic_long& count) : dbpath_(dbpath), action_(action), max_(max), count_(count) {} ~dbthread(void) {} private: acl::string dbpath_; acl::string action_; int max_; acl::atomic_long& count_; void* run(void) { acl::db_sqlite db(dbpath_, "gbk"); if (db.open() == false) { printf("open %s error\r\n", dbpath_.c_str()); return NULL; } if (tbl_create(db, "tbl_test") == false) { return NULL; } int ret; if (action_ == "add") { ret = dbadd(db, max_); } else if (action_ == "get") { ret = dbget(db, max_); } else if (action_ == "update") { ret = dbupdate(db, max_); } else if (action_ == "del") { ret = dbdel(db, max_); } else { printf("unknown action: %s\r\n", action_.c_str()); return NULL; } printf("db-%s: %d\r\n", action_.c_str(), ret); if (ret > 0) { count_ += ret; } return NULL; } int dbadd(acl::db_handle& db, int max) { acl::string sql; assert(db.begin_transaction()); for (int i = 0; i < max; i++) { sql.format("insert into tbl_test('key', 'value')" " values('key-%d', 'value-%d')", i, i); if (db.sql_update(sql) == false) { printf("sql_update: |%s| error\r\n", sql.c_str()); return -1; } if (i > 0 && i % 1000 == 0) { assert(db.commit()); assert(db.begin_transaction()); } } assert(db.commit()); return max; } int dbget(acl::db_handle& db, int max) { acl::string sql, key, value; int i; for (i = 0; i < max; i++) { key.format("key-%d", i); sql.format("select value from tbl_test" " where key='%s'", key.c_str()); if (db.sql_select(sql) == false) { printf("sql_select: |%s| error\r\n", sql.c_str()); return -1; } if (db.length() == 0) { break; } db.free_result(); } return i; } int dbupdate(acl::db_handle& db, int max) { acl::string sql, key, value; for (int i = 0; i < max; i++) { key.format("key-%d", i); value.format("value-%d-%d", i, i); sql.format("update tbl_test set value = '%s'" " where key='%s'", value.c_str(), key.c_str()); if (db.sql_update(sql) == false) { printf("sql_update: |%s| error\r\n", sql.c_str()); return -1; } } return max; } int dbdel(acl::db_handle& db, int max) { acl::string sql, key; int n = 0; for (int i = 0; i < max; i++) { key.format("key-%d", i); sql.format("delete from tbl_test where key='%s'", key.c_str()); if (db.sql_update(sql) == false) { printf("sql_update: |%s| error\r\n", sql.c_str()); return -1; } n += db.affect_count(); } return n; } bool tbl_create(acl::db_handle& db, const char* tbl_name) { if (db.tbl_exists(tbl_name)) { return true; } if (db.sql_update(CREATE_TBL) == false) { printf("create table failed\r\n"); return false; } return true; } }; static void usage(const char* procname) { printf("usage: %s -h[help]\r\n" " -s listen_addr[default: 127.0.0.1:7343\r\n" " -n max[default: 1000]\r\n" " -c nthreads[default: 1]\r\n" " -p dbpath[default: .]\r\n" " -l libpath[default: libsqlite3.so]\r\n" " -a action[default: get, update|add|get|del\r\n" , procname); } int main(int argc, char* argv[]) { int nthreads = 1, max = 1000, ch; acl::string dbpath = "./var", libpath = "./libsqlite3.so"; acl::string action = "get"; acl::string addr = "127.0.0.1:7343"; while ((ch = getopt(argc, argv, "hn:c:p:l:s:a:")) > 0) { switch (ch) { case 'h': usage(argv[0]); return 0; case 'n': max = atoi(optarg); break; case 'c': nthreads = atoi(optarg); break; case 'p': dbpath = optarg; break; case 'l': libpath = optarg; break; case 's': addr = optarg; break; case 'a': action = optarg; break; default: break; } } if (access(libpath.c_str(), R_OK) == -1) { printf("access %s failed %s\r\n", libpath.c_str(), acl::last_serror()); return 1; } acl::log::stdout_open(true); acl::db_handle::set_loadpath(libpath); acl::atomic_long success; std::vector threads; for (int i = 0; i < nthreads; i++) { acl::string path; path << dbpath << "/" << "db" << i << ".db"; acl::thread* thr = new dbthread(path, action, max, success); threads.push_back(thr); thr->start(); } for (std::vector::iterator it = threads.begin(); it != threads.end(); ++it) { (*it)->wait(); delete *it; } printf("All over, nthreads=%d, total=%d, success=%lld\r\n", nthreads, nthreads * max, success.value()); return 0; }