#include <iostream>
#include <unordered_map>
#include "sqlite_sth.h"
#include "sqlite_dbh.h"
#include "sqlite_queue.h"
#include "sqlite3.h"
sqlite_sth::sqlite_sth(
sqlite_dbh &dbh,
const std::string &sql
):dbh_{ dbh },
sql_{ sql }
{
auto code = sqlite3_prepare_v2(
dbh_.db(),
sql_.data(),
1 + sql_.size(),
&stmt_,
nullptr
);
if(code != SQLITE_OK) {
auto err = std::string {
"Failed to prepare query "
} + sql + std::string {
" - "
} + std::string {
sqlite3_errmsg(dbh_.db())
};
sqlite3_finalize(stmt_);
throw std::runtime_error(err);
}
count_ = sqlite3_column_count(stmt_);
for(int i = 0; i < count_; ++i) {
column_names_.emplace_back(
sqlite3_column_name(stmt_, i)
);
}
}
sqlite_sth::~sqlite_sth()
{
sqlite3_finalize(stmt_);
}
void
sqlite_sth::step()
{
auto *self = this;
dbh_.push([self] {
if(self->stmt_ == nullptr) {
throw std::logic_error("did not have valid sth");
}
auto code = sqlite3_step(self->stmt_);
switch(code) {
case SQLITE_OK:
std::cerr << self->stmt_ << " - OK\n";
break;
case SQLITE_BUSY:
std::cerr << self->stmt_ << " - busy\n";
break;
case SQLITE_DONE:
std::cerr << self->stmt_ << " - done\n";
break;
case SQLITE_ROW: {
std::cerr << self->stmt_ << " - row\n";
auto start = std::chrono::steady_clock::now();
{
std::unordered_map<std::string, std::string> row;
for(int i = 0; i < self->count_; ++i) {
const char *data = reinterpret_cast<const char *>(sqlite3_column_text(self->stmt_, i));
std::string::size_type size = sqlite3_column_bytes(self->stmt_, i);
std::string s { data, size };
// std::string k { sqlite3_column_name(self->stmt_, i) };
// std::cerr << k << " (" << i << ") = " << s << std::endl;
row[self->column_names_[i]] = s;
}
}
auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(
std::chrono::steady_clock::now() - start
);
std::cerr << "This row took " << duration.count() << "ns\n";
break;
}
case SQLITE_ERROR:
std::cerr << self->stmt_ << " - error\n";
break;
case SQLITE_MISUSE:
std::cerr << self->stmt_ << " - misuse\n";
break;
default:
std::cerr << "Unknown SQLite return code: " << code << std::endl;
break;
}
});
}