progress on record fetch
This commit is contained in:
parent
ae5777bdb0
commit
171e8d36ce
|
|
@ -2,6 +2,7 @@
|
||||||
#define QUERY_SQLITE_QUERY_RESULT_HPP
|
#define QUERY_SQLITE_QUERY_RESULT_HPP
|
||||||
|
|
||||||
#include "matador/sql/query_result_impl.hpp"
|
#include "matador/sql/query_result_impl.hpp"
|
||||||
|
#include "matador/sql/record.hpp"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|
@ -9,8 +10,15 @@ namespace matador::backends::sqlite {
|
||||||
|
|
||||||
class sqlite_query_result : public sql::query_result_impl {
|
class sqlite_query_result : public sql::query_result_impl {
|
||||||
public:
|
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_query_result() override;
|
||||||
|
|
||||||
|
size_t column_count() const override;
|
||||||
|
|
||||||
void read_value(const char *id, size_t index, char &value) 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, short &value) override;
|
||||||
void read_value(const char *id, size_t index, int &value) override;
|
void read_value(const char *id, size_t index, int &value) override;
|
||||||
|
|
@ -39,9 +47,6 @@ private:
|
||||||
void push_back(char **row_values, int column_count);
|
void push_back(char **row_values, int column_count);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
using columns = std::vector<char*>;
|
|
||||||
using rows = std::vector<columns>;
|
|
||||||
|
|
||||||
rows result_;
|
rows result_;
|
||||||
long long row_index_ = -1;
|
long long row_index_ = -1;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -37,14 +37,37 @@ bool sqlite_connection::is_open()
|
||||||
return sqlite_db_ != nullptr;
|
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)
|
int sqlite_connection::parse_result(void* param, int column_count, char** values, char** columns)
|
||||||
{
|
{
|
||||||
auto *result = static_cast<sqlite_query_result*>(param);
|
auto *context = static_cast<fetch_context*>(param);
|
||||||
result->push_back(values, column_count);
|
|
||||||
|
|
||||||
sql::record prototype;
|
sqlite_query_result::columns column;
|
||||||
for(int i = 0; i < column_count; ++i) {
|
for(int i = 0; i < column_count; ++i) {
|
||||||
prototype.append(sql::column{columns[i]});
|
// copy and store column data;
|
||||||
|
if (values[i] == nullptr) {
|
||||||
|
auto val = new char[1];
|
||||||
|
val[0] = '\0';
|
||||||
|
column.push_back(val);
|
||||||
|
} else {
|
||||||
|
size_t size = strlen(values[i]);
|
||||||
|
auto val = new char[size + 1];
|
||||||
|
std::memcpy(val, values[i], size);
|
||||||
|
val[size] = '\0';
|
||||||
|
column.push_back(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
context->rows.emplace_back(column);
|
||||||
|
|
||||||
|
if (context->prototype.empty()) {
|
||||||
|
for(int i = 0; i < column_count; ++i) {
|
||||||
|
context->prototype.append(sql::column{columns[i]});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -62,13 +85,13 @@ size_t sqlite_connection::execute(const std::string &stmt)
|
||||||
|
|
||||||
std::unique_ptr<sql::query_result_impl> sqlite_connection::fetch(const std::string &stmt)
|
std::unique_ptr<sql::query_result_impl> sqlite_connection::fetch(const std::string &stmt)
|
||||||
{
|
{
|
||||||
auto result = std::make_unique<sqlite_query_result>();
|
fetch_context context;
|
||||||
char *errmsg = nullptr;
|
char *errmsg = nullptr;
|
||||||
const int ret = sqlite3_exec(sqlite_db_, stmt.c_str(), parse_result, result.get(), &errmsg);
|
const int ret = sqlite3_exec(sqlite_db_, stmt.c_str(), parse_result, &context, &errmsg);
|
||||||
|
|
||||||
throw_sqlite_error(ret, sqlite_db_, "sqlite", stmt);
|
throw_sqlite_error(ret, sqlite_db_, "sqlite", stmt);
|
||||||
|
|
||||||
return std::move(result);
|
return std::move(std::make_unique<sqlite_query_result>(std::move(context.prototype), std::move(context.rows)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void sqlite_connection::prepare(const std::string &stmt)
|
void sqlite_connection::prepare(const std::string &stmt)
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,8 @@
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
|
#include <sqlite3.h>
|
||||||
|
|
||||||
namespace matador::backends::sqlite {
|
namespace matador::backends::sqlite {
|
||||||
|
|
||||||
template < class Type >
|
template < class Type >
|
||||||
|
|
@ -48,6 +50,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_query_result::~sqlite_query_result()
|
sqlite_query_result::~sqlite_query_result()
|
||||||
{
|
{
|
||||||
std::for_each(result_.begin(), result_.end(), [](rows ::value_type& row) {
|
std::for_each(result_.begin(), result_.end(), [](rows ::value_type& row) {
|
||||||
|
|
@ -57,6 +64,11 @@ sqlite_query_result::~sqlite_query_result()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t sqlite_query_result::column_count() const
|
||||||
|
{
|
||||||
|
return prototype_.size();
|
||||||
|
}
|
||||||
|
|
||||||
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, char &value)
|
||||||
{
|
{
|
||||||
read(value, result_[row_index_][index]);
|
read(value, result_[row_index_][index]);
|
||||||
|
|
@ -265,5 +277,4 @@ void sqlite_query_result::read_value(const char *id, size_t index, sql::any_type
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
#define QUERY_COLUMN_GENERATOR_HPP
|
#define QUERY_COLUMN_GENERATOR_HPP
|
||||||
|
|
||||||
#include "matador/sql/column.hpp"
|
#include "matador/sql/column.hpp"
|
||||||
#include "matador/sql/table_repository.hpp"
|
|
||||||
#include "matador/sql/types.hpp"
|
#include "matador/sql/types.hpp"
|
||||||
|
|
||||||
#include "matador/utils/access.hpp"
|
#include "matador/utils/access.hpp"
|
||||||
|
|
@ -13,6 +12,8 @@
|
||||||
|
|
||||||
namespace matador::sql {
|
namespace matador::sql {
|
||||||
|
|
||||||
|
class table_repository;
|
||||||
|
|
||||||
class fk_column_generator
|
class fk_column_generator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
||||||
|
|
@ -29,17 +29,23 @@ public:
|
||||||
[[nodiscard]] bool is_open() const;
|
[[nodiscard]] bool is_open() const;
|
||||||
[[nodiscard]] const connection_info& info() const;
|
[[nodiscard]] const connection_info& info() const;
|
||||||
|
|
||||||
|
[[nodiscard]] record describe(const std::string &table_name) const;
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
query_result<Type> fetch(const std::string &sql)
|
query_result<Type> fetch(const std::string &sql)
|
||||||
{
|
{
|
||||||
return query_result<Type>(connection_->execute(sql));
|
return query_result<Type>(connection_->fetch(sql));
|
||||||
}
|
}
|
||||||
query_result<record> fetch(const std::string &sql);
|
[[nodiscard]] query_result<record> fetch(const std::string &sql) const;
|
||||||
std::pair<size_t, std::string> execute(const std::string &sql);
|
[[nodiscard]] std::pair<size_t, std::string> execute(const std::string &sql) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class session;
|
||||||
|
|
||||||
|
[[nodiscard]] std::unique_ptr<query_result_impl> call_fetch(const std::string &sql) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
connection_info connection_info_;
|
connection_info connection_info_;
|
||||||
bool is_open_{false};
|
|
||||||
std::unique_ptr<connection_impl> connection_;
|
std::unique_ptr<connection_impl> connection_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,13 @@ enum class join_type_t {
|
||||||
INNER, OUTER, LEFT, RIGHT
|
INNER, OUTER, LEFT, RIGHT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct query
|
||||||
|
{
|
||||||
|
std::string sql;
|
||||||
|
record prototype;
|
||||||
|
std::vector<any_type> host_vars;
|
||||||
|
};
|
||||||
|
|
||||||
class query_builder
|
class query_builder
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
@ -123,8 +130,6 @@ public:
|
||||||
|
|
||||||
std::string compile();
|
std::string compile();
|
||||||
|
|
||||||
[[nodiscard]] const record& prototype() const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void transition_to(state_t next);
|
void transition_to(state_t next);
|
||||||
void initialize(command_t cmd, state_t state);
|
void initialize(command_t cmd, state_t state);
|
||||||
|
|
@ -139,7 +144,7 @@ private:
|
||||||
|
|
||||||
detail::any_type_to_string_visitor value_to_string_;
|
detail::any_type_to_string_visitor value_to_string_;
|
||||||
|
|
||||||
record prototype_;
|
query query_;
|
||||||
|
|
||||||
using query_state_set = std::unordered_set<state_t>;
|
using query_state_set = std::unordered_set<state_t>;
|
||||||
using query_state_transition_map = std::unordered_map<state_t, query_state_set>;
|
using query_state_transition_map = std::unordered_map<state_t, query_state_set>;
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,12 @@ protected:
|
||||||
using query_intermediate::query_intermediate;
|
using query_intermediate::query_intermediate;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
template < class Type >
|
||||||
|
query_result<Type> fetch_all()
|
||||||
|
{
|
||||||
|
return query_result<Type>(fetch());
|
||||||
|
}
|
||||||
|
|
||||||
query_result<record> fetch_all();
|
query_result<record> fetch_all();
|
||||||
record fetch_one();
|
record fetch_one();
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
|
|
@ -55,6 +61,9 @@ public:
|
||||||
auto result = fetch_all();
|
auto result = fetch_all();
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<query_result_impl> fetch();
|
||||||
};
|
};
|
||||||
|
|
||||||
class query_limit_intermediate : public query_select_finish
|
class query_limit_intermediate : public query_select_finish
|
||||||
|
|
@ -124,7 +133,6 @@ public:
|
||||||
using query_intermediate::query_intermediate;
|
using query_intermediate::query_intermediate;
|
||||||
|
|
||||||
query_from_intermediate from(const std::string &table, const std::string &as = "");
|
query_from_intermediate from(const std::string &table, const std::string &as = "");
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class query_into_intermediate : public query_intermediate
|
class query_into_intermediate : public query_intermediate
|
||||||
|
|
@ -149,7 +157,7 @@ public:
|
||||||
template<class Type>
|
template<class Type>
|
||||||
query_execute_finish table(const std::string &table_name)
|
query_execute_finish table(const std::string &table_name)
|
||||||
{
|
{
|
||||||
const auto &info = repository_.attach<Type>(table_name, record{column_generator::generate<Type>(repository_)});
|
const auto &info = repository_.attach<Type>(table_name/*, record{column_generator::generate<Type>(repository_)}*/);
|
||||||
return {db(), query().table(table_name, info.prototype.columns())};
|
return {db(), query().table(table_name, info.prototype.columns())};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -115,6 +115,7 @@ public:
|
||||||
public:
|
public:
|
||||||
explicit query_result(std::unique_ptr<query_result_impl> impl)
|
explicit query_result(std::unique_ptr<query_result_impl> impl)
|
||||||
: impl_(std::move(impl)) {}
|
: impl_(std::move(impl)) {}
|
||||||
|
|
||||||
query_result(std::unique_ptr<query_result_impl> impl, creator_func creator)
|
query_result(std::unique_ptr<query_result_impl> impl, creator_func creator)
|
||||||
: creator_(creator)
|
: creator_(creator)
|
||||||
, impl_(std::move(impl)) {}
|
, impl_(std::move(impl)) {}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
#include "matador/utils/field_attributes.hpp"
|
#include "matador/utils/field_attributes.hpp"
|
||||||
|
|
||||||
#include "matador/sql/any_type.hpp"
|
#include "matador/sql/any_type.hpp"
|
||||||
|
#include "matador/sql/record.hpp"
|
||||||
#include "matador/sql/types.hpp"
|
#include "matador/sql/types.hpp"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
@ -16,6 +17,8 @@ class query_result_impl
|
||||||
public:
|
public:
|
||||||
virtual ~query_result_impl() = default;
|
virtual ~query_result_impl() = default;
|
||||||
|
|
||||||
|
virtual size_t column_count() const = 0;
|
||||||
|
|
||||||
virtual void read_value(const char *id, size_t index, char &value) = 0;
|
virtual void read_value(const char *id, size_t index, char &value) = 0;
|
||||||
virtual void read_value(const char *id, size_t index, short &value) = 0;
|
virtual void read_value(const char *id, size_t index, short &value) = 0;
|
||||||
virtual void read_value(const char *id, size_t index, int &value) = 0;
|
virtual void read_value(const char *id, size_t index, int &value) = 0;
|
||||||
|
|
@ -79,8 +82,14 @@ public:
|
||||||
[[nodiscard]] virtual const char* column(size_t index) const = 0;
|
[[nodiscard]] virtual const char* column(size_t index) const = 0;
|
||||||
[[nodiscard]] virtual bool fetch() = 0;
|
[[nodiscard]] virtual bool fetch() = 0;
|
||||||
|
|
||||||
|
const record& prototype() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
explicit query_result_impl(record prototype);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
size_t column_index_ = 0;
|
size_t column_index_ = 0;
|
||||||
|
record prototype_;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,8 +29,8 @@ public:
|
||||||
query_update_intermediate update(const std::string &table);
|
query_update_intermediate update(const std::string &table);
|
||||||
query_delete_intermediate remove();
|
query_delete_intermediate remove();
|
||||||
|
|
||||||
query_result<record> fetch(const std::string &sql);
|
[[nodiscard]] query_result<record> fetch(const std::string &sql) const;
|
||||||
std::pair<size_t, std::string> execute(const std::string &sql);
|
[[nodiscard]] std::pair<size_t, std::string> execute(const std::string &sql) const;
|
||||||
|
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
void attach(const std::string &table_name)
|
void attach(const std::string &table_name)
|
||||||
|
|
@ -40,6 +40,11 @@ public:
|
||||||
|
|
||||||
[[nodiscard]] const table_repository& tables() const;
|
[[nodiscard]] const table_repository& tables() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class query_select_finish;
|
||||||
|
|
||||||
|
[[nodiscard]] std::unique_ptr<query_result_impl> call_fetch(const std::string &sql) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
connection_pool<connection> &pool_;
|
connection_pool<connection> &pool_;
|
||||||
query_builder query_;
|
query_builder query_;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#ifndef QUERY_TABLE_REPOSITORY_HPP
|
#ifndef QUERY_TABLE_REPOSITORY_HPP
|
||||||
#define QUERY_TABLE_REPOSITORY_HPP
|
#define QUERY_TABLE_REPOSITORY_HPP
|
||||||
|
|
||||||
|
#include "matador/sql/column_generator.hpp"
|
||||||
#include "matador/sql/record.hpp"
|
#include "matador/sql/record.hpp"
|
||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
|
@ -20,12 +21,11 @@ class table_repository
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
const table_info& attach(const std::string &table_name, const record &proto)
|
const table_info& attach(const std::string &table_name)
|
||||||
{
|
{
|
||||||
return attach(std::type_index(typeid(Type)), table_name, proto);
|
return attach(std::type_index(typeid(Type)), table_info{table_name, record{column_generator::generate<Type>(*this)}});
|
||||||
}
|
}
|
||||||
|
|
||||||
const table_info& attach(std::type_index ti, const std::string &table_name, const record &proto);
|
|
||||||
const table_info& attach(std::type_index ti, const table_info& table);
|
const table_info& attach(std::type_index ti, const table_info& table);
|
||||||
|
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
#include "matador/sql/column_generator.hpp"
|
#include "matador/sql/column_generator.hpp"
|
||||||
|
#include "matador/sql/table_repository.hpp"
|
||||||
|
|
||||||
namespace matador::sql {
|
namespace matador::sql {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -63,14 +63,25 @@ const connection_info &connection::info() const
|
||||||
return connection_info_;
|
return connection_info_;
|
||||||
}
|
}
|
||||||
|
|
||||||
query_result<record> connection::fetch(const std::string &sql)
|
record connection::describe(const std::string &table_name) const
|
||||||
|
{
|
||||||
|
return std::move(connection_->describe(table_name));
|
||||||
|
}
|
||||||
|
|
||||||
|
query_result<record> connection::fetch(const std::string &sql) const
|
||||||
{
|
{
|
||||||
auto rec = connection_->describe("person");
|
auto rec = connection_->describe("person");
|
||||||
return {connection_->fetch(sql), [rec](){ return new record(rec); }};
|
return {connection_->fetch(sql), [rec](){ return new record(rec); }};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<size_t, std::string> connection::execute(const std::string &sql)
|
std::pair<size_t, std::string> connection::execute(const std::string &sql) const
|
||||||
{
|
{
|
||||||
return {connection_->execute(sql), sql};
|
return {connection_->execute(sql), sql};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<query_result_impl> connection::call_fetch(const std::string &sql) const
|
||||||
|
{
|
||||||
|
return connection_->fetch(sql);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -108,13 +108,13 @@ query_builder& query_builder::select(const std::vector<std::string> &column_name
|
||||||
|
|
||||||
query_parts_.emplace_back(dialect_.token_at(dialect::token_t::SELECT) + " ");
|
query_parts_.emplace_back(dialect_.token_at(dialect::token_t::SELECT) + " ");
|
||||||
|
|
||||||
prototype_.clear();
|
query_.prototype.clear();
|
||||||
|
|
||||||
std::string result;
|
std::string result;
|
||||||
if (column_names.size() < 2) {
|
if (column_names.size() < 2) {
|
||||||
for (const auto &col : column_names) {
|
for (const auto &col : column_names) {
|
||||||
result.append(dialect_.prepare_identifier(col));
|
result.append(dialect_.prepare_identifier(col));
|
||||||
prototype_.append(column{col});
|
query_.prototype.append(column{col});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
auto it = column_names.begin();
|
auto it = column_names.begin();
|
||||||
|
|
@ -122,7 +122,7 @@ query_builder& query_builder::select(const std::vector<std::string> &column_name
|
||||||
for (; it != column_names.end(); ++it) {
|
for (; it != column_names.end(); ++it) {
|
||||||
result.append(", ");
|
result.append(", ");
|
||||||
result.append(dialect_.prepare_identifier(*it));
|
result.append(dialect_.prepare_identifier(*it));
|
||||||
prototype_.append(column{*it});
|
query_.prototype.append(column{*it});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -262,17 +262,20 @@ query_builder& query_builder::values(const std::vector<any_type> &values) {
|
||||||
std::string result{"("};
|
std::string result{"("};
|
||||||
if (values.size() < 2) {
|
if (values.size() < 2) {
|
||||||
for (auto val : values) {
|
for (auto val : values) {
|
||||||
|
query_.host_vars.push_back(val);
|
||||||
std::visit(value_to_string_, val);
|
std::visit(value_to_string_, val);
|
||||||
result.append(value_to_string_.result);
|
result.append(value_to_string_.result);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
auto it = values.begin();
|
auto it = values.begin();
|
||||||
auto val = *it++;
|
auto val = *it++;
|
||||||
|
query_.host_vars.push_back(val);
|
||||||
std::visit(value_to_string_, val);
|
std::visit(value_to_string_, val);
|
||||||
result.append(value_to_string_.result);
|
result.append(value_to_string_.result);
|
||||||
for (; it != values.end(); ++it) {
|
for (; it != values.end(); ++it) {
|
||||||
result.append(", ");
|
result.append(", ");
|
||||||
val = *it;
|
val = *it;
|
||||||
|
query_.host_vars.push_back(val);
|
||||||
std::visit(value_to_string_, val);
|
std::visit(value_to_string_, val);
|
||||||
result.append(value_to_string_.result);
|
result.append(value_to_string_.result);
|
||||||
}
|
}
|
||||||
|
|
@ -403,11 +406,6 @@ std::string query_builder::compile() {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
const record& query_builder::prototype() const
|
|
||||||
{
|
|
||||||
return prototype_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void query_builder::transition_to(query_builder::state_t next)
|
void query_builder::transition_to(query_builder::state_t next)
|
||||||
{
|
{
|
||||||
if (transitions_[state_].count(next) == 0) {
|
if (transitions_[state_].count(next) == 0) {
|
||||||
|
|
@ -419,6 +417,7 @@ void query_builder::transition_to(query_builder::state_t next)
|
||||||
void query_builder::initialize(query_builder::command_t cmd, query_builder::state_t state)
|
void query_builder::initialize(query_builder::command_t cmd, query_builder::state_t state)
|
||||||
{
|
{
|
||||||
command_ = cmd;
|
command_ = cmd;
|
||||||
|
query_ = {};
|
||||||
state_ = state;
|
state_ = state;
|
||||||
query_parts_.clear();
|
query_parts_.clear();
|
||||||
}
|
}
|
||||||
|
|
@ -432,11 +431,9 @@ std::string build_create_column(const column &col, const dialect &d, column_cont
|
||||||
result.append(" NOT NULL");
|
result.append(" NOT NULL");
|
||||||
}
|
}
|
||||||
if (is_constraint_set(col.attributes().options(), utils::constraints::PRIMARY_KEY)) {
|
if (is_constraint_set(col.attributes().options(), utils::constraints::PRIMARY_KEY)) {
|
||||||
// result.append(" PRIMARY KEY");
|
|
||||||
context.primary_keys.emplace_back(col.name());
|
context.primary_keys.emplace_back(col.name());
|
||||||
}
|
}
|
||||||
if (is_constraint_set(col.attributes().options(), utils::constraints::FOREIGN_KEY)) {
|
if (is_constraint_set(col.attributes().options(), utils::constraints::FOREIGN_KEY)) {
|
||||||
// result.append(" FOREIGN KEY");
|
|
||||||
context.foreign_contexts.push_back({col.name(), col.ref_table(), col.ref_column()});
|
context.foreign_contexts.push_back({col.name(), col.ref_table(), col.ref_column()});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,11 @@ record query_select_finish::fetch_one()
|
||||||
return *db().fetch(query().compile()).begin().get();
|
return *db().fetch(query().compile()).begin().get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<query_result_impl> query_select_finish::fetch()
|
||||||
|
{
|
||||||
|
return db().call_fetch(query().compile());
|
||||||
|
}
|
||||||
|
|
||||||
query_intermediate::query_intermediate(session &db, query_builder &query)
|
query_intermediate::query_intermediate(session &db, query_builder &query)
|
||||||
: db_(db), query_(query) {}
|
: db_(db), query_(query) {}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,4 +28,13 @@ query_result_impl::on_attribute(const char *id, any_type &value, data_type_t typ
|
||||||
read_value(id, column_index_++, value, type, attr.size());
|
read_value(id, column_index_++, value, type, attr.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const record& query_result_impl::prototype() const
|
||||||
|
{
|
||||||
|
return prototype_;
|
||||||
|
}
|
||||||
|
|
||||||
|
query_result_impl::query_result_impl(record prototype)
|
||||||
|
: prototype_(std::move(prototype))
|
||||||
|
{}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -16,6 +16,11 @@ record::record(const std::vector<column> &columns)
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::vector<column> &record::columns() const
|
||||||
|
{
|
||||||
|
return columns_;
|
||||||
|
}
|
||||||
|
|
||||||
bool record::has_primary_key() const
|
bool record::has_primary_key() const
|
||||||
{
|
{
|
||||||
return pk_index_ > -1;
|
return pk_index_ > -1;
|
||||||
|
|
@ -30,11 +35,6 @@ const column &record::primary_key() const
|
||||||
return columns_[pk_index_];
|
return columns_[pk_index_];
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<column> &record::columns() const
|
|
||||||
{
|
|
||||||
return columns_;
|
|
||||||
}
|
|
||||||
|
|
||||||
const column &record::at(const std::string &name) const
|
const column &record::at(const std::string &name) const
|
||||||
{
|
{
|
||||||
return columns_by_name_.at(name).first;
|
return columns_by_name_.at(name).first;
|
||||||
|
|
@ -113,7 +113,6 @@ void record::init()
|
||||||
size_t index{0};
|
size_t index{0};
|
||||||
for(auto &col : columns_) {
|
for(auto &col : columns_) {
|
||||||
add_to_map(col, index++);
|
add_to_map(col, index++);
|
||||||
// columns_by_name_.emplace(col.name(), column_index_pair {std::ref(col), index++});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ query_drop_intermediate session::drop()
|
||||||
|
|
||||||
query_select_intermediate session::select(std::initializer_list<std::string> column_names)
|
query_select_intermediate session::select(std::initializer_list<std::string> column_names)
|
||||||
{
|
{
|
||||||
|
|
||||||
return query_select_intermediate{*this, query_.select(column_names)};
|
return query_select_intermediate{*this, query_.select(column_names)};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -40,15 +41,14 @@ query_delete_intermediate session::remove()
|
||||||
return query_delete_intermediate{*this, query_.remove()};
|
return query_delete_intermediate{*this, query_.remove()};
|
||||||
}
|
}
|
||||||
|
|
||||||
query_result<record> session::fetch(const std::string &sql) {
|
query_result<record> session::fetch(const std::string &sql) const
|
||||||
auto c = pool_.acquire();
|
{
|
||||||
if (!c.valid()) {
|
auto res = call_fetch(sql);
|
||||||
throw std::logic_error("no database connection available");
|
auto proto = res->prototype();
|
||||||
}
|
return query_result<record>{std::move(res), [proto]() { return new record(proto); }};
|
||||||
return c->fetch(sql);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<size_t, std::string> session::execute(const std::string &sql) {
|
std::pair<size_t, std::string> session::execute(const std::string &sql) const {
|
||||||
auto c = pool_.acquire();
|
auto c = pool_.acquire();
|
||||||
if (!c.valid()) {
|
if (!c.valid()) {
|
||||||
throw std::logic_error("no database connection available");
|
throw std::logic_error("no database connection available");
|
||||||
|
|
@ -60,4 +60,14 @@ const table_repository& session::tables() const
|
||||||
{
|
{
|
||||||
return table_repository_;
|
return table_repository_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<query_result_impl> session::call_fetch(const std::string &sql) const
|
||||||
|
{
|
||||||
|
auto c = pool_.acquire();
|
||||||
|
if (!c.valid()) {
|
||||||
|
throw std::logic_error("no database connection available");
|
||||||
|
}
|
||||||
|
return c->call_fetch(sql);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -4,11 +4,6 @@
|
||||||
|
|
||||||
namespace matador::sql {
|
namespace matador::sql {
|
||||||
|
|
||||||
const table_info &table_repository::attach(std::type_index ti, const std::string &table_name, const record &proto)
|
|
||||||
{
|
|
||||||
return attach(ti, table_info{table_name, proto});
|
|
||||||
}
|
|
||||||
|
|
||||||
const table_info& table_repository::attach(const std::type_index ti, const table_info& table)
|
const table_info& table_repository::attach(const std::type_index ti, const table_info& table)
|
||||||
{
|
{
|
||||||
return repository_.try_emplace(ti, table).first->second;
|
return repository_.try_emplace(ti, table).first->second;
|
||||||
|
|
|
||||||
|
|
@ -161,12 +161,13 @@ TEST_CASE("Execute select statement with where clause", "[session]") {
|
||||||
.execute();
|
.execute();
|
||||||
REQUIRE(res.first == 1);
|
REQUIRE(res.first == 1);
|
||||||
|
|
||||||
auto result = s.select<person>()
|
// fetch person as record
|
||||||
.from("person")
|
auto result_record = s.select<person>()
|
||||||
.where("id"_col == 7)
|
.from("person")
|
||||||
.fetch_all();
|
.where("id"_col == 7)
|
||||||
|
.fetch_all();
|
||||||
|
|
||||||
for (const auto& i : result) {
|
for (const auto& i : result_record) {
|
||||||
REQUIRE(i.size() == 3);
|
REQUIRE(i.size() == 3);
|
||||||
REQUIRE(i.at(0).name() == "id");
|
REQUIRE(i.at(0).name() == "id");
|
||||||
REQUIRE(i.at(0).type() == data_type_t::type_long_long);
|
REQUIRE(i.at(0).type() == data_type_t::type_long_long);
|
||||||
|
|
@ -179,10 +180,19 @@ TEST_CASE("Execute select statement with where clause", "[session]") {
|
||||||
REQUIRE(i.at(2).value<long long>() == george.age);
|
REQUIRE(i.at(2).value<long long>() == george.age);
|
||||||
}
|
}
|
||||||
|
|
||||||
// REQUIRE(res.str() == R"(SELECT "id", "name", "color" FROM "person" WHERE "id" = 8)");
|
// fetch person as person
|
||||||
|
auto result_person = s.select<person>()
|
||||||
|
.from("person")
|
||||||
|
.where("id"_col == 7)
|
||||||
|
.fetch_all<person>();
|
||||||
|
|
||||||
|
for (const auto& i : result_person) {
|
||||||
|
REQUIRE(i.id == 7);
|
||||||
|
REQUIRE(i.name == "george");
|
||||||
|
REQUIRE(i.age == 45);
|
||||||
|
}
|
||||||
|
|
||||||
s.drop().table("person").execute();
|
s.drop().table("person").execute();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("Execute select statement with order by", "[session]") {
|
TEST_CASE("Execute select statement with order by", "[session]") {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue