added sqlite query result and enhanced column generator and value extractor

This commit is contained in:
2023-11-14 20:21:51 +01:00
parent 4ed01a617d
commit d76ac60278
44 changed files with 1052 additions and 192 deletions
+30 -7
View File
@@ -8,18 +8,38 @@ column::column(std::string name, data_type_t type, utils::field_attributes attr)
, type_(type)
, attributes_(attr) {}
const std::string &column::name() const {
column::column(std::string name, data_type_t type, std::string ref_table, std::string ref_column, utils::field_attributes attr)
: name_(std::move(name))
, type_(type)
, attributes_(attr)
, ref_table_(std::move(ref_table))
, ref_column_(std::move(ref_column)) {}
const std::string &column::name() const
{
return name_;
}
const utils::field_attributes &column::attributes() const {
const utils::field_attributes &column::attributes() const
{
return attributes_;
}
data_type_t column::type() const {
data_type_t column::type() const
{
return type_;
}
const std::string &column::ref_table() const
{
return ref_table_;
}
const std::string &column::ref_column() const
{
return ref_column_;
}
column operator "" _col(const char *name, size_t len)
{
return column(std::string(name, len));
@@ -31,17 +51,20 @@ column make_column( const std::string& name, data_type_t type, utils::field_attr
}
template<>
column make_column<std::string>( const std::string& name, utils::field_attributes attr ) {
column make_column<std::string>( const std::string& name, utils::field_attributes attr )
{
return make_column(name, data_type_traits<std::string>::builtin_type(attr.size()), attr);
}
template<>
column make_fk_column<std::string>( const std::string& name, size_t size ) {
column make_pk_column<std::string>( const std::string& name, size_t size )
{
return make_column<std::string>(name, { size, utils::constraints::FOREIGN_KEY });
}
template<>
column make_pk_column<std::string>( const std::string& name, size_t size ) {
return make_column<std::string>(name, { size, utils::constraints::PRIMARY_KEY | utils::constraints::NOT_NULL});
[[maybe_unused]] column make_fk_column<std::string>(const std::string& name, size_t size, const std::string &ref_table, const std::string &ref_column)
{
return {name, data_type_traits<std::string>::builtin_type(size), ref_table, ref_column, { size, utils::constraints::PRIMARY_KEY | utils::constraints::NOT_NULL}};
}
}
+24 -17
View File
@@ -20,70 +20,77 @@ void column_generator::on_revision(const char *id, unsigned long long int &x)
void column_generator::on_belongs_to(const char *id, utils::identifiable &x, utils::cascade_type)
{
columns_.push_back(fk_column_generator_.generate(id, x));
// x.primary_key().serialize(fk_column_generator)
}
void column_generator::on_has_one(const char *id, utils::identifiable &x, utils::cascade_type)
{
columns_.push_back(fk_column_generator_.generate(id, x));
}
column fk_column_generator::generate(const char *id, utils::identifiable &x)
{
identifiable_ = x;
id_ = id;
x.primary_key().serialize(*this);
return column_;
return column{id, type_, { utils::constraints::FOREIGN_KEY }};
}
template < typename Type >
data_type_t determine_data_type(const Type &)
{
return data_type_traits<Type>::builtin_type(0);
}
data_type_t determine_data_type(const std::string&, size_t size)
{
return data_type_traits<std::string>::builtin_type(size);
}
void fk_column_generator::serialize(short &i, const utils::field_attributes &attributes)
{
column_.
type_ = determine_data_type(i);
}
void fk_column_generator::serialize(int &i, const utils::field_attributes &attributes)
{
type_ = determine_data_type(i);
}
void fk_column_generator::serialize(long &i, const utils::field_attributes &attributes)
{
type_ = determine_data_type(i);
}
void fk_column_generator::serialize(long long int &i, const utils::field_attributes &attributes)
{
type_ = determine_data_type(i);
}
void fk_column_generator::serialize(unsigned short &i, const utils::field_attributes &attributes)
{
type_ = determine_data_type(i);
}
void fk_column_generator::serialize(unsigned int &i, const utils::field_attributes &attributes)
{
type_ = determine_data_type(i);
}
void fk_column_generator::serialize(unsigned long &i, const utils::field_attributes &attributes)
{
type_ = determine_data_type(i);
}
void fk_column_generator::serialize(unsigned long long int &i, const utils::field_attributes &attributes)
{
type_ = determine_data_type(i);
}
void fk_column_generator::serialize(std::string &string, const utils::field_attributes &attributes)
void fk_column_generator::serialize(std::string &x, const utils::field_attributes &attributes)
{
type_ = determine_data_type(x, attributes.size());
}
void fk_column_generator::serialize(utils::null_type_t &type, const utils::field_attributes &attributes)
{
type_ = data_type_t::type_null;
}
}
+21 -4
View File
@@ -3,6 +3,7 @@
#include "matador/sql/backend_provider.hpp"
#include "matador/sql/connection_impl.hpp"
#include <stdexcept>
#include <utility>
namespace matador::sql {
@@ -10,19 +11,35 @@ namespace matador::sql {
connection::connection(connection_info info)
: connection_info_(std::move(info))
{
connection_ = backend_provider::instance().create_connection(connection_info_.type, connection_info_);
connection_.reset(backend_provider::instance().create_connection(connection_info_.type, connection_info_));
}
connection::connection(const std::string& dns)
: connection(connection_info::parse(dns))
{}
connection::connection(const connection &x)
: connection_info_(x.connection_info_)
{
if (x.connection_) {
throw std::runtime_error("couldn't copy connection with valid connection impl");
}
}
connection &connection::operator=(const connection &x) {
connection_info_ = x.connection_info_;
if (x.connection_) {
throw std::runtime_error("couldn't copy connection with valid connection impl");
}
return *this;
}
connection::~connection()
{
if (connection_->is_open()) {
connection_->close();
}
backend_provider::instance().destroy_connection(connection_info_.type, connection_);
backend_provider::instance().destroy_connection(connection_info_.type, connection_.release());
connection_ = nullptr;
}
@@ -48,11 +65,11 @@ const connection_info &connection::info() const
query_result<record> connection::fetch(const std::string &sql)
{
return {sql};
return query_result<record>(connection_->fetch(sql));
}
std::pair<size_t, std::string> connection::execute(const std::string &sql)
{
return {0, sql};
return {connection_->execute(sql), sql};
}
}
+10
View File
@@ -0,0 +1,10 @@
#include "matador/sql/fk_value_extractor.hpp"
namespace matador::sql::detail {
void fk_value_extractor::on_primary_key(const char *, std::string &pk, size_t)
{
value_ = pk;
}
}
+16
View File
@@ -0,0 +1,16 @@
#include "matador/sql/key_value_generator.hpp"
#include "matador/sql/value_extractor.hpp"
namespace matador::sql {
void key_value_generator::on_primary_key(const char *id, std::string &x, size_t)
{
result_.emplace_back(id, x);
}
void key_value_generator::on_revision(const char *id, unsigned long long int &x)
{
result_.emplace_back(id, x);
}
}
+58 -9
View File
@@ -1,6 +1,8 @@
#include "matador/sql/query_builder.hpp"
#include "matador/sql/dialect.hpp"
#include "matador/utils/string.hpp"
#include <stdexcept>
namespace matador::sql {
@@ -18,7 +20,6 @@ void any_type_to_string_visitor::to_string(std::string &val)
}
}
std::string build_create_column(const column &col, const dialect &d);
// poor mens state machine
// but does the job for query
@@ -148,6 +149,21 @@ query_builder& query_builder::table(const std::string &table, std::initializer_l
return this->table(table, std::vector<column>{columns});
}
struct fk_context
{
std::string column;
std::string ref_table;
std::string ref_column;
};
struct column_context
{
std::vector<std::string> primary_keys;
std::vector<fk_context> foreign_contexts;
};
std::string build_create_column(const column &col, const dialect &d, column_context &context);
query_builder &query_builder::table(const std::string &table, const std::vector<column> &columns) {
transition_to(state_t::QUERY_TABLE_CREATE);
@@ -155,19 +171,31 @@ query_builder &query_builder::table(const std::string &table, const std::vector<
std::string result = "(";
column_context context;
if (columns.size() < 2) {
for (const auto &col : columns) {
result.append(build_create_column(col, dialect_));
result.append(build_create_column(col, dialect_, context));
}
} else {
auto it = columns.begin();
result.append(build_create_column(*it++, dialect_));
result.append(build_create_column(*it++, dialect_, context));
for (; it != columns.end(); ++it) {
result.append(", ");
result.append(build_create_column(*it, dialect_));
result.append(build_create_column(*it, dialect_, context));
}
}
if (!context.primary_keys.empty()) {
result.append(", CONSTRAINT PK_" + table + " PRIMARY KEY (" + utils::join(context.primary_keys, ", ") + ")");
}
for (const auto &fk : context.foreign_contexts) {
result += ", CONSTRAINT FK_" + table;
result += "_" + fk.column;
result += " FOREIGN KEY (" + fk.column + ")";
result += " REFERENCES " + fk.ref_table + "(" + fk.ref_column + ")";
}
result += ")";
query_parts_.emplace_back(result);
return *this;
@@ -181,7 +209,13 @@ query_builder& query_builder::table(const std::string &table) {
return *this;
}
query_builder& query_builder::into(const std::string &table, std::initializer_list<std::string> column_names) {
query_builder& query_builder::into(const std::string &table, std::initializer_list<std::string> column_names)
{
return into(table, std::vector<std::string>{column_names});
}
query_builder &query_builder::into(const std::string &table, const std::vector<std::string> &column_names)
{
transition_to(state_t::QUERY_INTO);
query_parts_.emplace_back(" " + dialect_.token_at(dialect::token_t::INTO) + " " + dialect_.prepare_identifier(table) + " ");
@@ -205,7 +239,12 @@ query_builder& query_builder::into(const std::string &table, std::initializer_li
return *this;
}
query_builder& query_builder::values(std::initializer_list<any_type> values) {
query_builder& query_builder::values(std::initializer_list<any_type> values)
{
return this->values(std::vector<any_type>{values});
}
query_builder& query_builder::values(const std::vector<any_type> &values) {
transition_to(state_t::QUERY_VALUES);
query_parts_.emplace_back(" " + dialect_.token_at(dialect::token_t::VALUES) + " ");
@@ -252,7 +291,12 @@ query_builder &query_builder::on(const std::string &column, const std::string &j
return *this;
}
query_builder& query_builder::set(std::initializer_list<key_value_pair> key_values) {
query_builder &query_builder::set(std::initializer_list<key_value_pair> key_values)
{
return set(std::vector<key_value_pair>{key_values});
}
query_builder& query_builder::set(const std::vector<key_value_pair> &key_values) {
transition_to(state_t::QUERY_SET);
query_parts_.emplace_back(" " + dialect_.token_at(dialect::token_t::SET) + " ");
@@ -364,7 +408,7 @@ void query_builder::initialize(query_builder::command_t cmd, query_builder::stat
query_parts_.clear();
}
std::string build_create_column(const column &col, const dialect &d) {
std::string build_create_column(const column &col, const dialect &d, column_context &context) {
std::string result = d.prepare_identifier(col.name()) + " " + d.data_type_at(col.type());
if (col.attributes().size() > 0) {
result.append("(" + std::to_string(col.attributes().size()) +")");
@@ -373,7 +417,12 @@ std::string build_create_column(const column &col, const dialect &d) {
result.append(" NOT NULL");
}
if (is_constraint_set(col.attributes().options(), utils::constraints::PRIMARY_KEY)) {
result.append(" PRIMARY KEY");
// result.append(" PRIMARY KEY");
context.primary_keys.emplace_back(col.name());
}
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()});
}
return result;
+3 -4
View File
@@ -1,6 +1,5 @@
#include "matador/sql/query_intermediates.hpp"
#include "matador/sql/session.hpp"
#include "matador/sql/query_builder.hpp"
namespace matador::sql {
session &query_intermediate::db()
@@ -20,7 +19,7 @@ query_result<record> query_select_finish::fetch_all()
record query_select_finish::fetch_one()
{
return db().fetch(query().compile()).begin();
return *db().fetch(query().compile()).begin().get();
}
query_intermediate::query_intermediate(session &db, query_builder &query)
@@ -131,8 +130,8 @@ query_execute_where_intermediate query_delete_from_intermediate::where(const bas
return {db(), query().where(cond)};
}
query_delete_from_intermediate query_delete_intermediate::from(const std::string &table, const std::string &as)
query_delete_from_intermediate query_delete_intermediate::from(const std::string &table)
{
return {db(), query().from(table, as)};
return {db(), query().from(table)};
}
}
+10
View File
@@ -22,4 +22,14 @@ void query_result_impl::on_attribute(const char *id, std::string &value, const u
read_value(id, column_index_++, value, attr.size());
}
void query_result_impl::on_belongs_to(const char *id, utils::identifiable &x, utils::cascade_type)
{
}
void query_result_impl::on_has_one(const char *id, utils::identifiable &x, utils::cascade_type)
{
}
}
+29
View File
@@ -0,0 +1,29 @@
#include "matador/sql/value_extractor.hpp"
namespace matador::sql {
value_extractor::value_extractor(std::vector<any_type> &values)
: values_(values)
{}
void value_extractor::on_primary_key(const char *, std::string &pk, size_t)
{
append(pk);
}
void value_extractor::on_revision(const char *, unsigned long long int &rev)
{
append(rev);
}
void value_extractor::on_attribute(const char *, char *x, const utils::field_attributes &)
{
append(x);
}
void value_extractor::on_attribute(const char *, std::string &x, const utils::field_attributes &)
{
append(x);
}
}
-36
View File
@@ -1,36 +0,0 @@
#include "matador/sql/value_generator.hpp"
namespace matador::sql {
value_generator::value_generator(std::vector<any_type> &values)
: values_(values)
{}
void value_generator::on_primary_key(const char *, std::string &pk, size_t)
{
append(pk);
}
void value_generator::on_revision(const char *, unsigned long long int &rev)
{
append(rev);
}
void value_generator::on_attribute(const char *, char *x, const utils::field_attributes &)
{
append(x);
}
void value_generator::on_attribute(const char *, std::string &x, const utils::field_attributes &)
{
append(x);
}
void value_generator::on_belongs_to(const char *, utils::identifiable &x, utils::cascade_type) {
}
void value_generator::on_has_one(const char *, utils::identifiable &x, utils::cascade_type) {
}
}