22            init(sqlite_db, query);
 
 
   29        SqliteStmt(sqlite3 *sqlite_db, 
const std::string &query) {
 
   30            init(sqlite_db, query);
 
 
   44        void init(sqlite3 *sqlite_db, 
const char *query) {
 
   47                err = sqlite3_prepare_v2(sqlite_db, query, -1, &
m_stmt, 
nullptr);
 
   48                if (err == SQLITE_BUSY) {
 
   51                if (err != SQLITE_OK) {
 
   52                    std::string err_msg = 
"Failed to prepare SQL statement: ";
 
   53                    err_msg += std::string(query);
 
   54                    err_msg += 
". Error code: ";
 
   55                    err_msg += std::to_string(err);
 
   58            } 
while (err == SQLITE_BUSY);
 
 
   65        void init(sqlite3 *sqlite_db, 
const std::string &query) {
 
   66            init(sqlite_db, query.c_str());
 
 
   78            const int err = sqlite3_reset(
m_stmt);
 
   79            if (err == SQLITE_OK) 
return;
 
   80            throw sqlite_exception(
"Failed to reset SQL statement. Error code: " + std::to_string(err), err);
 
 
   86            const int err = sqlite3_clear_bindings(
m_stmt);
 
   87            if (err == SQLITE_OK) 
return;
 
   88            throw sqlite_exception(
"Failed to clear bindings on SQL statement. Error code: " + std::to_string(err), err);
 
 
  107            return sqlite3_step(
m_stmt);
 
 
  115                typename std::enable_if<std::is_integral<T>::value>::type* = 0) {
 
  116            return static_cast<T
>(sqlite3_column_int64(
m_stmt, index));
 
 
  121                typename std::enable_if<std::is_floating_point<T>::value>::type* = 0) {
 
  122            return static_cast<T
>(sqlite3_column_double(
m_stmt, index));
 
 
  127                typename std::enable_if<std::is_same<T, std::string>::value>::type* = 0) {
 
  128            const unsigned char *text = sqlite3_column_text(
m_stmt, index);
 
  130                return std::string(
reinterpret_cast<const char*
>(text));
 
  132            return std::string();
 
 
  137                typename std::enable_if<std::is_same<T, std::vector<char>>::value>::type* = 0) {
 
  138            const void* blob = sqlite3_column_blob(
m_stmt, index);
 
  139            const int blob_size = sqlite3_column_bytes(
m_stmt, index);
 
  140            return std::vector<char>(
static_cast<const char*
>(blob), 
static_cast<const char*
>(blob) + blob_size);
 
 
  145                typename std::enable_if<std::is_same<T, std::vector<uint8_t>>::value>::type* = 0) {
 
  146            const void* blob = sqlite3_column_blob(
m_stmt, index);
 
  147            const int blob_size = sqlite3_column_bytes(
m_stmt, index);
 
  148            return std::vector<uint8_t>(
static_cast<const uint8_t*
>(blob), 
static_cast<const uint8_t*
>(blob) + blob_size);
 
 
  153                typename std::enable_if<
 
  154                    !std::is_integral<T>::value &&
 
  155                    !std::is_floating_point<T>::value &&
 
  156                    !std::is_same<T, std::string>::value &&
 
  157                    !std::is_same<T, std::vector<char>>::value &&
 
  158                    !std::is_same<T, std::vector<uint8_t>>::value &&
 
  159                    std::is_trivially_copyable<T>::value
 
  162            const void* blob = sqlite3_column_blob(
m_stmt, index);
 
  163            const int blob_size = sqlite3_column_bytes(
m_stmt, index);
 
  164            if (blob_size == 
sizeof(T)) {
 
  165                std::memcpy(&value, blob, 
sizeof(T));
 
 
  178                typename std::enable_if<std::is_integral<T>::value>::type* = 0) {
 
  179            return (sqlite3_bind_int64(
m_stmt, index, 
static_cast<int64_t
>(value)) == SQLITE_OK);
 
 
  184                typename std::enable_if<std::is_floating_point<T>::value>::type* = 0) {
 
  185            return (sqlite3_bind_double(
m_stmt, index, 
static_cast<double>(value)) == SQLITE_OK);
 
 
  190                typename std::enable_if<std::is_same<T, std::string>::value>::type* = 0) {
 
  191            return (sqlite3_bind_text(
m_stmt, index, value.c_str(), 
static_cast<int>(value.size()), SQLITE_STATIC) == SQLITE_OK);
 
 
  196                typename std::enable_if<std::is_same<T, std::vector<char>>::value>::type* = 0) {
 
  197            return (sqlite3_bind_blob(
m_stmt, index, value.data(), value.size(), SQLITE_STATIC) == SQLITE_OK);
 
 
  202                typename std::enable_if<std::is_same<T, std::vector<uint8_t>>::value>::type* = 0) {
 
  203            return (sqlite3_bind_blob(
m_stmt, index, value.data(), value.size(), SQLITE_STATIC) == SQLITE_OK);
 
 
  208                typename std::enable_if<
 
  209                    !std::is_integral<T>::value &&
 
  210                    !std::is_floating_point<T>::value &&
 
  211                    !std::is_same<T, std::string>::value &&
 
  212                    !std::is_same<T, std::vector<char>>::value &&
 
  213                    !std::is_same<T, std::vector<uint8_t>>::value &&
 
  214                    std::is_trivially_copyable<T>::value
 
  216            return (sqlite3_bind_blob(
m_stmt, index, &value, 
sizeof(T), SQLITE_STATIC) == SQLITE_OK);
 
 
 
Utility functions for working with SQLite in sqlite_containers.
 
#define SQLITE_CONTAINERS_BUSY_RETRY_DELAY_MS
 
SqliteStmt(sqlite3 *sqlite_db, const char *query)
Constructs a SqliteStmt and prepares the statement.
 
T extract_column(const int &index, typename std::enable_if< !std::is_integral< T >::value &&!std::is_floating_point< T >::value &&!std::is_same< T, std::string >::value &&!std::is_same< T, std::vector< char > >::value &&!std::is_same< T, std::vector< uint8_t > >::value &&std::is_trivially_copyable< T >::value >::type *=0)
 
void clear_bindings()
Clears all bindings on the prepared statement.
 
SqliteStmt()=default
Default constructor.
 
bool bind_value(const int &index, const T &value, typename std::enable_if< std::is_same< T, std::vector< uint8_t > >::value >::type *=0)
 
sqlite3_stmt * m_stmt
Pointer to the prepared SQLite statement.
 
void execute(sqlite3 *sqlite_db)
Executes the prepared statement.
 
T extract_column(const int &index, typename std::enable_if< std::is_floating_point< T >::value >::type *=0)
 
sqlite3_stmt * get_stmt() noexcept
Gets the prepared SQLite statement.
 
T extract_column(const int &index, typename std::enable_if< std::is_integral< T >::value >::type *=0)
Extracts a value from a SQLite statement column.
 
void init(sqlite3 *sqlite_db, const std::string &query)
Initializes the statement.
 
void reset()
Resets the prepared statement.
 
bool bind_value(const int &index, const T &value, typename std::enable_if< std::is_floating_point< T >::value >::type *=0)
 
SqliteStmt(sqlite3 *sqlite_db, const std::string &query)
Constructs a SqliteStmt and prepares the statement.
 
void init(sqlite3 *sqlite_db, const char *query)
Initializes the statement.
 
bool bind_value(const int &index, const T &value, typename std::enable_if< std::is_same< T, std::string >::value >::type *=0)
 
T extract_column(const int &index, typename std::enable_if< std::is_same< T, std::string >::value >::type *=0)
 
bool bind_value(const int &index, const T &value, typename std::enable_if< !std::is_integral< T >::value &&!std::is_floating_point< T >::value &&!std::is_same< T, std::string >::value &&!std::is_same< T, std::vector< char > >::value &&!std::is_same< T, std::vector< uint8_t > >::value &&std::is_trivially_copyable< T >::value >::type *=0)
 
bool bind_value(const int &index, const T &value, typename std::enable_if< std::is_integral< T >::value >::type *=0)
Binds a value to a SQLite statement.
 
T extract_column(const int &index, typename std::enable_if< std::is_same< T, std::vector< char > >::value >::type *=0)
 
void execute()
Executes the prepared statement.
 
bool bind_value(const int &index, const T &value, typename std::enable_if< std::is_same< T, std::vector< char > >::value >::type *=0)
 
T extract_column(const int &index, typename std::enable_if< std::is_same< T, std::vector< uint8_t > >::value >::type *=0)
 
Exception class for SQLite errors.
 
void execute(sqlite3_stmt *stmt)
Executes a SQLite statement.