implemented lazy loading for object_ptr and belongs_to
This commit is contained in:
@@ -3,7 +3,6 @@
|
||||
#include "matador/sql/backend_provider.hpp"
|
||||
#include "matador/sql/dialect.hpp"
|
||||
#include "matador/sql/dialect_token.hpp"
|
||||
#include "matador/sql/error_code.hpp"
|
||||
#include "matador/sql/interface/connection_impl.hpp"
|
||||
|
||||
|
||||
@@ -28,16 +27,29 @@ public:
|
||||
};
|
||||
|
||||
}
|
||||
connection::connection(const connection_info& info, const std::shared_ptr<abstract_sql_logger> &sql_logger)
|
||||
: logger_(sql_logger)
|
||||
{
|
||||
connection::connection(const connection_info& info, logger_ptr sql_logger)
|
||||
: logger_(std::move(sql_logger)) {
|
||||
connection_.reset(backend_provider::instance().create_connection(info.type, info));
|
||||
}
|
||||
|
||||
connection::connection(const std::string& dns, const std::shared_ptr<abstract_sql_logger> &sql_logger)
|
||||
connection::connection(const connection_info &info,
|
||||
std::shared_ptr<producer_resolver_factory> resolver_factory,
|
||||
logger_ptr sql_logger)
|
||||
: logger_(std::move(sql_logger))
|
||||
, resolver_factory_(std::move(resolver_factory)) {
|
||||
connection_.reset(backend_provider::instance().create_connection(info.type, info));
|
||||
}
|
||||
|
||||
connection::connection(const std::string& dns, const logger_ptr &sql_logger)
|
||||
: connection(connection_info::parse(dns), sql_logger)
|
||||
{}
|
||||
|
||||
connection::connection(const std::string &dns,
|
||||
std::shared_ptr<producer_resolver_factory> resolver_factory,
|
||||
const logger_ptr &sql_logger)
|
||||
: connection(connection_info::parse(dns), std::move(resolver_factory), sql_logger)
|
||||
{}
|
||||
|
||||
connection::connection(const connection &x) {
|
||||
if (x.connection_) {
|
||||
throw std::runtime_error("couldn't copy connection with valid connection impl");
|
||||
@@ -58,11 +70,13 @@ connection &connection::operator=(const connection &x) {
|
||||
connection::connection( connection&& x ) noexcept
|
||||
: connection_(std::move(x.connection_))
|
||||
, logger_(std::move(x.logger_))
|
||||
, resolver_factory_(std::move(x.resolver_factory_))
|
||||
{}
|
||||
|
||||
connection & connection::operator=(connection &&x) noexcept {
|
||||
connection_ = std::move(x.connection_);
|
||||
logger_ = std::move(x.logger_);
|
||||
resolver_factory_ = std::move(x.resolver_factory_);
|
||||
|
||||
return *this;
|
||||
}
|
||||
@@ -71,7 +85,7 @@ connection::~connection() {
|
||||
if (!connection_) {
|
||||
return;
|
||||
}
|
||||
if (connection_->is_open()) {
|
||||
if (const auto result = connection_->is_open(); *result) {
|
||||
connection_->close();
|
||||
}
|
||||
connection_impl* impl = connection_.release();
|
||||
@@ -219,6 +233,10 @@ const class dialect &connection::dialect() const
|
||||
return connection_->dialect();
|
||||
}
|
||||
|
||||
std::shared_ptr<class producer_resolver_factory> connection::resolver_factory() const {
|
||||
return resolver_factory_;
|
||||
}
|
||||
|
||||
utils::result<std::unique_ptr<statement_impl>, utils::error> connection::perform_prepare(const query_context& ctx) const {
|
||||
if (ctx.command != sql_command::SQL_CREATE_TABLE && (ctx.prototype.empty() || has_unknown_columns(ctx.prototype))) {
|
||||
if (const auto result = describe(ctx.table_name); result.is_ok()) {
|
||||
|
||||
@@ -53,21 +53,19 @@ bool connection_ptr::valid() const {
|
||||
return connection_ != nullptr;
|
||||
}
|
||||
|
||||
connection_pool::connection_pool(const std::string& dns, size_t count)
|
||||
: info_(connection_info::parse(dns)) {
|
||||
connection_pool::connection_pool(const std::string& dns, const size_t count)
|
||||
: connection_pool(dns, count, [](const connection_info &info) { return connection{info}; })
|
||||
{}
|
||||
|
||||
connection_pool::connection_pool(const std::string &dns, size_t count, std::function<connection(const connection_info &)> &&connection_creator)
|
||||
: info_(connection_info::parse(dns))
|
||||
, connection_creator_(std::move(connection_creator)) {
|
||||
connection_repo_.reserve(count);
|
||||
while (count) {
|
||||
// connection c(info_);
|
||||
// auto&& cc = std::move(c);
|
||||
// const auto ic = identifiable_connection{count, std::move(cc)};
|
||||
// connection_repo_.push_back(ic);
|
||||
// connection_repo_.emplace_back(count, std::move(cc));
|
||||
connection_repo_.emplace_back(count, connection{info_});
|
||||
connection_repo_.emplace_back(count, connection_creator_(info_));
|
||||
auto &conn = connection_repo_.back();
|
||||
idle_connections_.emplace(conn.id, &conn);
|
||||
// Todo: handle result
|
||||
const auto result = conn.conn.open();
|
||||
if (!result) {
|
||||
if (const auto result = conn.conn.open(); !result) {
|
||||
throw std::runtime_error("Failed to open connection");
|
||||
}
|
||||
--count;
|
||||
|
||||
@@ -35,6 +35,17 @@ field &field::operator=(field &&x) noexcept {
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool field::operator==(const field &rhs) const {
|
||||
return name_ == rhs.name_ &&
|
||||
type_ == rhs.type_ &&
|
||||
index_ == rhs.index_ &&
|
||||
value_ == rhs.value_;
|
||||
}
|
||||
|
||||
bool field::operator!=(const field &rhs) const {
|
||||
return !operator==(rhs);
|
||||
}
|
||||
|
||||
const std::string &field::name() const {
|
||||
return name_;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
#include "matador/sql/internal/identifier_reader.hpp"
|
||||
|
||||
namespace matador::sql::internal {
|
||||
identifier_reader::identifier_reader(query_result_reader &reader)
|
||||
: reader_(reader) {}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
#include "matador/sql/internal/identifier_statement_binder.hpp"
|
||||
|
||||
#include "matador/sql/statement.hpp"
|
||||
|
||||
namespace matador::sql {
|
||||
identifier_statement_binder::identifier_statement_binder(statement &stmt, const size_t index)
|
||||
: stmt_(stmt)
|
||||
, index_(index) {}
|
||||
|
||||
void identifier_statement_binder::bind(const utils::identifier &id) {
|
||||
id.serialize(*this);
|
||||
}
|
||||
|
||||
void identifier_statement_binder::serialize(int8_t &value, const utils::field_attributes &) {
|
||||
stmt_.bind(index_, value);
|
||||
}
|
||||
|
||||
void identifier_statement_binder::serialize(int16_t &value, const utils::field_attributes &) {
|
||||
stmt_.bind(index_, value);
|
||||
}
|
||||
|
||||
void identifier_statement_binder::serialize(int32_t &value, const utils::field_attributes &) {
|
||||
stmt_.bind(index_, value);
|
||||
}
|
||||
|
||||
void identifier_statement_binder::serialize(int64_t &value, const utils::field_attributes &) {
|
||||
stmt_.bind(index_, value);
|
||||
}
|
||||
|
||||
void identifier_statement_binder::serialize(uint8_t &value, const utils::field_attributes &) {
|
||||
stmt_.bind(index_, value);
|
||||
}
|
||||
|
||||
void identifier_statement_binder::serialize(uint16_t &value, const utils::field_attributes &) {
|
||||
stmt_.bind(index_, value);
|
||||
}
|
||||
|
||||
void identifier_statement_binder::serialize(uint32_t &value, const utils::field_attributes &) {
|
||||
stmt_.bind(index_, value);
|
||||
}
|
||||
|
||||
void identifier_statement_binder::serialize(uint64_t &value, const utils::field_attributes &) {
|
||||
stmt_.bind(index_, value);
|
||||
}
|
||||
|
||||
void identifier_statement_binder::serialize(const char *value, const utils::field_attributes &) {
|
||||
stmt_.bind(index_, value);
|
||||
}
|
||||
|
||||
void identifier_statement_binder::serialize(std::string &value, const utils::field_attributes &) {
|
||||
stmt_.bind(index_, value);
|
||||
}
|
||||
|
||||
void identifier_statement_binder::serialize(utils::null_type_t &/*value*/, const utils::field_attributes &) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#include "matador/sql/internal/resolver_producer.hpp"
|
||||
|
||||
namespace matador::sql {
|
||||
const std::type_index & resolver_producer::type() const {
|
||||
return type_;
|
||||
}
|
||||
|
||||
resolver_producer::resolver_producer(const std::type_index &type)
|
||||
: type_(type) {}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
#include "matador/sql/producer_resolver_factory.hpp"
|
||||
|
||||
namespace matador::sql {
|
||||
std::shared_ptr<object::abstract_object_resolver> producer_resolver_factory::acquire_resolver(const std::type_index &type) {
|
||||
if (const auto it = resolvers_.find(type); it != resolvers_.end()) {
|
||||
return it->second;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void producer_resolver_factory::register_resolver(std::shared_ptr<object::abstract_object_resolver> &&resolver) {
|
||||
resolvers_[resolver->type()] = std::move(resolver);
|
||||
}
|
||||
}
|
||||
@@ -5,12 +5,11 @@
|
||||
|
||||
namespace matador::sql::detail {
|
||||
|
||||
template<>
|
||||
record *create_prototype<record>(const std::vector<object::attribute> &prototype) {
|
||||
auto result = std::make_unique<record>();
|
||||
record create_prototype(const std::vector<object::attribute> &prototype) {
|
||||
record rec;
|
||||
int index{0};
|
||||
for (const auto &col: prototype) {
|
||||
result->append({
|
||||
rec.append({
|
||||
col.name(),
|
||||
col.type(),
|
||||
col.attributes().options(),
|
||||
@@ -18,7 +17,7 @@ record *create_prototype<record>(const std::vector<object::attribute> &prototype
|
||||
index++
|
||||
});
|
||||
}
|
||||
return result.release();
|
||||
return rec;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -70,9 +70,25 @@ record::const_iterator record::find(const std::string &column_name) const {
|
||||
return it != fields_by_name_.end() ? fields_.begin() + it->second.second : fields_.end();
|
||||
}
|
||||
|
||||
bool record::operator==(const record &rhs) const {
|
||||
if (size() != rhs.size()) {
|
||||
return false;
|
||||
}
|
||||
for(size_t i = 0; i < size(); ++i) {
|
||||
if (at(i) != rhs.at(i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool record::operator!=(const record &rhs) const {
|
||||
return !operator==(rhs);
|
||||
}
|
||||
|
||||
void record::append(const field &col) {
|
||||
const auto it = fields_by_name_.emplace(col.name(), field_index_pair {col, fields_.size()});
|
||||
fields_.push_back(std::ref(it.first->second.first));
|
||||
const auto [fst, snd] = fields_by_name_.emplace(col.name(), field_index_pair {col, fields_.size()});
|
||||
fields_.push_back(std::ref(fst->second.first));
|
||||
}
|
||||
|
||||
record::iterator record::begin()
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "matador/sql/statement.hpp"
|
||||
#include "matador/sql/record.hpp"
|
||||
#include "matador/sql/field.hpp"
|
||||
#include "matador/sql/query_record_result.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
@@ -64,9 +65,7 @@ utils::result<query_result<record>, utils::error> statement::fetch() const {
|
||||
}
|
||||
// logger_.info(statement_->query_.sql);
|
||||
const auto prototype = result.value()->prototype();
|
||||
return utils::ok(query_result<record>(std::move(*result), [prototype] {
|
||||
return detail::create_prototype<record>(prototype);
|
||||
}));
|
||||
return utils::ok(query_result<record>(std::move(*result), prototype));
|
||||
}
|
||||
|
||||
utils::result<std::optional<record>, utils::error> statement::fetch_one() const {
|
||||
@@ -77,15 +76,13 @@ utils::result<std::optional<record>, utils::error> statement::fetch_one() const
|
||||
}
|
||||
|
||||
const auto prototype = result.value()->prototype();
|
||||
query_result<record> records(std::move(*result), [prototype] {
|
||||
return sql::detail::create_prototype<record>(prototype);
|
||||
});
|
||||
query_result<record> records(std::move(*result), prototype);
|
||||
auto first = records.begin();
|
||||
if (first == records.end()) {
|
||||
return utils::ok(std::optional<record>{std::nullopt});
|
||||
}
|
||||
|
||||
return utils::ok(std::optional{*first.get()});
|
||||
return utils::ok(std::optional{first.release()});
|
||||
}
|
||||
|
||||
void statement::reset() const {
|
||||
|
||||
Reference in New Issue
Block a user