entity query and record progress

This commit is contained in:
2024-03-04 20:09:39 +01:00
parent 830185c3c5
commit be610ffcad
31 changed files with 294 additions and 50 deletions
+1 -1
View File
@@ -37,7 +37,7 @@ public:
size_t execute(const std::string &stmt) override; size_t execute(const std::string &stmt) override;
sql::record describe(const std::string& table) override; std::vector<sql::column_definition> describe(const std::string& table) override;
bool exists(const std::string &schema_name, const std::string &table_name) override; bool exists(const std::string &schema_name, const std::string &table_name) override;
+5 -5
View File
@@ -181,13 +181,13 @@ std::unique_ptr<sql::query_result_impl> mysql_connection::fetch(const std::strin
auto field_count = mysql_num_fields(result); auto field_count = mysql_num_fields(result);
auto fields = mysql_fetch_fields(result); auto fields = mysql_fetch_fields(result);
sql::record prototype; std::vector<sql::column_definition> prototype;
for (unsigned i = 0; i < field_count; ++i) { for (unsigned i = 0; i < field_count; ++i) {
auto type = to_type(fields[i].type, fields[i].flags); auto type = to_type(fields[i].type, fields[i].flags);
auto options = to_constraints(fields[i].flags); auto options = to_constraints(fields[i].flags);
auto null_opt = to_null_option(fields[i].flags); auto null_opt = to_null_option(fields[i].flags);
prototype.append({fields[i].name, type, options, null_opt}); prototype.emplace_back(fields[i].name, type, options, null_opt);
} }
return std::move(std::make_unique<sql::query_result_impl>(std::make_unique<mysql_result_reader>(result, field_count), std::move(prototype))); return std::move(std::make_unique<sql::query_result_impl>(std::make_unique<mysql_result_reader>(result, field_count), std::move(prototype)));
@@ -216,7 +216,7 @@ size_t mysql_connection::execute(const std::string &stmt)
return mysql_affected_rows(mysql_.get()); return mysql_affected_rows(mysql_.get());
} }
sql::record mysql_connection::describe(const std::string &table) std::vector<sql::column_definition> mysql_connection::describe(const std::string &table)
{ {
std::string stmt("SHOW COLUMNS FROM " + table); std::string stmt("SHOW COLUMNS FROM " + table);
@@ -230,7 +230,7 @@ sql::record mysql_connection::describe(const std::string &table)
} }
mysql_result_reader reader(result, mysql_num_fields(result)); mysql_result_reader reader(result, mysql_num_fields(result));
sql::record prototype; std::vector<sql::column_definition> prototype;
while (reader.fetch()) { while (reader.fetch()) {
char *end = nullptr; char *end = nullptr;
@@ -242,7 +242,7 @@ sql::record mysql_connection::describe(const std::string &table)
if (strtoul(reader.column(2), &end, 10) == 0) { if (strtoul(reader.column(2), &end, 10) == 0) {
null_opt = sql::null_option::NOT_NULL; null_opt = sql::null_option::NOT_NULL;
} }
prototype.append({name, typeinfo.type, {typeinfo.size}, null_opt, prototype.size()}); prototype.push_back({name, typeinfo.type, {typeinfo.size}, null_opt, prototype.size()});
} }
return prototype; return prototype;
@@ -33,7 +33,7 @@ public:
size_t execute(const std::string &stmt) override; size_t execute(const std::string &stmt) override;
sql::record describe(const std::string& table) override; std::vector<sql::column_definition> describe(const std::string& table) override;
bool exists(const std::string &schema_name, const std::string &table_name) override; bool exists(const std::string &schema_name, const std::string &table_name) override;
@@ -51,14 +51,13 @@ std::unique_ptr<sql::query_result_impl> postgres_connection::fetch(const std::st
throw_postgres_error(res, conn_, "postgres", stmt); throw_postgres_error(res, conn_, "postgres", stmt);
sql::record prototype; std::vector<sql::column_definition> prototype;
auto num_col = PQnfields(res); auto num_col = PQnfields(res);
for (int i = 0; i < num_col; ++i) { for (int i = 0; i < num_col; ++i) {
const char *col_name = PQfname(res, i); const char *col_name = PQfname(res, i);
auto type = PQftype(res, i); auto type = PQftype(res, i);
auto size = PQfmod(res, i); auto size = PQfmod(res, i);
// std::cout << "column " << col_name << ", type " << type << " (size: " << size << ")\n"; prototype.emplace_back(col_name);
prototype.append(sql::column_definition{col_name});
} }
return std::move(std::make_unique<sql::query_result_impl>(std::make_unique<postgres_result_reader>(res), std::move(prototype))); return std::move(std::make_unique<sql::query_result_impl>(std::make_unique<postgres_result_reader>(res), std::move(prototype)));
} }
@@ -131,7 +130,7 @@ sql::data_type_t string2type(const char *type)
} }
} }
sql::record postgres_connection::describe(const std::string &table) std::vector<sql::column_definition> postgres_connection::describe(const std::string &table)
{ {
std::string stmt( std::string stmt(
"SELECT ordinal_position, column_name, udt_name, data_type, is_nullable, column_default FROM information_schema.columns WHERE table_schema='public' AND table_name='" + table + "'"); "SELECT ordinal_position, column_name, udt_name, data_type, is_nullable, column_default FROM information_schema.columns WHERE table_schema='public' AND table_name='" + table + "'");
@@ -141,7 +140,7 @@ sql::record postgres_connection::describe(const std::string &table)
throw_postgres_error(res, conn_, "postgres", stmt); throw_postgres_error(res, conn_, "postgres", stmt);
postgres_result_reader reader(res); postgres_result_reader reader(res);
sql::record prototype; std::vector<sql::column_definition> prototype;
while (reader.fetch()) { while (reader.fetch()) {
char *end = nullptr; char *end = nullptr;
// Todo: Handle error // Todo: Handle error
@@ -156,7 +155,7 @@ sql::record postgres_connection::describe(const std::string &table)
null_opt = sql::null_option::NOT_NULL; null_opt = sql::null_option::NOT_NULL;
} }
// f.default_value(res->column(4)); // f.default_value(res->column(4));
prototype.append({name, type, utils::null_attributes, null_opt, index}); prototype.emplace_back(name, type, utils::null_attributes, null_opt, index);
} }
return std::move(prototype); return std::move(prototype);
@@ -33,14 +33,14 @@ public:
size_t execute(const std::string &stmt) override; size_t execute(const std::string &stmt) override;
sql::record describe(const std::string& table) override; std::vector<sql::column_definition> describe(const std::string& table) override;
bool exists(const std::string &schema_name, const std::string &table_name) override; bool exists(const std::string &schema_name, const std::string &table_name) override;
private: private:
struct fetch_context struct fetch_context
{ {
sql::record prototype; std::vector<sql::column_definition> prototype;
sqlite_result_reader::rows rows; sqlite_result_reader::rows rows;
}; };
+4 -4
View File
@@ -65,7 +65,7 @@ int sqlite_connection::parse_result(void* param, int column_count, char** values
if (context->prototype.empty()) { if (context->prototype.empty()) {
for(int i = 0; i < column_count; ++i) { for(int i = 0; i < column_count; ++i) {
context->prototype.append(sql::column_definition{columns[i]}); context->prototype.emplace_back(columns[i]);
} }
} }
@@ -144,12 +144,12 @@ sql::data_type_t string2type(const char *type)
} }
} }
sql::record sqlite_connection::describe(const std::string& table) std::vector<sql::column_definition> sqlite_connection::describe(const std::string& table)
{ {
const auto result = fetch_internal("PRAGMA table_info(" + table + ")"); const auto result = fetch_internal("PRAGMA table_info(" + table + ")");
sqlite_result_reader reader(result.rows, result.prototype.size()); sqlite_result_reader reader(result.rows, result.prototype.size());
sql::record prototype; std::vector<sql::column_definition> prototype;
while (reader.fetch()) { while (reader.fetch()) {
char *end = nullptr; char *end = nullptr;
// Todo: add index to column // Todo: add index to column
@@ -163,7 +163,7 @@ sql::record sqlite_connection::describe(const std::string& table)
null_opt = sql::null_option::NOT_NULL; null_opt = sql::null_option::NOT_NULL;
} }
// f.default_value(res->column(4)); // f.default_value(res->column(4));
prototype.append({name, type, utils::null_attributes, null_opt, index}); prototype.emplace_back(name, type, utils::null_attributes, null_opt, index);
} }
return std::move(prototype); return std::move(prototype);
+11 -2
View File
@@ -37,10 +37,19 @@ private:
using namespace matador; using namespace matador;
TEST_CASE_METHOD(SessionFixture, "Session relation test", "[session][relation]") { TEST_CASE_METHOD(SessionFixture, "Session relation test", "[session][relation]") {
using namespace matador;
ses.attach<matador::test::airplane>("airplane"); ses.attach<test::airplane>("airplane");
ses.create_schema(); ses.create_schema();
ses.insert<test::airplane>(1, "Boeing", "A380"); ses.insert<test::airplane>(1, "Boeing", "A380");
REQUIRE(true); REQUIRE(true);
}
TEST_CASE_METHOD(SessionFixture, "Find object with id", "[session][find]") {
ses.attach<matador::test::airplane>("airplane");
ses.create_schema();
auto a380 = ses.insert<test::airplane>(1, "Boeing", "A380");
ses.find<test::airplane>(1);
} }
+11
View File
@@ -10,6 +10,17 @@
namespace matador::sql { namespace matador::sql {
using any_db_type = std::variant<
long long,
unsigned long long,
double,
bool,
const char*,
std::string,
utils::blob,
placeholder,
nullptr_t>;
using any_type = std::variant< using any_type = std::variant<
char, short, int, long, long long, char, short, int, long, long long,
unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long, unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long,
+3 -2
View File
@@ -9,7 +9,6 @@
#include "matador/sql/query_result.hpp" #include "matador/sql/query_result.hpp"
#include "matador/sql/record.hpp" #include "matador/sql/record.hpp"
#include "matador/sql/statement.hpp" #include "matador/sql/statement.hpp"
#include "matador/sql/schema.hpp"
#include "matador/utils/logger.hpp" #include "matador/utils/logger.hpp"
@@ -17,6 +16,8 @@
namespace matador::sql { namespace matador::sql {
class schema;
class connection class connection
{ {
public: public:
@@ -32,7 +33,7 @@ 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; [[nodiscard]] std::vector<sql::column_definition> describe(const std::string &table_name) const;
[[nodiscard]] bool exists(const std::string &schema_name, const std::string &table_name) const; [[nodiscard]] bool exists(const std::string &schema_name, const std::string &table_name) const;
[[nodiscard]] bool exists(const std::string &table_name) const; [[nodiscard]] bool exists(const std::string &table_name) const;
+1 -1
View File
@@ -26,7 +26,7 @@ public:
virtual std::unique_ptr<query_result_impl> fetch(const std::string &stmt) = 0; virtual std::unique_ptr<query_result_impl> fetch(const std::string &stmt) = 0;
virtual std::unique_ptr<statement_impl> prepare(query_context context) = 0; virtual std::unique_ptr<statement_impl> prepare(query_context context) = 0;
virtual record describe(const std::string &table) = 0; virtual std::vector<sql::column_definition> describe(const std::string &table) = 0;
virtual bool exists(const std::string &schema_name, const std::string &table_name) = 0; virtual bool exists(const std::string &schema_name, const std::string &table_name) = 0;
protected: protected:
@@ -0,0 +1,62 @@
#ifndef QUERY_ENTITY_QUERY_BUILDER_HPP
#define QUERY_ENTITY_QUERY_BUILDER_HPP
#include "matador/sql/query_context.hpp"
namespace matador::sql {
template < typename PrimaryKeyType >
class entity_query_builder
{
public:
// determine pk
// collect eager relations for joins
template<class EntityType>
query_context build() {
EntityType obj;
matador::utils::access::process(*this, obj);
return {};
}
template < class V >
void on_primary_key(const char *id, V &, typename std::enable_if<std::is_integral<V>::value && !std::is_same<bool, V>::value>::type* = 0)
{
}
void on_primary_key(const char *id, std::string &, size_t)
{
}
void on_revision(const char * /*id*/, unsigned long long &/*rev*/) {}
template<typename Type>
void on_attribute(const char * /*id*/, Type &, const utils::field_attributes &/*attr*/ = utils::null_attributes) {}
template<class Pointer>
void on_belongs_to(const char *id, Pointer &, const utils::foreign_attributes &/*attr*/)
{
}
template<class Pointer>
void on_has_one(const char *id, Pointer &, const utils::foreign_attributes &attr)
{
}
template<class ContainerType>
void on_has_many(const char *, ContainerType &, const char *, const char *, const utils::foreign_attributes &attr)
{
}
template<class ContainerType>
void on_has_many(const char *id, ContainerType &c, const utils::foreign_attributes &attr)
{
on_has_many(id, c, "", "", attr);
}
private:
PrimaryKeyType pk_;
};
}
#endif //QUERY_ENTITY_QUERY_BUILDER_HPP
+37
View File
@@ -0,0 +1,37 @@
#ifndef QUERY_FIELD_HPP
#define QUERY_FIELD_HPP
#include "matador/sql/any_type.hpp"
#include "matador/sql/any_type_to_visitor.hpp"
#include <string>
namespace matador::sql {
class field
{
public:
[[nodiscard]] const std::string& name() const;
template<class Type>
Type as() const
{
const Type* ptr= std::get_if<Type>(&value_);
if (ptr) {
return *ptr;
}
any_type_to_visitor<Type> visitor;
std::visit(visitor, const_cast<any_type&>(value_));
return visitor.result;
}
friend std::ostream& operator<<(std::ostream &out, const field &col);
private:
std::string name_;
any_type value_;
};
}
#endif //QUERY_FIELD_HPP
+1 -1
View File
@@ -16,7 +16,7 @@ public:
size_t execute(const std::string &stmt) override; size_t execute(const std::string &stmt) override;
std::unique_ptr<query_result_impl> fetch(const std::string &stmt) override; std::unique_ptr<query_result_impl> fetch(const std::string &stmt) override;
std::unique_ptr<statement_impl> prepare(query_context context) override; std::unique_ptr<statement_impl> prepare(query_context context) override;
record describe(const std::string &table) override; std::vector<sql::column_definition> describe(const std::string &table) override;
bool exists(const std::string &schema_name, const std::string &table_name) override; bool exists(const std::string &schema_name, const std::string &table_name) override;
private: private:
+1 -1
View File
@@ -11,7 +11,7 @@ struct query_context
std::string sql; std::string sql;
std::string command_name; std::string command_name;
sql::table table{""}; sql::table table{""};
record prototype; std::vector<column_definition> prototype;
std::vector<std::string> result_vars; std::vector<std::string> result_vars;
std::vector<std::string> bind_vars; std::vector<std::string> bind_vars;
}; };
+4 -4
View File
@@ -107,13 +107,13 @@ private:
namespace detail { namespace detail {
template < typename Type > template < typename Type >
Type* create_prototype(const record &/*prototype*/) Type* create_prototype(const std::vector<column_definition> &/*prototype*/)
{ {
return new Type{}; return new Type{};
} }
template <> template <>
record* create_prototype<record>(const record &prototype); record* create_prototype<record>(const std::vector<column_definition> &prototype);
} }
@@ -128,7 +128,7 @@ 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, record record_prototype) query_result(std::unique_ptr<query_result_impl> impl, std::vector<column_definition> record_prototype)
: record_prototype_(std::move(record_prototype)) : record_prototype_(std::move(record_prototype))
, impl_(std::move(impl)) {} , impl_(std::move(impl)) {}
@@ -151,7 +151,7 @@ private:
} }
private: private:
record record_prototype_; std::vector<column_definition> record_prototype_;
std::unique_ptr<query_result_impl> impl_; std::unique_ptr<query_result_impl> impl_;
}; };
+3 -3
View File
@@ -55,7 +55,7 @@ private:
class query_result_impl class query_result_impl
{ {
public: public:
query_result_impl(std::unique_ptr<query_result_reader> &&reader, record prototype); query_result_impl(std::unique_ptr<query_result_reader> &&reader, std::vector<column_definition> prototype);
template<typename ValueType> template<typename ValueType>
void on_primary_key(const char *id, ValueType &value, typename std::enable_if<std::is_integral<ValueType>::value && !std::is_same<bool, ValueType>::value>::type* = 0) void on_primary_key(const char *id, ValueType &value, typename std::enable_if<std::is_integral<ValueType>::value && !std::is_same<bool, ValueType>::value>::type* = 0)
@@ -110,11 +110,11 @@ public:
return true; return true;
} }
[[nodiscard]] const record& prototype() const; [[nodiscard]] const std::vector<column_definition>& prototype() const;
protected: protected:
size_t column_index_ = 0; size_t column_index_ = 0;
record prototype_; std::vector<column_definition> prototype_;
std::unique_ptr<query_result_reader> reader_; std::unique_ptr<query_result_reader> reader_;
detail::pk_reader pk_reader_; detail::pk_reader pk_reader_;
}; };
+23 -1
View File
@@ -31,6 +31,28 @@ public:
return insert(new Type(std::forward<Args>(args)...)); return insert(new Type(std::forward<Args>(args)...));
} }
template<typename Type, typename PrimaryKeyType>
entity<Type> find(const PrimaryKeyType &pk) {
auto c = pool_.acquire();
if (!c.valid()) {
throw std::logic_error("no database connection available");
}
// collect all columns
// - evaluate fetch::Eager flag for relations
// build pk where condition
// - check if type has pk
// - check type
// pk_condition_builder<Type> builder;
// auto cond = builder.build(pk);
// create query with relations as requested
//
// c->query(*schema_).select<Type>().from("xyz").where().fetch_all();
return {};
}
template<typename Type> template<typename Type>
void drop_table(); void drop_table();
void drop_table(const std::string &table_name); void drop_table(const std::string &table_name);
@@ -40,7 +62,7 @@ public:
[[nodiscard]] size_t execute(const std::string &sql) const; [[nodiscard]] size_t execute(const std::string &sql) const;
statement prepare(query_context q) const; statement prepare(query_context q) const;
record describe_table(const std::string &table_name) const; std::vector<sql::column_definition> describe_table(const std::string &table_name) const;
bool table_exists(const std::string &table_name) const; bool table_exists(const std::string &table_name) const;
[[nodiscard]] const schema& tables() const; [[nodiscard]] const schema& tables() const;
+3
View File
@@ -35,6 +35,7 @@ set(SQL_SOURCES
sql/noop_connection.cpp sql/noop_connection.cpp
sql/query_part.cpp sql/query_part.cpp
sql/any_type_to_string_visitor.cpp sql/any_type_to_string_visitor.cpp
sql/field.cpp
) )
set(SQL_HEADER set(SQL_HEADER
@@ -86,6 +87,8 @@ set(SQL_HEADER
../include/matador/sql/query_part.hpp ../include/matador/sql/query_part.hpp
../include/matador/sql/any_type_to_string_visitor.hpp ../include/matador/sql/any_type_to_string_visitor.hpp
../include/matador/sql/query_helper.hpp ../include/matador/sql/query_helper.hpp
../include/matador/sql/field.hpp
../include/matador/sql/entity_query_builder.hpp
) )
set(QUERY_SOURCES set(QUERY_SOURCES
+14 -3
View File
@@ -2,7 +2,9 @@
#include "matador/sql/backend_provider.hpp" #include "matador/sql/backend_provider.hpp"
#include "matador/sql/connection_impl.hpp" #include "matador/sql/connection_impl.hpp"
#include "matador/sql/schema.hpp"
#include <algorithm>
#include <stdexcept> #include <stdexcept>
#include <utility> #include <utility>
@@ -68,7 +70,7 @@ const connection_info &connection::info() const
return connection_info_; return connection_info_;
} }
record connection::describe(const std::string &table_name) const std::vector<sql::column_definition> connection::describe(const std::string &table_name) const
{ {
return std::move(connection_->describe(table_name)); return std::move(connection_->describe(table_name));
} }
@@ -94,12 +96,21 @@ sql::query connection::query(const sql::schema &schema) const
return sql::query(*const_cast<connection*>(this), schema); return sql::query(*const_cast<connection*>(this), schema);
} }
bool is_unknown(const std::vector<sql::column_definition> &columns) {
return std::all_of(std::begin(columns), std::end(columns), [](const auto &col) {
return col.type() == data_type_t::type_unknown;
});
}
query_result<record> connection::fetch(const query_context &q) const query_result<record> connection::fetch(const query_context &q) const
{ {
if (q.prototype.empty() || q.prototype.unknown()) { if (q.prototype.empty() || is_unknown(q.prototype)) {
const auto table_prototype = describe(q.table.name); const auto table_prototype = describe(q.table.name);
for (auto &col : q.prototype) { for (auto &col : q.prototype) {
if (const auto rit = table_prototype.find(col.name()); col.type() == data_type_t::type_unknown && rit != table_prototype.end()) { const auto rit = std::find_if(std::begin(table_prototype), std::end(table_prototype), [&col](const auto &value) {
return value.name() == col.name();
});
if (col.type() == data_type_t::type_unknown && rit != table_prototype.end()) {
const_cast<column_definition&>(col).type(rit->type()); const_cast<column_definition&>(col).type(rit->type());
} }
} }
+15
View File
@@ -0,0 +1,15 @@
#include "matador/sql/field.hpp"
namespace matador::sql {
const std::string &field::name() const
{
return name_;
}
std::ostream &operator<<(std::ostream &out, const field &col)
{
return out;
}
}
+1 -1
View File
@@ -39,7 +39,7 @@ std::unique_ptr<statement_impl> noop_connection::prepare(query_context context)
return {}; return {};
} }
record noop_connection::describe(const std::string &table) std::vector<sql::column_definition> noop_connection::describe(const std::string &table)
{ {
return {}; return {};
} }
+3 -3
View File
@@ -141,18 +141,18 @@ query_builder &query_builder::select(const std::vector<column> &columns)
for (const auto &col: columns) { for (const auto &col: columns) {
result.append(dialect_.prepare_identifier(col)); result.append(dialect_.prepare_identifier(col));
query_.result_vars.emplace_back(col.name); query_.result_vars.emplace_back(col.name);
query_.prototype.append(column_definition{col.name}); query_.prototype.emplace_back(col.name);
} }
} else { } else {
auto it = columns.begin(); auto it = columns.begin();
result.append(dialect_.prepare_identifier(*it)); result.append(dialect_.prepare_identifier(*it));
query_.result_vars.emplace_back(it->name); query_.result_vars.emplace_back(it->name);
query_.prototype.append(column_definition{(*it++).name}); query_.prototype.emplace_back((*it++).name);
for (; it != columns.end(); ++it) { for (; it != columns.end(); ++it) {
result.append(", "); result.append(", ");
result.append(dialect_.prepare_identifier(*it)); result.append(dialect_.prepare_identifier(*it));
query_.result_vars.emplace_back(it->name); query_.result_vars.emplace_back(it->name);
query_.prototype.append(column_definition{(*it).name}); query_.prototype.emplace_back((*it).name);
} }
} }
+3 -3
View File
@@ -33,18 +33,18 @@ void query_compiler::visit(query_select_part &select_part)
for (const auto &col: columns) { for (const auto &col: columns) {
result.append(dialect_.prepare_identifier(col)); result.append(dialect_.prepare_identifier(col));
query_.result_vars.emplace_back(col.name); query_.result_vars.emplace_back(col.name);
query_.prototype.append(column_definition{col.name}); query_.prototype.emplace_back(col.name);
} }
} else { } else {
auto it = columns.begin(); auto it = columns.begin();
result.append(dialect_.prepare_identifier(*it)); result.append(dialect_.prepare_identifier(*it));
query_.result_vars.emplace_back(it->name); query_.result_vars.emplace_back(it->name);
query_.prototype.append(column_definition{(*it++).name}); query_.prototype.emplace_back((*it++).name);
for (; it != columns.end(); ++it) { for (; it != columns.end(); ++it) {
result.append(", "); result.append(", ");
result.append(dialect_.prepare_identifier(*it)); result.append(dialect_.prepare_identifier(*it));
query_.result_vars.emplace_back(it->name); query_.result_vars.emplace_back(it->name);
query_.prototype.append(column_definition{(*it).name}); query_.prototype.emplace_back((*it).name);
} }
} }
+1 -1
View File
@@ -3,7 +3,7 @@
namespace matador::sql::detail { namespace matador::sql::detail {
template<> template<>
record *create_prototype<record>(const record &prototype) record *create_prototype<record>(const std::vector<column_definition> &prototype)
{ {
return new record{prototype}; return new record{prototype};
} }
+2 -2
View File
@@ -11,7 +11,7 @@ void detail::pk_reader::on_primary_key(const char *id, std::string &value, size_
data_type_traits<std::string>::read_value(reader_, id, column_index_++, value, size); data_type_traits<std::string>::read_value(reader_, id, column_index_++, value, size);
} }
query_result_impl::query_result_impl(std::unique_ptr<query_result_reader> &&reader, record prototype) query_result_impl::query_result_impl(std::unique_ptr<query_result_reader> &&reader, std::vector<column_definition> prototype)
: prototype_(std::move(prototype)) : prototype_(std::move(prototype))
, reader_(std::move(reader)) , reader_(std::move(reader))
, pk_reader_(*reader_) , pk_reader_(*reader_)
@@ -44,7 +44,7 @@ query_result_impl::on_attribute(const char *id, any_type &value, data_type_t typ
reader_->read_value(id, column_index_++, value, type, attr.size()); reader_->read_value(id, column_index_++, value, type, attr.size());
} }
const record& query_result_impl::prototype() const const std::vector<column_definition>& query_result_impl::prototype() const
{ {
return prototype_; return prototype_;
} }
+1 -1
View File
@@ -71,7 +71,7 @@ statement session::prepare(query_context q) const
return c->prepare(std::move(q)); return c->prepare(std::move(q));
} }
record session::describe_table(const std::string &table_name) const std::vector<sql::column_definition> session::describe_table(const std::string &table_name) const
{ {
auto c = pool_.acquire(); auto c = pool_.acquire();
if (!c.valid()) { if (!c.valid()) {
+4 -1
View File
@@ -35,7 +35,10 @@ add_executable(tests
models/optional.hpp models/optional.hpp
ConvertTest.cpp ConvertTest.cpp
DummyConnection.hpp DummyConnection.hpp
DummyConnection.cpp) DummyConnection.cpp
EntityQueryBuilderTest.cpp
models/author.hpp
models/book.hpp)
target_link_libraries(tests PRIVATE target_link_libraries(tests PRIVATE
Catch2::Catch2WithMain Catch2::Catch2WithMain
+11
View File
@@ -0,0 +1,11 @@
#include <catch2/catch_test_macros.hpp>
#include <matador/sql/connection.hpp>
using namespace matador::sql;
TEST_CASE("Create sql query for entity", "[query][entity][builder]") {
connection noop("noop://noop.db");
schema scm("noop");
}
-1
View File
@@ -4,7 +4,6 @@
#include <matador/sql/condition.hpp> #include <matador/sql/condition.hpp>
#include <matador/sql/connection.hpp> #include <matador/sql/connection.hpp>
#include <matador/sql/dialect_builder.hpp> #include <matador/sql/dialect_builder.hpp>
#include <matador/sql/query_builder.hpp>
#include <matador/sql/query.hpp> #include <matador/sql/query.hpp>
using namespace matador::sql; using namespace matador::sql;
+27
View File
@@ -0,0 +1,27 @@
#ifndef QUERY_AUTHOR_HPP
#define QUERY_AUTHOR_HPP
#include "matador/utils/access.hpp"
#include <string>
namespace matador::test {
struct category
{
unsigned long id{};
std::string name;
template<class Operator>
void process(Operator &op)
{
namespace field = matador::utils::access;
using namespace matador::utils;
field::primary_key(op, "id", id);
field::attribute(op, "name", name, 255);
}
};
}
#endif //QUERY_AUTHOR_HPP
+34
View File
@@ -0,0 +1,34 @@
#ifndef QUERY_BOOK_HPP
#define QUERY_BOOK_HPP
#include "matador/sql/entity.hpp"
#include "matador/utils/access.hpp"
#include "matador/utils/foreign_attributes.hpp"
#include <string>
namespace matador::test {
struct author;
struct book
{
unsigned long id{};
matador::sql::entity<author> book_author;
std::string title;
unsigned short published_in{};
template<typename Operator>
void process(Operator &op)
{
namespace field = matador::utils::access;
field::primary_key(op, "id", id);
field::attribute(op, "title", title, 511);
field::has_one(op, "author_id", book_author, matador::utils::default_foreign_attributes);
field::attribute(op, "published_in", published_in);
}
};
}
#endif //QUERY_BOOK_HPP