renamed foreign class to entity, introduced interface class query_result_reader
This commit is contained in:
@@ -2,14 +2,14 @@ set(HEADER
|
||||
include/sqlite_connection.hpp
|
||||
include/sqlite_error.hpp
|
||||
include/sqlite_dialect.hpp
|
||||
include/sqlite_query_result.hpp
|
||||
include/sqlite_result_reader.hpp
|
||||
)
|
||||
|
||||
set(SOURCES
|
||||
src/sqlite_connection.cpp
|
||||
src/sqlite_error.cpp
|
||||
src/sqlite_dialect.cpp
|
||||
src/sqlite_query_result.cpp
|
||||
src/sqlite_result_reader.cpp
|
||||
)
|
||||
|
||||
add_library(matador-sqlite SHARED ${SOURCES} ${HEADER})
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
|
||||
#include "matador/sql/connection_impl.hpp"
|
||||
|
||||
#include "sqlite_result_reader.hpp"
|
||||
|
||||
#include <sqlite3.h>
|
||||
|
||||
namespace matador::backends::sqlite {
|
||||
@@ -35,9 +37,18 @@ public:
|
||||
|
||||
bool exists(const std::string &table_name) override;
|
||||
|
||||
private:
|
||||
struct fetch_context
|
||||
{
|
||||
sql::record prototype;
|
||||
sqlite_result_reader::rows rows;
|
||||
};
|
||||
|
||||
private:
|
||||
static int parse_result(void* param, int column_count, char** values, char** columns);
|
||||
|
||||
fetch_context fetch_internal(const std::string &stmt);
|
||||
|
||||
private:
|
||||
sqlite3 *sqlite_db_{};
|
||||
};
|
||||
|
||||
+12
-17
@@ -1,24 +1,27 @@
|
||||
#ifndef QUERY_SQLITE_QUERY_RESULT_HPP
|
||||
#define QUERY_SQLITE_QUERY_RESULT_HPP
|
||||
#ifndef QUERY_SQLITE_RESULT_READER_HPP
|
||||
#define QUERY_SQLITE_RESULT_READER_HPP
|
||||
|
||||
#include "matador/sql/query_result_impl.hpp"
|
||||
#include "matador/sql/record.hpp"
|
||||
#include "matador/sql/query_result_reader.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace matador::backends::sqlite {
|
||||
|
||||
class sqlite_query_result : public sql::query_result_impl {
|
||||
class sqlite_result_reader : public sql::query_result_reader
|
||||
{
|
||||
public:
|
||||
using columns = std::vector<char*>;
|
||||
using rows = std::vector<columns>;
|
||||
|
||||
public:
|
||||
sqlite_query_result(sql::record prototype, rows result);
|
||||
~sqlite_query_result() override;
|
||||
sqlite_result_reader(rows result, size_t column_count);
|
||||
~sqlite_result_reader() override;
|
||||
|
||||
size_t column_count() const override;
|
||||
|
||||
[[nodiscard]] const char* column(size_t index) const override;
|
||||
[[nodiscard]] bool fetch() override;
|
||||
|
||||
void read_value(const char *id, size_t index, char &value) override;
|
||||
void read_value(const char *id, size_t index, short &value) override;
|
||||
void read_value(const char *id, size_t index, int &value) override;
|
||||
@@ -37,20 +40,12 @@ public:
|
||||
void read_value(const char *id, size_t index, std::string &value, size_t s) override;
|
||||
void read_value(const char *id, size_t index, sql::any_type &value, sql::data_type_t type, size_t size) override;
|
||||
|
||||
[[nodiscard]] const char* column(size_t index) const override;
|
||||
[[nodiscard]] bool fetch() override;
|
||||
|
||||
private:
|
||||
friend class sqlite_connection;
|
||||
|
||||
private:
|
||||
void push_back(char **row_values, int column_count);
|
||||
|
||||
private:
|
||||
rows result_;
|
||||
long long row_index_ = -1;
|
||||
size_t column_count_{};
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //QUERY_SQLITE_QUERY_RESULT_HPP
|
||||
#endif //QUERY_SQLITE_RESULT_READER_HPP
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "sqlite_connection.hpp"
|
||||
#include "sqlite_error.hpp"
|
||||
#include "sqlite_query_result.hpp"
|
||||
#include "sqlite_result_reader.hpp"
|
||||
|
||||
#include "matador/sql/record.hpp"
|
||||
|
||||
@@ -37,17 +37,11 @@ bool sqlite_connection::is_open()
|
||||
return sqlite_db_ != nullptr;
|
||||
}
|
||||
|
||||
struct fetch_context
|
||||
{
|
||||
sql::record prototype;
|
||||
sqlite_query_result::rows rows;
|
||||
};
|
||||
|
||||
int sqlite_connection::parse_result(void* param, int column_count, char** values, char** columns)
|
||||
{
|
||||
auto *context = static_cast<fetch_context*>(param);
|
||||
|
||||
sqlite_query_result::columns column;
|
||||
sqlite_result_reader::columns column;
|
||||
for(int i = 0; i < column_count; ++i) {
|
||||
// copy and store column data;
|
||||
if (values[i] == nullptr) {
|
||||
@@ -73,6 +67,17 @@ int sqlite_connection::parse_result(void* param, int column_count, char** values
|
||||
return 0;
|
||||
}
|
||||
|
||||
sqlite_connection::fetch_context sqlite_connection::fetch_internal(const std::string &stmt)
|
||||
{
|
||||
fetch_context context;
|
||||
char *errmsg = nullptr;
|
||||
const int ret = sqlite3_exec(sqlite_db_, stmt.c_str(), parse_result, &context, &errmsg);
|
||||
|
||||
throw_sqlite_error(ret, sqlite_db_, "sqlite", stmt);
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
size_t sqlite_connection::execute(const std::string &stmt)
|
||||
{
|
||||
char *errmsg = nullptr;
|
||||
@@ -85,13 +90,9 @@ size_t sqlite_connection::execute(const std::string &stmt)
|
||||
|
||||
std::unique_ptr<sql::query_result_impl> sqlite_connection::fetch(const std::string &stmt)
|
||||
{
|
||||
fetch_context context;
|
||||
char *errmsg = nullptr;
|
||||
const int ret = sqlite3_exec(sqlite_db_, stmt.c_str(), parse_result, &context, &errmsg);
|
||||
auto context = fetch_internal(stmt);
|
||||
|
||||
throw_sqlite_error(ret, sqlite_db_, "sqlite", stmt);
|
||||
|
||||
return std::move(std::make_unique<sqlite_query_result>(std::move(context.prototype), std::move(context.rows)));
|
||||
return std::move(std::make_unique<sql::query_result_impl>(std::make_unique<sqlite_result_reader>(std::move(context.rows), context.prototype.size()), std::move(context.prototype)));
|
||||
}
|
||||
|
||||
void sqlite_connection::prepare(const std::string &stmt)
|
||||
@@ -135,21 +136,21 @@ sql::data_type_t string2type(const char *type)
|
||||
|
||||
sql::record sqlite_connection::describe(const std::string& table)
|
||||
{
|
||||
std::string stmt("PRAGMA table_info(" + table + ")");
|
||||
const auto result = fetch("PRAGMA table_info(" + table + ")");
|
||||
const auto result = fetch_internal("PRAGMA table_info(" + table + ")");
|
||||
|
||||
sqlite_result_reader reader(std::move(result.rows), result.prototype.size());
|
||||
sql::record prototype;
|
||||
while (result->fetch()) {
|
||||
while (reader.fetch()) {
|
||||
char *end = nullptr;
|
||||
// Todo: add index to column
|
||||
auto index = strtoul(result->column(0), &end, 10);
|
||||
std::string name = result->column(1);
|
||||
auto index = strtoul(reader.column(0), &end, 10);
|
||||
std::string name = reader.column(1);
|
||||
|
||||
// Todo: extract size
|
||||
auto type = (string2type(result->column(2)));
|
||||
auto type = (string2type(reader.column(2)));
|
||||
end = nullptr;
|
||||
utils::constraints options{};
|
||||
if (strtoul(result->column(3), &end, 10) == 0) {
|
||||
if (strtoul(reader.column(3), &end, 10) == 0) {
|
||||
options = utils::constraints::NOT_NULL;
|
||||
}
|
||||
// f.default_value(res->column(4));
|
||||
@@ -161,15 +162,16 @@ sql::record sqlite_connection::describe(const std::string& table)
|
||||
|
||||
bool sqlite_connection::exists(const std::string &table_name)
|
||||
{
|
||||
const auto result = fetch("SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND tbl_name='" + table_name + "' LIMIT 1");
|
||||
const auto result = fetch_internal("SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND tbl_name='" + table_name + "' LIMIT 1");
|
||||
sqlite_result_reader reader(std::move(result.rows), result.prototype.size());
|
||||
|
||||
if (!result->fetch()) {
|
||||
if (!reader.fetch()) {
|
||||
// Todo: throw an exception?
|
||||
return false;
|
||||
}
|
||||
|
||||
int v{};
|
||||
result->read_value(nullptr, 0, v);
|
||||
reader.read_value(nullptr, 0, v);
|
||||
|
||||
return v == 1;
|
||||
}
|
||||
|
||||
+34
-58
@@ -1,11 +1,9 @@
|
||||
#include "sqlite_query_result.hpp"
|
||||
#include "sqlite_result_reader.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <sqlite3.h>
|
||||
|
||||
namespace matador::backends::sqlite {
|
||||
|
||||
template < class Type >
|
||||
@@ -50,12 +48,11 @@ void read(Type &x, const char *val, typename std::enable_if<std::is_floating_poi
|
||||
}
|
||||
}
|
||||
|
||||
sqlite_query_result::sqlite_query_result(sql::record prototype, sqlite_query_result::rows result)
|
||||
: sql::query_result_impl(std::move(prototype))
|
||||
, result_(std::move(result))
|
||||
{}
|
||||
sqlite_result_reader::sqlite_result_reader(sqlite_result_reader::rows result, size_t column_count)
|
||||
: result_(std::move(result))
|
||||
, column_count_(column_count) {}
|
||||
|
||||
sqlite_query_result::~sqlite_query_result()
|
||||
sqlite_result_reader::~sqlite_result_reader()
|
||||
{
|
||||
std::for_each(result_.begin(), result_.end(), [](rows ::value_type& row) {
|
||||
std::for_each(row.begin(), row.end(), [](const char *val) {
|
||||
@@ -64,77 +61,87 @@ sqlite_query_result::~sqlite_query_result()
|
||||
});
|
||||
}
|
||||
|
||||
size_t sqlite_query_result::column_count() const
|
||||
size_t sqlite_result_reader::column_count() const
|
||||
{
|
||||
return prototype_.size();
|
||||
return column_count_;
|
||||
}
|
||||
|
||||
void sqlite_query_result::read_value(const char *id, size_t index, char &value)
|
||||
const char* sqlite_result_reader::column(size_t index) const
|
||||
{
|
||||
return result_[row_index_][index];
|
||||
}
|
||||
|
||||
bool sqlite_result_reader::fetch()
|
||||
{
|
||||
return ++row_index_ < result_.size();
|
||||
}
|
||||
|
||||
void sqlite_result_reader::read_value(const char *id, size_t index, char &value)
|
||||
{
|
||||
read(value, result_[row_index_][index]);
|
||||
}
|
||||
|
||||
void sqlite_query_result::read_value(const char *id, size_t index, short &value)
|
||||
void sqlite_result_reader::read_value(const char *id, size_t index, short &value)
|
||||
{
|
||||
read(value, result_[row_index_][index]);
|
||||
}
|
||||
|
||||
void sqlite_query_result::read_value(const char *id, size_t index, int &value)
|
||||
void sqlite_result_reader::read_value(const char *id, size_t index, int &value)
|
||||
{
|
||||
read(value, result_[row_index_][index]);
|
||||
}
|
||||
|
||||
void sqlite_query_result::read_value(const char *id, size_t index, long &value)
|
||||
void sqlite_result_reader::read_value(const char *id, size_t index, long &value)
|
||||
{
|
||||
read(value, result_[row_index_][index]);
|
||||
}
|
||||
|
||||
void sqlite_query_result::read_value(const char *id, size_t index, long long int &value)
|
||||
void sqlite_result_reader::read_value(const char *id, size_t index, long long int &value)
|
||||
{
|
||||
read(value, result_[row_index_][index]);
|
||||
}
|
||||
|
||||
void sqlite_query_result::read_value(const char *id, size_t index, unsigned char &value)
|
||||
void sqlite_result_reader::read_value(const char *id, size_t index, unsigned char &value)
|
||||
{
|
||||
read(value, result_[row_index_][index]);
|
||||
}
|
||||
|
||||
void sqlite_query_result::read_value(const char *id, size_t index, unsigned short &value)
|
||||
void sqlite_result_reader::read_value(const char *id, size_t index, unsigned short &value)
|
||||
{
|
||||
read(value, result_[row_index_][index]);
|
||||
}
|
||||
|
||||
void sqlite_query_result::read_value(const char *id, size_t index, unsigned int &value)
|
||||
void sqlite_result_reader::read_value(const char *id, size_t index, unsigned int &value)
|
||||
{
|
||||
read(value, result_[row_index_][index]);
|
||||
}
|
||||
|
||||
void sqlite_query_result::read_value(const char *id, size_t index, unsigned long &value)
|
||||
void sqlite_result_reader::read_value(const char *id, size_t index, unsigned long &value)
|
||||
{
|
||||
read(value, result_[row_index_][index]);
|
||||
}
|
||||
|
||||
void sqlite_query_result::read_value(const char *id, size_t index, unsigned long long int &value)
|
||||
void sqlite_result_reader::read_value(const char *id, size_t index, unsigned long long int &value)
|
||||
{
|
||||
read(value, result_[row_index_][index]);
|
||||
}
|
||||
|
||||
void sqlite_query_result::read_value(const char *id, size_t index, bool &value)
|
||||
void sqlite_result_reader::read_value(const char *id, size_t index, bool &value)
|
||||
{
|
||||
read(value, result_[row_index_][index]);
|
||||
}
|
||||
|
||||
void sqlite_query_result::read_value(const char *id, size_t index, float &value)
|
||||
void sqlite_result_reader::read_value(const char *id, size_t index, float &value)
|
||||
{
|
||||
read(value, result_[row_index_][index]);
|
||||
}
|
||||
|
||||
void sqlite_query_result::read_value(const char *id, size_t index, double &value)
|
||||
void sqlite_result_reader::read_value(const char *id, size_t index, double &value)
|
||||
{
|
||||
read(value, result_[row_index_][index]);
|
||||
}
|
||||
|
||||
void sqlite_query_result::read_value(const char *id, size_t index, char *value, size_t size)
|
||||
void sqlite_result_reader::read_value(const char *id, size_t index, char *value, size_t size)
|
||||
{
|
||||
auto val = result_[row_index_][index];
|
||||
size_t len = strlen(val);
|
||||
@@ -154,47 +161,16 @@ void sqlite_query_result::read_value(const char *id, size_t index, char *value,
|
||||
}
|
||||
}
|
||||
|
||||
void sqlite_query_result::read_value(const char *id, size_t index, std::string &value)
|
||||
void sqlite_result_reader::read_value(const char *id, size_t index, std::string &value)
|
||||
{
|
||||
value.assign(result_[row_index_][index]);
|
||||
}
|
||||
|
||||
void sqlite_query_result::read_value(const char *id, size_t index, std::string &value, size_t s)
|
||||
void sqlite_result_reader::read_value(const char *id, size_t index, std::string &value, size_t s)
|
||||
{
|
||||
value.assign(result_[row_index_][index]);
|
||||
}
|
||||
|
||||
void sqlite_query_result::push_back(char **row_values, int column_count)
|
||||
{
|
||||
columns data;
|
||||
for(int i = 0; i < column_count; ++i) {
|
||||
// copy and store column data;
|
||||
if (row_values[i] == nullptr) {
|
||||
auto val = new char[1];
|
||||
val[0] = '\0';
|
||||
data.push_back(val);
|
||||
} else {
|
||||
size_t size = strlen(row_values[i]);
|
||||
auto val = new char[size + 1];
|
||||
std::memcpy(val, row_values[i], size);
|
||||
val[size] = '\0';
|
||||
data.push_back(val);
|
||||
}
|
||||
}
|
||||
result_.emplace_back(data);
|
||||
}
|
||||
|
||||
const char* sqlite_query_result::column(size_t index) const
|
||||
{
|
||||
return result_[row_index_][index];
|
||||
}
|
||||
|
||||
bool sqlite_query_result::fetch()
|
||||
{
|
||||
column_index_ = 0;
|
||||
return ++row_index_ < result_.size();
|
||||
}
|
||||
|
||||
template < typename Type >
|
||||
void convert(const char *valstr, sql::any_type &value)
|
||||
{
|
||||
@@ -203,7 +179,7 @@ void convert(const char *valstr, sql::any_type &value)
|
||||
value = val;
|
||||
}
|
||||
|
||||
void sqlite_query_result::read_value(const char *id, size_t index, sql::any_type &value, sql::data_type_t type, size_t size)
|
||||
void sqlite_result_reader::read_value(const char *id, size_t index, sql::any_type &value, sql::data_type_t type, size_t size)
|
||||
{
|
||||
switch (type) {
|
||||
case sql::data_type_t::type_char:
|
||||
Reference in New Issue
Block a user