138 lines
3.5 KiB
C++
138 lines
3.5 KiB
C++
#include "matador/sql/connection.hpp"
|
|
|
|
#include "matador/sql/backend_provider.hpp"
|
|
#include "matador/sql/connection_impl.hpp"
|
|
|
|
#include <stdexcept>
|
|
#include <utility>
|
|
|
|
namespace matador::sql {
|
|
|
|
connection::connection(connection_info info)
|
|
: connection_info_(std::move(info))
|
|
, logger_(stdout, "SQL")
|
|
, dialect_(backend_provider::instance().connection_dialect(connection_info_.type))
|
|
{
|
|
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_)
|
|
, logger_(x.logger_)
|
|
, dialect_(x.dialect_)
|
|
{
|
|
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_;
|
|
logger_ = x.logger_;
|
|
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_.release());
|
|
connection_ = nullptr;
|
|
}
|
|
|
|
void connection::open()
|
|
{
|
|
connection_->open();
|
|
}
|
|
|
|
void connection::close()
|
|
{
|
|
connection_->close();
|
|
}
|
|
|
|
bool connection::is_open() const
|
|
{
|
|
return connection_->is_open();
|
|
}
|
|
|
|
const connection_info &connection::info() const
|
|
{
|
|
return connection_info_;
|
|
}
|
|
|
|
record connection::describe(const std::string &table_name) const
|
|
{
|
|
return std::move(connection_->describe(table_name));
|
|
}
|
|
|
|
bool connection::exists(const std::string &schema_name, const std::string &table_name) const
|
|
{
|
|
return connection_->exists(schema_name, table_name);
|
|
}
|
|
|
|
bool connection::exists(const std::string &table_name) const
|
|
{
|
|
return connection_->exists(dialect_.default_schema_name(), table_name);
|
|
}
|
|
|
|
size_t connection::execute(const std::string &sql) const
|
|
{
|
|
logger_.debug(sql);
|
|
return connection_->execute(sql);
|
|
}
|
|
|
|
sql::query connection::query(const std::shared_ptr<sql::schema> &schema) const
|
|
{
|
|
return sql::query(*const_cast<connection*>(this), schema);
|
|
}
|
|
|
|
query_result<record> connection::fetch(const query_context &q) const
|
|
{
|
|
if (q.prototype.empty() || q.prototype.unknown()) {
|
|
const auto table_prototype = describe(q.table_name);
|
|
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_cast<column_definition&>(col).type(rit->type());
|
|
}
|
|
}
|
|
}
|
|
// auto it = prototypes_.find(q.table_name);
|
|
// if (it == prototypes_.end()) {
|
|
// it = prototypes_.emplace(q.table_name, describe(q.table_name)).first;
|
|
// }
|
|
// // adjust columns from given query
|
|
// for (auto &col : q.prototype) {
|
|
// if (const auto rit = it->second.find(col.name()); col.type() == data_type_t::type_unknown && rit != it->second.end()) {
|
|
// const_cast<column&>(col).type(rit->type());
|
|
// }
|
|
// }
|
|
auto res = fetch(q.sql);
|
|
return query_result<record>{std::move(res), q.prototype};
|
|
}
|
|
|
|
std::unique_ptr<query_result_impl> connection::fetch(const std::string &sql) const
|
|
{
|
|
logger_.debug(sql);
|
|
return connection_->fetch(sql);
|
|
}
|
|
|
|
statement connection::prepare(query_context &&query) const
|
|
{
|
|
return statement(connection_->prepare(std::move(query)), logger_);
|
|
}
|
|
|
|
const class dialect &connection::dialect() const
|
|
{
|
|
return dialect_;
|
|
}
|
|
|
|
}
|