8 #include <botan/sqlite3.h>
9 #include <botan/exceptn.h>
16 int rc = ::sqlite3_open(db_filename.c_str(), &m_db);
20 const std::string err_msg = ::sqlite3_errmsg(m_db);
21 ::sqlite3_close(m_db);
30 ::sqlite3_close(m_db);
36 return std::make_shared<Sqlite3_Statement>(m_db, base_sql);
41 auto stmt =
new_statement(
"select count(*) from " + table_name);
44 return stmt->get_size_t(0);
46 throw SQL_DB_Error(
"Querying size of table " + table_name +
" failed");
51 char* errmsg =
nullptr;
52 int rc = ::sqlite3_exec(m_db, table_schema.c_str(),
nullptr,
nullptr, &errmsg);
56 const std::string err_msg = errmsg;
57 ::sqlite3_free(errmsg);
58 ::sqlite3_close(m_db);
60 throw SQL_DB_Error(
"sqlite3_exec for table failed - " + err_msg);
64 Sqlite3_Database::Sqlite3_Statement::Sqlite3_Statement(sqlite3* db,
const std::string& base_sql)
66 int rc = ::sqlite3_prepare_v2(db, base_sql.c_str(), -1, &m_stmt,
nullptr);
69 throw SQL_DB_Error(
"sqlite3_prepare failed " + base_sql +
73 void Sqlite3_Database::Sqlite3_Statement::bind(
int column,
const std::string& val)
75 int rc = ::sqlite3_bind_text(m_stmt, column, val.c_str(), -1, SQLITE_TRANSIENT);
77 throw SQL_DB_Error(
"sqlite3_bind_text failed, code " +
std::to_string(rc));
80 void Sqlite3_Database::Sqlite3_Statement::bind(
int column,
size_t val)
82 if(val != static_cast<size_t>(static_cast<int>(val)))
83 throw SQL_DB_Error(
"sqlite3 cannot store " +
std::to_string(val) +
" without truncation");
84 int rc = ::sqlite3_bind_int(m_stmt, column, val);
86 throw SQL_DB_Error(
"sqlite3_bind_int failed, code " +
std::to_string(rc));
89 void Sqlite3_Database::Sqlite3_Statement::bind(
int column, std::chrono::system_clock::time_point time)
91 const int timeval = std::chrono::duration_cast<std::chrono::seconds>(time.time_since_epoch()).count();
92 bind(column, timeval);
95 void Sqlite3_Database::Sqlite3_Statement::bind(
int column,
const std::vector<uint8_t>& val)
97 int rc = ::sqlite3_bind_blob(m_stmt, column, val.data(), val.size(), SQLITE_TRANSIENT);
99 throw SQL_DB_Error(
"sqlite3_bind_text failed, code " +
std::to_string(rc));
102 void Sqlite3_Database::Sqlite3_Statement::bind(
int column,
const uint8_t* p,
size_t len)
104 int rc = ::sqlite3_bind_blob(m_stmt, column, p, len, SQLITE_TRANSIENT);
106 throw SQL_DB_Error(
"sqlite3_bind_text failed, code " +
std::to_string(rc));
109 std::pair<const uint8_t*, size_t> Sqlite3_Database::Sqlite3_Statement::get_blob(
int column)
111 BOTAN_ASSERT(::sqlite3_column_type(m_stmt, 0) == SQLITE_BLOB,
112 "Return value is a blob");
114 const void* session_blob = ::sqlite3_column_blob(m_stmt, column);
115 const int session_blob_size = ::sqlite3_column_bytes(m_stmt, column);
117 BOTAN_ASSERT(session_blob_size >= 0,
"Blob size is non-negative");
119 return std::make_pair(static_cast<const uint8_t*>(session_blob),
120 static_cast<size_t>(session_blob_size));
123 size_t Sqlite3_Database::Sqlite3_Statement::get_size_t(
int column)
125 BOTAN_ASSERT(::sqlite3_column_type(m_stmt, column) == SQLITE_INTEGER,
126 "Return count is an integer");
128 const int sessions_int = ::sqlite3_column_int(m_stmt, column);
130 BOTAN_ASSERT(sessions_int >= 0,
"Expected size_t is non-negative");
132 return static_cast<size_t>(sessions_int);
135 size_t Sqlite3_Database::Sqlite3_Statement::spin()
146 bool Sqlite3_Database::Sqlite3_Statement::step()
148 return (::sqlite3_step(m_stmt) == SQLITE_ROW);
151 Sqlite3_Database::Sqlite3_Statement::~Sqlite3_Statement()
153 ::sqlite3_finalize(m_stmt);
std::string to_string(const BER_Object &obj)
#define BOTAN_ASSERT(expr, assertion_made)
void create_table(const std::string &table_schema) override
Sqlite3_Database(const std::string &file)
std::shared_ptr< Statement > new_statement(const std::string &sql) const override
size_t row_count(const std::string &table_name) override