class SSqlException
{
public:
- SSqlException(const string &reason) : d_reason(reason)
+ SSqlException(const string& reason) :
+ d_reason(reason)
{
}
{
return d_reason;
}
+
private:
string d_reason;
};
typedef vector<string> row_t;
typedef vector<row_t> result_t;
- virtual SSqlStatement* bind(const string& name, bool value)=0;
- virtual SSqlStatement* bind(const string& name, int value)=0;
- virtual SSqlStatement* bind(const string& name, uint32_t value)=0;
- virtual SSqlStatement* bind(const string& name, long value)=0;
- virtual SSqlStatement* bind(const string& name, unsigned long value)=0;
- virtual SSqlStatement* bind(const string& name, long long value)=0;;
- virtual SSqlStatement* bind(const string& name, unsigned long long value)=0;
- virtual SSqlStatement* bind(const string& name, const std::string& value)=0;
- SSqlStatement* bind(const string& name, const DNSName& value) {
+ virtual SSqlStatement* bind(const string& name, bool value) = 0;
+ virtual SSqlStatement* bind(const string& name, int value) = 0;
+ virtual SSqlStatement* bind(const string& name, uint32_t value) = 0;
+ virtual SSqlStatement* bind(const string& name, long value) = 0;
+ virtual SSqlStatement* bind(const string& name, unsigned long value) = 0;
+ virtual SSqlStatement* bind(const string& name, long long value) = 0;
+ ;
+ virtual SSqlStatement* bind(const string& name, unsigned long long value) = 0;
+ virtual SSqlStatement* bind(const string& name, const std::string& value) = 0;
+ SSqlStatement* bind(const string& name, const DNSName& value)
+ {
if (!value.empty()) {
return bind(name, value.makeLowerCase().toStringRootDot());
}
return bind(name, string(""));
}
- virtual SSqlStatement* bindNull(const string& name)=0;
- virtual SSqlStatement* execute()=0;;
- virtual bool hasNextRow()=0;
- virtual SSqlStatement* nextRow(row_t& row)=0;
- virtual SSqlStatement* getResult(result_t& result)=0;
- virtual SSqlStatement* reset()=0;
- virtual const std::string& getQuery()=0;
+ virtual SSqlStatement* bindNull(const string& name) = 0;
+ virtual SSqlStatement* execute() = 0;
+ ;
+ virtual bool hasNextRow() = 0;
+ virtual SSqlStatement* nextRow(row_t& row) = 0;
+ virtual SSqlStatement* getResult(result_t& result) = 0;
+ virtual SSqlStatement* reset() = 0;
+ virtual const std::string& getQuery() = 0;
virtual ~SSqlStatement();
};
class SSql
{
public:
- virtual SSqlException sPerrorException(const string &reason)=0;
- virtual std::unique_ptr<SSqlStatement> prepare(const string& query, int nparams)=0;
- virtual void execute(const string& query)=0;
- virtual void startTransaction()=0;
- virtual void rollback()=0;
- virtual void commit()=0;
- virtual void setLog(bool /* state */){}
+ virtual SSqlException sPerrorException(const string& reason) = 0;
+ virtual std::unique_ptr<SSqlStatement> prepare(const string& query, int nparams) = 0;
+ virtual void execute(const string& query) = 0;
+ virtual void startTransaction() = 0;
+ virtual void rollback() = 0;
+ virtual void commit() = 0;
+ virtual void setLog(bool /* state */) {}
virtual bool isConnectionUsable()
{
return true;
}
- virtual void reconnect() {};
+ virtual void reconnect(){};
virtual ~SSql(){};
};
* copied from sqlite 3.3.6 // cmouse
*/
#if SQLITE_VERSION_NUMBER < 3003009
-static int pdns_sqlite3_clear_bindings(sqlite3_stmt *pStmt){
+static int pdns_sqlite3_clear_bindings(sqlite3_stmt* pStmt)
+{
int i;
int rc = SQLITE_OK;
- for(i=1; rc==SQLITE_OK && i<=sqlite3_bind_parameter_count(pStmt); i++){
+ for (i = 1; rc == SQLITE_OK && i <= sqlite3_bind_parameter_count(pStmt); i++) {
rc = sqlite3_bind_null(pStmt, i);
}
return rc;
}
#endif
-static string SSQLite3ErrorString(sqlite3 *db)
+static string SSQLite3ErrorString(sqlite3* db)
{
- return string(sqlite3_errmsg(db)+string(" (")+std::to_string(sqlite3_extended_errcode(db))+string(")"));
+ return string(sqlite3_errmsg(db) + string(" (") + std::to_string(sqlite3_extended_errcode(db)) + string(")"));
}
-class SSQLite3Statement: public SSqlStatement
+class SSQLite3Statement : public SSqlStatement
{
public:
- SSQLite3Statement(SSQLite3 *db, bool dolog, const string& query) :
+ SSQLite3Statement(SSQLite3* db, bool dolog, const string& query) :
d_query(query),
d_db(db),
d_dolog(dolog)
{
}
- int name2idx(const string& name) {
- string zName = string(":")+name;
+ int name2idx(const string& name)
+ {
+ string zName = string(":") + name;
prepareStatement();
return sqlite3_bind_parameter_index(d_stmt, zName.c_str());
// XXX: support @ and $?
}
- SSqlStatement* bind(const string& name, bool value) { int idx = name2idx(name); if (idx>0) { sqlite3_bind_int(d_stmt, idx, value ? 1 : 0); }; return this; }
- SSqlStatement* bind(const string& name, int value) { int idx = name2idx(name); if (idx>0) { sqlite3_bind_int(d_stmt, idx, value); }; return this; }
- SSqlStatement* bind(const string& name, uint32_t value) { int idx = name2idx(name); if (idx>0) { sqlite3_bind_int64(d_stmt, idx, value); }; return this; }
- SSqlStatement* bind(const string& name, long value) { int idx = name2idx(name); if (idx>0) { sqlite3_bind_int64(d_stmt, idx, value); }; return this; }
- SSqlStatement* bind(const string& name, unsigned long value) { int idx = name2idx(name); if (idx>0) { sqlite3_bind_int64(d_stmt, idx, value); }; return this; }
- SSqlStatement* bind(const string& name, long long value) { int idx = name2idx(name); if (idx>0) { sqlite3_bind_int64(d_stmt, idx, value); }; return this; };
- SSqlStatement* bind(const string& name, unsigned long long value) { int idx = name2idx(name); if (idx>0) { sqlite3_bind_int64(d_stmt, idx, value); }; return this; }
- SSqlStatement* bind(const string& name, const std::string& value) { int idx = name2idx(name); if (idx>0) { sqlite3_bind_text(d_stmt, idx, value.c_str(), value.size(), SQLITE_TRANSIENT); }; return this; }
- SSqlStatement* bindNull(const string& name) { int idx = name2idx(name); if (idx>0) { sqlite3_bind_null(d_stmt, idx); }; return this; }
+ SSqlStatement* bind(const string& name, bool value)
+ {
+ int idx = name2idx(name);
+ if (idx > 0) {
+ sqlite3_bind_int(d_stmt, idx, value ? 1 : 0);
+ };
+ return this;
+ }
+ SSqlStatement* bind(const string& name, int value)
+ {
+ int idx = name2idx(name);
+ if (idx > 0) {
+ sqlite3_bind_int(d_stmt, idx, value);
+ };
+ return this;
+ }
+ SSqlStatement* bind(const string& name, uint32_t value)
+ {
+ int idx = name2idx(name);
+ if (idx > 0) {
+ sqlite3_bind_int64(d_stmt, idx, value);
+ };
+ return this;
+ }
+ SSqlStatement* bind(const string& name, long value)
+ {
+ int idx = name2idx(name);
+ if (idx > 0) {
+ sqlite3_bind_int64(d_stmt, idx, value);
+ };
+ return this;
+ }
+ SSqlStatement* bind(const string& name, unsigned long value)
+ {
+ int idx = name2idx(name);
+ if (idx > 0) {
+ sqlite3_bind_int64(d_stmt, idx, value);
+ };
+ return this;
+ }
+ SSqlStatement* bind(const string& name, long long value)
+ {
+ int idx = name2idx(name);
+ if (idx > 0) {
+ sqlite3_bind_int64(d_stmt, idx, value);
+ };
+ return this;
+ };
+ SSqlStatement* bind(const string& name, unsigned long long value)
+ {
+ int idx = name2idx(name);
+ if (idx > 0) {
+ sqlite3_bind_int64(d_stmt, idx, value);
+ };
+ return this;
+ }
+ SSqlStatement* bind(const string& name, const std::string& value)
+ {
+ int idx = name2idx(name);
+ if (idx > 0) {
+ sqlite3_bind_text(d_stmt, idx, value.c_str(), value.size(), SQLITE_TRANSIENT);
+ };
+ return this;
+ }
+ SSqlStatement* bindNull(const string& name)
+ {
+ int idx = name2idx(name);
+ if (idx > 0) {
+ sqlite3_bind_null(d_stmt, idx);
+ };
+ return this;
+ }
- SSqlStatement* execute() {
+ SSqlStatement* execute()
+ {
prepareStatement();
if (d_dolog) {
- g_log<<Logger::Warning<< "Query "<<((long)(void*)this)<<": " << d_query << endl;
+ g_log << Logger::Warning << "Query " << ((long)(void*)this) << ": " << d_query << endl;
d_dtime.set();
}
int attempts = d_db->inTransaction(); // try only once
- while(attempts < 2 && (d_rc = sqlite3_step(d_stmt)) == SQLITE_BUSY) attempts++;
+ while (attempts < 2 && (d_rc = sqlite3_step(d_stmt)) == SQLITE_BUSY)
+ attempts++;
if (d_rc != SQLITE_ROW && d_rc != SQLITE_DONE) {
// failed.
releaseStatement();
if (d_rc == SQLITE_CANTOPEN)
- throw SSqlException(string("CANTOPEN error in sqlite3, often caused by unwritable sqlite3 db *directory*: ")+SSQLite3ErrorString(d_db->db()));
- throw SSqlException(string("Error while retrieving SQLite query results: ")+SSQLite3ErrorString(d_db->db()));
+ throw SSqlException(string("CANTOPEN error in sqlite3, often caused by unwritable sqlite3 db *directory*: ") + SSQLite3ErrorString(d_db->db()));
+ throw SSqlException(string("Error while retrieving SQLite query results: ") + SSQLite3ErrorString(d_db->db()));
}
- if(d_dolog)
- g_log<<Logger::Warning<< "Query "<<((long)(void*)this)<<": "<<d_dtime.udiffNoReset()<<" us to execute"<<endl;
+ if (d_dolog)
+ g_log << Logger::Warning << "Query " << ((long)(void*)this) << ": " << d_dtime.udiffNoReset() << " us to execute" << endl;
return this;
}
- bool hasNextRow() {
- if(d_dolog && d_rc != SQLITE_ROW) {
- g_log<<Logger::Warning<< "Query "<<((long)(void*)this)<<": "<<d_dtime.udiffNoReset()<<" us total to last row"<<endl;
+ bool hasNextRow()
+ {
+ if (d_dolog && d_rc != SQLITE_ROW) {
+ g_log << Logger::Warning << "Query " << ((long)(void*)this) << ": " << d_dtime.udiffNoReset() << " us total to last row" << endl;
}
return d_rc == SQLITE_ROW;
}
- SSqlStatement* nextRow(row_t& row) {
+ SSqlStatement* nextRow(row_t& row)
+ {
row.clear();
int numCols = sqlite3_column_count(d_stmt);
row.reserve(numCols); // preallocate memory
// Another row received, process it.
- for ( int i=0; i<numCols; i++)
- {
- if (sqlite3_column_type(d_stmt,i) == SQLITE_NULL) {
+ for (int i = 0; i < numCols; i++) {
+ if (sqlite3_column_type(d_stmt, i) == SQLITE_NULL) {
row.emplace_back("");
- } else {
- const char *pData = (const char*) sqlite3_column_text(d_stmt, i);
+ }
+ else {
+ const char* pData = (const char*)sqlite3_column_text(d_stmt, i);
row.emplace_back(pData, sqlite3_column_bytes(d_stmt, i));
}
}
return this;
}
- SSqlStatement* getResult(result_t& result) {
+ SSqlStatement* getResult(result_t& result)
+ {
result.clear();
- while(hasNextRow()) {
+ while (hasNextRow()) {
row_t row;
nextRow(row);
result.push_back(std::move(row));
return this;
}
- SSqlStatement* reset() {
+ SSqlStatement* reset()
+ {
sqlite3_reset(d_stmt);
#if SQLITE_VERSION_NUMBER >= 3003009
sqlite3_clear_bindings(d_stmt);
return this;
}
- ~SSQLite3Statement() {
+ ~SSQLite3Statement()
+ {
// deallocate if necessary
releaseStatement();
}
const string& getQuery() { return d_query; };
+
private:
string d_query;
DTime d_dtime;
bool d_dolog;
bool d_prepared{false};
- void prepareStatement() {
- const char *pTail;
+ void prepareStatement()
+ {
+ const char* pTail;
- if (d_prepared) return;
+ if (d_prepared)
+ return;
#if SQLITE_VERSION_NUMBER >= 3003009
- if (sqlite3_prepare_v2(d_db->db(), d_query.c_str(), -1, &d_stmt, &pTail ) != SQLITE_OK)
+ if (sqlite3_prepare_v2(d_db->db(), d_query.c_str(), -1, &d_stmt, &pTail) != SQLITE_OK)
#else
- if (sqlite3_prepare(d_db->db(), d_query.c_str(), -1, &d_stmt, &pTail ) != SQLITE_OK)
+ if (sqlite3_prepare(d_db->db(), d_query.c_str(), -1, &d_stmt, &pTail) != SQLITE_OK)
#endif
{
releaseStatement();
- throw SSqlException(string("Unable to compile SQLite statement : '")+d_query+"': "+SSQLite3ErrorString(d_db->db()));
+ throw SSqlException(string("Unable to compile SQLite statement : '") + d_query + "': " + SSQLite3ErrorString(d_db->db()));
}
- if (pTail && strlen(pTail)>0)
- g_log<<Logger::Warning<<"Sqlite3 command partially processed. Unprocessed part: "<<pTail<<endl;
+ if (pTail && strlen(pTail) > 0)
+ g_log << Logger::Warning << "Sqlite3 command partially processed. Unprocessed part: " << pTail << endl;
d_prepared = true;
}
- void releaseStatement() {
+ void releaseStatement()
+ {
if (d_stmt)
sqlite3_finalize(d_stmt);
d_stmt = nullptr;
};
// Constructor.
-SSQLite3::SSQLite3( const std::string & database, const std::string & journalmode, bool creat )
+SSQLite3::SSQLite3(const std::string& database, const std::string& journalmode, bool creat)
{
- if (access( database.c_str(), F_OK ) == -1){
+ if (access(database.c_str(), F_OK) == -1) {
if (!creat)
- throw sPerrorException( "SQLite database '"+database+"' does not exist yet" );
- } else {
+ throw sPerrorException("SQLite database '" + database + "' does not exist yet");
+ }
+ else {
if (creat)
- throw sPerrorException( "SQLite database '"+database+"' already exists" );
+ throw sPerrorException("SQLite database '" + database + "' already exists");
}
- if ( sqlite3_open( database.c_str(), &m_pDB)!=SQLITE_OK )
- throw sPerrorException( "Could not connect to the SQLite database '" + database + "'" );
+ if (sqlite3_open(database.c_str(), &m_pDB) != SQLITE_OK)
+ throw sPerrorException("Could not connect to the SQLite database '" + database + "'");
m_dolog = 0;
m_in_transaction = false;
sqlite3_busy_handler(m_pDB, busyHandler, 0);
- if(journalmode.length())
- execute("PRAGMA journal_mode="+journalmode);
+ if (journalmode.length())
+ execute("PRAGMA journal_mode=" + journalmode);
}
void SSQLite3::setLog(bool state)
{
- m_dolog=state;
+ m_dolog = state;
}
// Destructor.
SSQLite3::~SSQLite3()
{
int ret;
- for(int n = 0; ; ++n) {
- if((ret =sqlite3_close( m_pDB )) != SQLITE_OK) {
- if(n || ret != SQLITE_BUSY) { // if we have SQLITE_BUSY, and a working m_Pstmt, try finalize
- cerr<<"Unable to close down sqlite connection: "<<ret<<endl;
+ for (int n = 0;; ++n) {
+ if ((ret = sqlite3_close(m_pDB)) != SQLITE_OK) {
+ if (n || ret != SQLITE_BUSY) { // if we have SQLITE_BUSY, and a working m_Pstmt, try finalize
+ cerr << "Unable to close down sqlite connection: " << ret << endl;
abort();
}
}
}
}
-std::unique_ptr<SSqlStatement> SSQLite3::prepare(const string& query, int nparams __attribute__((unused))) {
+std::unique_ptr<SSqlStatement> SSQLite3::prepare(const string& query, int nparams __attribute__((unused)))
+{
return std::make_unique<SSQLite3Statement>(this, m_dolog, query);
}
-void SSQLite3::execute(const string& query) {
- char *errmsg;
+void SSQLite3::execute(const string& query)
+{
+ char* errmsg;
std::string errstr1;
int rc = sqlite3_exec(m_pDB, query.c_str(), nullptr, nullptr, &errmsg);
if (rc != SQLITE_OK) {
if (rc == SQLITE_BUSY) {
if (m_in_transaction) {
throw SSqlException("Failed to execute query: " + errstr1);
- } else {
+ }
+ else {
rc = sqlite3_exec(m_pDB, query.c_str(), NULL, NULL, &errmsg);
std::string errstr2;
- if (rc != SQLITE_OK) {
+ if (rc != SQLITE_OK) {
errstr2 = errmsg;
sqlite3_free(errmsg);
throw SSqlException("Failed to execute query: " + errstr2);
}
}
- } else if (rc != SQLITE_OK) {
+ }
+ else if (rc != SQLITE_OK) {
throw SSqlException("Failed to execute query: " + errstr1);
}
}
return 1;
}
-void SSQLite3::startTransaction() {
+void SSQLite3::startTransaction()
+{
execute("begin");
m_in_transaction = true;
}
-void SSQLite3::rollback() {
+void SSQLite3::rollback()
+{
execute("rollback");
m_in_transaction = false;
}
-void SSQLite3::commit() {
+void SSQLite3::commit()
+{
execute("commit");
m_in_transaction = false;
}
// Constructs a SSqlException object.
-SSqlException SSQLite3::sPerrorException( const std::string & reason )
+SSqlException SSQLite3::sPerrorException(const std::string& reason)
{
- return SSqlException( reason );
+ return SSqlException(reason);
}