Advertisement
Guest User

Untitled

a guest
Jan 11th, 2017
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.93 KB | None | 0 0
  1. #include "sqlite3.h"
  2. #include <thread>
  3. #include <cstdlib> // for rand()
  4. #include <string>
  5. #include <vector>
  6. #include <iostream>
  7.  
  8. using std::string;
  9. using std::cerr;
  10. using std::endl;
  11.  
  12. const int NUM_THREADS = 3;
  13. const int ROWS_PER_THREAD = 10;
  14.  
  15. #define TEST(x) do{cerr<<(x?"PASSED ":"FAILED ")<< #x <<endl;} while(0)
  16.  
  17. class connection {
  18. public:
  19. explicit connection(string dbpath) : dbpath_(dbpath) { open(); }
  20. virtual ~connection() { sqlite3_close(db_); }
  21. operator sqlite3*() { return db_; }
  22. int exec(string sql) {return sqlite3_exec(db_, sql.c_str(), 0, 0, 0);}
  23. private:
  24. int open() {
  25. int const flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
  26. return sqlite3_open_v2(dbpath_.c_str(), &db_, flags, 0);
  27. }
  28. string const dbpath_;
  29. sqlite3* db_;
  30. };
  31.  
  32. class statement {
  33. public:
  34. statement(sqlite3* db, string sql) : db_(db), sql_(sql) {prepare();}
  35. virtual ~statement() { sqlite3_finalize(stmt_); }
  36. operator sqlite3_stmt*() { return stmt_; }
  37. int column_int(int col) {return sqlite3_column_int(stmt_, col);}
  38. int step() { return sqlite3_step(stmt_); }
  39. int bind(int i, int v) { return sqlite3_bind_int(stmt_, i, v); }
  40. int bind(int i, string v) {
  41. sqlite3_bind_text(stmt_, i, v.c_str(), v.length(), 0);
  42. }
  43. int reset() { sqlite3_reset(stmt_); }
  44. private:
  45. int prepare() {
  46. return sqlite3_prepare_v2(db_, sql_.c_str(), sql_.length(), &stmt_, 0);
  47. }
  48. sqlite3* db_;
  49. string sql_;
  50. sqlite3_stmt* stmt_;
  51. };
  52.  
  53. int get_row_count(connection& conn) {
  54. statement select(conn, "SELECT count(id) FROM test;");
  55. if (SQLITE_ROW == select.step())
  56. return select.column_int(0);
  57. return 0;
  58. }
  59.  
  60. int insert_random(sqlite3* db, string dbpath, int tno) {
  61. statement insert(db, "INSERT INTO test (n,name) VALUES (?,?);");
  62. string name = "Thread " + std::to_string(tno);
  63. for (int i=0; i<ROWS_PER_THREAD; ++i) {
  64. insert.reset();
  65. insert.bind(1, rand());
  66. insert.bind(2, name);
  67. if (insert.step() != SQLITE_DONE) {
  68. cerr << name << ": " << sqlite3_errmsg(db) << endl;
  69. break;
  70. }
  71. }
  72. }
  73.  
  74. int new_connection_insert_random(sqlite3* db, string dbpath, int tno) {
  75. connection conn(dbpath);
  76. return insert_random(conn, dbpath, tno);
  77. }
  78.  
  79. template<class Function>
  80. bool run(Function&& func, string dbpath) {
  81. connection conn(dbpath);
  82. conn.exec("DROP TABLE IF EXISTS test;");
  83. conn.exec("CREATE TABLE test ("
  84. " id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,"
  85. " n INTEGER,"
  86. " name TEXT );");
  87.  
  88. std::vector<std::thread> threads;
  89. for (int i=1; i<=NUM_THREADS; ++i)
  90. threads.emplace_back(func, conn, dbpath, i);
  91. for (auto t=threads.begin(); t!=threads.end(); ++t) t->join();
  92. return (get_row_count(conn) == ROWS_PER_THREAD*NUM_THREADS);
  93. }
  94.  
  95. int main() {
  96. TEST(run(insert_random, "/var/tmp/testdb1.db"));
  97. TEST(run(new_connection_insert_random, "/var/tmp/testdb2.db"));
  98. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement