Loading backends/sqlite/sqlite.cpp +74 −35 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ #include <iostream> #include <atomic> #include <stdexcept> #include <memory> #include <sqlite3.h> Loading @@ -35,6 +36,25 @@ std::atomic<bool> sqllock(false); namespace { class SqlSpinGuard { public: SqlSpinGuard() { while (sqllock.exchange(true, std::memory_order_acquire)) { } } ~SqlSpinGuard() { sqllock.store(false, std::memory_order_release); } SqlSpinGuard(const SqlSpinGuard &) = delete; SqlSpinGuard &operator=(const SqlSpinGuard &) = delete; }; } // namespace static std::string quoteDoubleIdentifier(const std::string &identifier) { std::string result; result.reserve(identifier.size() + 2); Loading @@ -52,78 +72,97 @@ static std::string quoteDoubleIdentifier(const std::string &identifier) { dbpp::SQLite::SQLite(const char *constr){ while( sqllock.exchange(true, std::memory_order_acquire) ); SqlSpinGuard lock; int status=sqlite3_open(constr,&_dbconn); if (status != SQLITE_OK ){ std::string err = _dbconn ? sqlite3_errmsg(_dbconn) : "sqlite3_open failed"; if (_dbconn) sqlite3_close(_dbconn); throw std::runtime_error(sqlite3_errmsg(_dbconn)); _dbconn = nullptr; throw std::runtime_error(err); } sqllock.store(false); } dbpp::SQLite::~SQLite(){ if (_dbconn) sqlite3_close(_dbconn); } int dbpp::SQLite::exec(const SQL &sql,DBResult &res){ while( sqllock.exchange(true, std::memory_order_acquire) ); char *ssql; ssql=new char[sql.size()]; memcpy(ssql,sql.c_str(),sql.size()); sqlite3_stmt *prep; SqlSpinGuard lock; std::unique_ptr<char[]> ssql(new char[sql.size()]); memcpy(ssql.get(),sql.c_str(),sql.size()); int rcount = 0; res.clear(); DBResult::Data *lastdat; DBResult::Data *lastdat = nullptr; const char *cssql=ssql; const char *cssql = ssql.get(); const char *end = ssql.get() + strlen(ssql.get()); do{ const char *sqlptr = nullptr; int pstate=sqlite3_prepare_v3(_dbconn,cssql,sql.size(),0,&prep,&sqlptr); sqlite3_stmt *prep = nullptr; int pstate = sqlite3_prepare_v3(_dbconn, cssql, -1, 0, &prep, &sqlptr); if (pstate != SQLITE_OK) { throw std::runtime_error(sqlite3_errmsg(_dbconn)); } cssql = sqlptr; if(pstate == SQLITE_ERROR) { std::cerr << sqlite3_errmsg(_dbconn) << std::endl; continue; if(!prep) { if (cssql == nullptr) { throw std::runtime_error("sqlite prepare returned null tail pointer"); } if(!prep) continue; } int pcode; while( ( pcode = sqlite3_step(prep) ) !=SQLITE_DONE ) { if(pcode==SQLITE_ERROR){ delete[] ssql; sqllock.store(false); throw std::runtime_error(sqlite3_errmsg(_dbconn)); while (true) { pcode = sqlite3_step(prep); if (pcode == SQLITE_DONE) { break; } if (pcode == SQLITE_ROW) { int i; for(i=0; i < sqlite3_column_count(prep); ++i){ const unsigned char *txt = sqlite3_column_text(prep, i); const char *val = txt ? reinterpret_cast<const char *>(txt) : ""; int len = sqlite3_column_bytes(prep, i); if(!res.firstRow){ res.firstRow = new DBResult::Data(rcount,i,(const char*)sqlite3_column_text(prep,i),sqlite3_column_bytes(prep,i)); res.firstRow = new DBResult::Data(rcount, i, val, len); lastdat = res.firstRow; } else { lastdat->nextData=new DBResult::Data(rcount,i,(const char*)sqlite3_column_text(prep,i),sqlite3_column_bytes(prep,i)); lastdat->nextData = new DBResult::Data(rcount, i, val, len); lastdat = lastdat->nextData; } } ++rcount; continue; } if (pcode == SQLITE_BUSY || pcode == SQLITE_LOCKED) { sqlite3_finalize(prep); throw std::runtime_error("sqlite database is busy/locked: " + std::string(sqlite3_errmsg(_dbconn))); } if(pcode == SQLITE_ERROR || pcode == SQLITE_MISUSE) { sqlite3_finalize(prep); throw std::runtime_error(sqlite3_errmsg(_dbconn)); } sqlite3_finalize(prep); throw std::runtime_error("sqlite step failed with code " + std::to_string(pcode) + ": " + std::string(sqlite3_errmsg(_dbconn))); } sqlite3_finalize(prep); }while(cssql != ssql+strlen(ssql)); } while (cssql != end); sqllock.store(false); delete[] ssql; return rcount; }; Loading Loading
backends/sqlite/sqlite.cpp +74 −35 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ #include <iostream> #include <atomic> #include <stdexcept> #include <memory> #include <sqlite3.h> Loading @@ -35,6 +36,25 @@ std::atomic<bool> sqllock(false); namespace { class SqlSpinGuard { public: SqlSpinGuard() { while (sqllock.exchange(true, std::memory_order_acquire)) { } } ~SqlSpinGuard() { sqllock.store(false, std::memory_order_release); } SqlSpinGuard(const SqlSpinGuard &) = delete; SqlSpinGuard &operator=(const SqlSpinGuard &) = delete; }; } // namespace static std::string quoteDoubleIdentifier(const std::string &identifier) { std::string result; result.reserve(identifier.size() + 2); Loading @@ -52,78 +72,97 @@ static std::string quoteDoubleIdentifier(const std::string &identifier) { dbpp::SQLite::SQLite(const char *constr){ while( sqllock.exchange(true, std::memory_order_acquire) ); SqlSpinGuard lock; int status=sqlite3_open(constr,&_dbconn); if (status != SQLITE_OK ){ std::string err = _dbconn ? sqlite3_errmsg(_dbconn) : "sqlite3_open failed"; if (_dbconn) sqlite3_close(_dbconn); throw std::runtime_error(sqlite3_errmsg(_dbconn)); _dbconn = nullptr; throw std::runtime_error(err); } sqllock.store(false); } dbpp::SQLite::~SQLite(){ if (_dbconn) sqlite3_close(_dbconn); } int dbpp::SQLite::exec(const SQL &sql,DBResult &res){ while( sqllock.exchange(true, std::memory_order_acquire) ); char *ssql; ssql=new char[sql.size()]; memcpy(ssql,sql.c_str(),sql.size()); sqlite3_stmt *prep; SqlSpinGuard lock; std::unique_ptr<char[]> ssql(new char[sql.size()]); memcpy(ssql.get(),sql.c_str(),sql.size()); int rcount = 0; res.clear(); DBResult::Data *lastdat; DBResult::Data *lastdat = nullptr; const char *cssql=ssql; const char *cssql = ssql.get(); const char *end = ssql.get() + strlen(ssql.get()); do{ const char *sqlptr = nullptr; int pstate=sqlite3_prepare_v3(_dbconn,cssql,sql.size(),0,&prep,&sqlptr); sqlite3_stmt *prep = nullptr; int pstate = sqlite3_prepare_v3(_dbconn, cssql, -1, 0, &prep, &sqlptr); if (pstate != SQLITE_OK) { throw std::runtime_error(sqlite3_errmsg(_dbconn)); } cssql = sqlptr; if(pstate == SQLITE_ERROR) { std::cerr << sqlite3_errmsg(_dbconn) << std::endl; continue; if(!prep) { if (cssql == nullptr) { throw std::runtime_error("sqlite prepare returned null tail pointer"); } if(!prep) continue; } int pcode; while( ( pcode = sqlite3_step(prep) ) !=SQLITE_DONE ) { if(pcode==SQLITE_ERROR){ delete[] ssql; sqllock.store(false); throw std::runtime_error(sqlite3_errmsg(_dbconn)); while (true) { pcode = sqlite3_step(prep); if (pcode == SQLITE_DONE) { break; } if (pcode == SQLITE_ROW) { int i; for(i=0; i < sqlite3_column_count(prep); ++i){ const unsigned char *txt = sqlite3_column_text(prep, i); const char *val = txt ? reinterpret_cast<const char *>(txt) : ""; int len = sqlite3_column_bytes(prep, i); if(!res.firstRow){ res.firstRow = new DBResult::Data(rcount,i,(const char*)sqlite3_column_text(prep,i),sqlite3_column_bytes(prep,i)); res.firstRow = new DBResult::Data(rcount, i, val, len); lastdat = res.firstRow; } else { lastdat->nextData=new DBResult::Data(rcount,i,(const char*)sqlite3_column_text(prep,i),sqlite3_column_bytes(prep,i)); lastdat->nextData = new DBResult::Data(rcount, i, val, len); lastdat = lastdat->nextData; } } ++rcount; continue; } if (pcode == SQLITE_BUSY || pcode == SQLITE_LOCKED) { sqlite3_finalize(prep); throw std::runtime_error("sqlite database is busy/locked: " + std::string(sqlite3_errmsg(_dbconn))); } if(pcode == SQLITE_ERROR || pcode == SQLITE_MISUSE) { sqlite3_finalize(prep); throw std::runtime_error(sqlite3_errmsg(_dbconn)); } sqlite3_finalize(prep); throw std::runtime_error("sqlite step failed with code " + std::to_string(pcode) + ": " + std::string(sqlite3_errmsg(_dbconn))); } sqlite3_finalize(prep); }while(cssql != ssql+strlen(ssql)); } while (cssql != end); sqllock.store(false); delete[] ssql; return rcount; }; Loading