added connection impl class
This commit is contained in:
parent
ba3db4aa78
commit
f4f5c00eec
|
|
@ -5,8 +5,12 @@ set(CMAKE_CXX_STANDARD 17)
|
||||||
|
|
||||||
include_directories(${PROJECT_SOURCE_DIR}/include)
|
include_directories(${PROJECT_SOURCE_DIR}/include)
|
||||||
|
|
||||||
|
find_package(ODBC REQUIRED)
|
||||||
|
|
||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
add_subdirectory(test)
|
add_subdirectory(test)
|
||||||
|
|
||||||
add_executable(query main.cpp)
|
add_executable(query main.cpp
|
||||||
|
include/matador/sql/connection_impl.hpp
|
||||||
|
include/matador/sql/connection_info.hpp)
|
||||||
target_link_libraries(query matador)
|
target_link_libraries(query matador)
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ 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();
|
||||||
|
|
||||||
result fetch(const std::string &sql);
|
query_result<record> fetch(const std::string &sql);
|
||||||
std::pair<size_t, std::string> execute(const std::string &sql);
|
std::pair<size_t, std::string> execute(const std::string &sql);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
#ifndef QUERY_CONNECTION_IMPL_HPP
|
||||||
|
#define QUERY_CONNECTION_IMPL_HPP
|
||||||
|
|
||||||
|
#include "matador/sql/connection_info.hpp"
|
||||||
|
|
||||||
|
namespace matador::sql {
|
||||||
|
|
||||||
|
class connection_impl
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~connection_impl() = default;
|
||||||
|
|
||||||
|
virtual void open() = 0;
|
||||||
|
virtual void close() = 0;
|
||||||
|
virtual bool is_open() = 0;
|
||||||
|
|
||||||
|
virtual void execute(const std::string &stmt) = 0;
|
||||||
|
virtual void prepare(const std::string &stmt) = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
explicit connection_impl(connection_info info);
|
||||||
|
|
||||||
|
[[nodiscard]] const connection_info &info() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
connection_info info_;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif //QUERY_CONNECTION_IMPL_HPP
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
#ifndef QUERY_CONNECTION_INFO_HPP
|
||||||
|
#define QUERY_CONNECTION_INFO_HPP
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace matador::sql {
|
||||||
|
|
||||||
|
struct connection_info
|
||||||
|
{
|
||||||
|
std::string type;
|
||||||
|
std::string user;
|
||||||
|
std::string password;
|
||||||
|
std::string hostname;
|
||||||
|
unsigned short port{};
|
||||||
|
std::string database;
|
||||||
|
std::string driver;
|
||||||
|
|
||||||
|
static connection_info parse(const std::string &info, unsigned short default_port = 0, const std::string &default_driver = "");
|
||||||
|
static std::string to_string(const connection_info &ci);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif //QUERY_CONNECTION_INFO_HPP
|
||||||
|
|
@ -3,7 +3,8 @@
|
||||||
|
|
||||||
#include "matador/sql/column.hpp"
|
#include "matador/sql/column.hpp"
|
||||||
#include "matador/sql/key_value_pair.hpp"
|
#include "matador/sql/key_value_pair.hpp"
|
||||||
#include "matador/sql/result.hpp"
|
#include "matador/sql/query_result.hpp"
|
||||||
|
#include "matador/sql/record.hpp"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
|
@ -27,15 +28,28 @@ private:
|
||||||
query_builder &query_;
|
query_builder &query_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class query_execute_finish : public query_intermediate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using query_intermediate::query_intermediate;
|
||||||
|
|
||||||
|
std::pair<size_t, std::string> execute();
|
||||||
|
};
|
||||||
|
|
||||||
class query_select_finish : public query_intermediate
|
class query_select_finish : public query_intermediate
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
using query_intermediate::query_intermediate;
|
using query_intermediate::query_intermediate;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
result fetch_all();
|
query_result<record> fetch_all();
|
||||||
result fetch_one();
|
record fetch_one();
|
||||||
result fetch_value();
|
template<typename Type>
|
||||||
|
Type fetch_value()
|
||||||
|
{
|
||||||
|
auto result = fetch_all();
|
||||||
|
return {};
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class query_limit_intermediate : public query_select_finish
|
class query_limit_intermediate : public query_select_finish
|
||||||
|
|
@ -108,14 +122,6 @@ public:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class query_execute_finish : public query_intermediate
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
using query_intermediate::query_intermediate;
|
|
||||||
|
|
||||||
std::pair<size_t, std::string> execute();
|
|
||||||
};
|
|
||||||
|
|
||||||
class query_into_intermediate : public query_intermediate
|
class query_into_intermediate : public query_intermediate
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -124,20 +130,12 @@ public:
|
||||||
query_execute_finish values(std::initializer_list<any_type> values);
|
query_execute_finish values(std::initializer_list<any_type> values);
|
||||||
};
|
};
|
||||||
|
|
||||||
class query_create_drop_finish : public query_intermediate
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
using query_intermediate::query_intermediate;
|
|
||||||
|
|
||||||
void execute();
|
|
||||||
};
|
|
||||||
|
|
||||||
class query_create_intermediate : query_intermediate
|
class query_create_intermediate : query_intermediate
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using query_intermediate::query_intermediate;
|
using query_intermediate::query_intermediate;
|
||||||
|
|
||||||
query_create_drop_finish table(const std::string &table, std::initializer_list<column> columns);
|
query_execute_finish table(const std::string &table, std::initializer_list<column> columns);
|
||||||
};
|
};
|
||||||
|
|
||||||
class query_drop_intermediate : query_intermediate
|
class query_drop_intermediate : query_intermediate
|
||||||
|
|
@ -145,7 +143,7 @@ class query_drop_intermediate : query_intermediate
|
||||||
public:
|
public:
|
||||||
using query_intermediate::query_intermediate;
|
using query_intermediate::query_intermediate;
|
||||||
|
|
||||||
query_create_drop_finish table(const std::string &table);
|
query_execute_finish table(const std::string &table);
|
||||||
};
|
};
|
||||||
|
|
||||||
class query_insert_intermediate : public query_intermediate
|
class query_insert_intermediate : public query_intermediate
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,95 @@
|
||||||
|
#ifndef QUERY_QUERY_RESULT_HPP
|
||||||
|
#define QUERY_QUERY_RESULT_HPP
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace matador::sql {
|
||||||
|
|
||||||
|
template < typename Type >
|
||||||
|
class query_result;
|
||||||
|
|
||||||
|
template < typename Type >
|
||||||
|
class query_result_iterator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using iterator_category = std::forward_iterator_tag;
|
||||||
|
using value_type = Type;
|
||||||
|
using difference_type = std::ptrdiff_t;
|
||||||
|
using pointer = value_type*; /**< Shortcut for the pointer type. */
|
||||||
|
using reference = value_type&; /**< Shortcut for the reference type */
|
||||||
|
|
||||||
|
public:
|
||||||
|
query_result_iterator() = default;
|
||||||
|
explicit query_result_iterator(query_result<Type> &res, Type *obj = nullptr)
|
||||||
|
: obj_(obj)
|
||||||
|
, result_(res)
|
||||||
|
{}
|
||||||
|
query_result_iterator(query_result_iterator&& x) noexcept
|
||||||
|
: obj_(std::move(x.obj_))
|
||||||
|
, result_(x.result_)
|
||||||
|
{}
|
||||||
|
|
||||||
|
query_result_iterator& operator=(query_result_iterator&& x) noexcept
|
||||||
|
{
|
||||||
|
result_ = x.result_;
|
||||||
|
obj_ = std::move(x.obj_);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
~query_result_iterator() = default;
|
||||||
|
|
||||||
|
bool operator==(const query_result_iterator& rhs)
|
||||||
|
{
|
||||||
|
return obj_ == rhs.obj_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const query_result_iterator& rhs)
|
||||||
|
{
|
||||||
|
return obj_ != rhs.obj_;
|
||||||
|
}
|
||||||
|
|
||||||
|
pointer operator->()
|
||||||
|
{
|
||||||
|
return obj_.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
reference operator&()
|
||||||
|
{
|
||||||
|
return &obj_.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<Type> operator*()
|
||||||
|
{
|
||||||
|
return std::move(obj_);
|
||||||
|
}
|
||||||
|
|
||||||
|
pointer get()
|
||||||
|
{
|
||||||
|
return obj_.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
pointer release()
|
||||||
|
{
|
||||||
|
return obj_.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::unique_ptr<Type> obj_;
|
||||||
|
query_result<Type> &result_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template < typename Type >
|
||||||
|
class query_result
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
query_result(std::string sql) : sql_(std::move(sql)) {}
|
||||||
|
|
||||||
|
[[nodiscard]] const std::string& str() const { return sql_; }
|
||||||
|
|
||||||
|
Type begin() { return {}; }
|
||||||
|
private:
|
||||||
|
std::string sql_;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif //QUERY_QUERY_RESULT_HPP
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
#ifndef QUERY_RECORD_HPP
|
||||||
|
#define QUERY_RECORD_HPP
|
||||||
|
|
||||||
|
#include "matador/sql/column.hpp"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
namespace matador::sql {
|
||||||
|
|
||||||
|
class record
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
using column_by_index = std::vector<column>;
|
||||||
|
using column_index_pair = std::pair<std::reference_wrapper<column>, size_t>;
|
||||||
|
using column_by_name_map = std::unordered_map<std::string, column_index_pair>;
|
||||||
|
|
||||||
|
public:
|
||||||
|
using iterator = column_by_index::iterator;
|
||||||
|
using const_iterator = column_by_index::const_iterator;
|
||||||
|
|
||||||
|
record() = default;
|
||||||
|
record(std::initializer_list<column> columns);
|
||||||
|
~record() = default;
|
||||||
|
|
||||||
|
template < typename Type >
|
||||||
|
void append(const std::string &name, long size = -1)
|
||||||
|
{
|
||||||
|
append(make_column<Type>(name, size));
|
||||||
|
}
|
||||||
|
|
||||||
|
void append(column col);
|
||||||
|
|
||||||
|
[[nodiscard]] const column& at(const std::string &name) const;
|
||||||
|
const column& at(size_t index);
|
||||||
|
|
||||||
|
iterator find(const std::string &column_name);
|
||||||
|
const_iterator find(const std::string &column_name) const;
|
||||||
|
|
||||||
|
iterator begin();
|
||||||
|
[[nodiscard]] const_iterator begin() const;
|
||||||
|
[[nodiscard]] const_iterator cbegin() const;
|
||||||
|
|
||||||
|
iterator end();
|
||||||
|
[[nodiscard]] const_iterator end() const;
|
||||||
|
[[nodiscard]] const_iterator cend() const;
|
||||||
|
|
||||||
|
[[nodiscard]] size_t size() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
column_by_index columns_;
|
||||||
|
column_by_name_map columns_by_name_;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif //QUERY_RECORD_HPP
|
||||||
|
|
@ -2,22 +2,29 @@ set(SQL_SOURCES
|
||||||
sql/dialect.cpp
|
sql/dialect.cpp
|
||||||
sql/query_builder.cpp
|
sql/query_builder.cpp
|
||||||
sql/column.cpp
|
sql/column.cpp
|
||||||
sql/key_value_pair.cpp
|
sql/key_value_pair.cpp
|
||||||
sql/basic_condition.cpp
|
sql/basic_condition.cpp
|
||||||
sql/connection.cpp
|
sql/connection.cpp
|
||||||
sql/connection_intermediates.cpp)
|
sql/connection_intermediates.cpp
|
||||||
|
sql/record.cpp
|
||||||
|
sql/connection_info.cpp
|
||||||
|
sql/connection_impl.cpp)
|
||||||
|
|
||||||
set(SQL_HEADER
|
set(SQL_HEADER
|
||||||
../include/matador/sql/dialect.hpp
|
../include/matador/sql/dialect.hpp
|
||||||
../include/matador/sql/query_builder.hpp
|
../include/matador/sql/query_builder.hpp
|
||||||
../include/matador/sql/column.hpp
|
../include/matador/sql/column.hpp
|
||||||
../include/matador/sql/types.hpp
|
../include/matador/sql/types.hpp
|
||||||
../include/matador/sql/key_value_pair.hpp
|
../include/matador/sql/key_value_pair.hpp
|
||||||
../include/matador/sql/basic_condition.hpp
|
../include/matador/sql/basic_condition.hpp
|
||||||
../include/matador/sql/condition.hpp
|
../include/matador/sql/condition.hpp
|
||||||
../include/matador/sql/connection.hpp
|
../include/matador/sql/connection.hpp
|
||||||
../include/matador/sql/connection_intermediates.hpp
|
../include/matador/sql/connection_intermediates.hpp
|
||||||
../include/matador/sql/result.hpp)
|
../include/matador/sql/result.hpp
|
||||||
|
../include/matador/sql/record.hpp
|
||||||
|
../include/matador/sql/query_result.hpp
|
||||||
|
../include/matador/sql/connection_impl.hpp
|
||||||
|
../include/matador/sql/connection_info.hpp)
|
||||||
|
|
||||||
set(UTILS_HEADER
|
set(UTILS_HEADER
|
||||||
../include/matador/utils/field_attributes.hpp
|
../include/matador/utils/field_attributes.hpp
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ query_delete_intermediate connection::remove()
|
||||||
return query_delete_intermediate{*this, query_.remove()};
|
return query_delete_intermediate{*this, query_.remove()};
|
||||||
}
|
}
|
||||||
|
|
||||||
result connection::fetch(const std::string &sql)
|
query_result<record> connection::fetch(const std::string &sql)
|
||||||
{
|
{
|
||||||
return {sql};
|
return {sql};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include "matador/sql/connection_impl.hpp"
|
||||||
|
|
||||||
|
namespace matador::sql {
|
||||||
|
|
||||||
|
connection_impl::connection_impl(connection_info info)
|
||||||
|
: info_(std::move(info)){}
|
||||||
|
|
||||||
|
const connection_info &connection_impl::info() const {
|
||||||
|
return info_;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,72 @@
|
||||||
|
#include "matador/sql/connection_info.hpp"
|
||||||
|
|
||||||
|
#include <regex>
|
||||||
|
|
||||||
|
namespace matador::sql {
|
||||||
|
|
||||||
|
connection_info connection_info::parse(const std::string &info, unsigned short default_port, const std::string &default_driver) {
|
||||||
|
static const std::regex DNS_RGX (R"((\w+):\/\/((([\w]+)(:([\w!]+))?)@)?((((([\w.\(\)\\]+)([:]([\d]+))?)?)\/)?(([\w.]+)( \((.*)\))?)))");
|
||||||
|
|
||||||
|
std::smatch what;
|
||||||
|
|
||||||
|
if (!std::regex_match(info, what, DNS_RGX)) {
|
||||||
|
throw std::logic_error("connect invalid dns: " + info);
|
||||||
|
}
|
||||||
|
|
||||||
|
connection_info ci{};
|
||||||
|
ci.type = what[1].str();
|
||||||
|
ci.user = what[4].str();
|
||||||
|
ci.password = what[6].str();
|
||||||
|
|
||||||
|
// get connection part
|
||||||
|
ci.hostname = what[11].str();
|
||||||
|
if (what[13].matched) {
|
||||||
|
char *end;
|
||||||
|
ci.port = static_cast<unsigned short>(std::strtoul(what[13].str().c_str(), &end, 10));
|
||||||
|
} else {
|
||||||
|
ci.port = default_port;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Should we just ignore the "instance" part?
|
||||||
|
// const std::string instance = what[5].str();
|
||||||
|
ci.database = what[15].str();
|
||||||
|
|
||||||
|
if (what[17].matched) {
|
||||||
|
ci.driver = what[17].str();
|
||||||
|
} else {
|
||||||
|
ci.driver = default_driver;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ci;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string connection_info::to_string(const connection_info &ci) {
|
||||||
|
std::string dns{ci.type};
|
||||||
|
dns += "://";
|
||||||
|
|
||||||
|
if (!ci.user.empty()) {
|
||||||
|
dns += ci.user;
|
||||||
|
if (!ci.password.empty()) {
|
||||||
|
dns += ":" + ci.password;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ci.hostname.empty()) {
|
||||||
|
dns += "@" + ci.hostname;
|
||||||
|
if (ci.port > 0) {
|
||||||
|
dns += ":" + std::to_string(ci.port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dns.empty()) {
|
||||||
|
dns += "/";
|
||||||
|
}
|
||||||
|
dns += ci.database;
|
||||||
|
|
||||||
|
if (!ci.driver.empty()) {
|
||||||
|
dns += " (" + ci.driver +")";
|
||||||
|
}
|
||||||
|
return dns;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -13,19 +13,14 @@ query_builder &query_intermediate::query()
|
||||||
return query_;
|
return query_;
|
||||||
}
|
}
|
||||||
|
|
||||||
result query_select_finish::fetch_all()
|
query_result<record> query_select_finish::fetch_all()
|
||||||
{
|
{
|
||||||
return db().fetch(query().compile());
|
return db().fetch(query().compile());
|
||||||
}
|
}
|
||||||
|
|
||||||
result query_select_finish::fetch_one()
|
record query_select_finish::fetch_one()
|
||||||
{
|
{
|
||||||
return db().fetch(query().compile());
|
return db().fetch(query().compile()).begin();
|
||||||
}
|
|
||||||
|
|
||||||
result query_select_finish::fetch_value()
|
|
||||||
{
|
|
||||||
return db().fetch(query().compile());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
query_intermediate::query_intermediate(connection &db, query_builder &query)
|
query_intermediate::query_intermediate(connection &db, query_builder &query)
|
||||||
|
|
@ -106,17 +101,12 @@ query_execute_finish query_into_intermediate::values(std::initializer_list<any_t
|
||||||
return {db(), query().values(values)};
|
return {db(), query().values(values)};
|
||||||
}
|
}
|
||||||
|
|
||||||
void query_create_drop_finish::execute()
|
query_execute_finish query_create_intermediate::table(const std::string &table, std::initializer_list<column> columns)
|
||||||
{
|
|
||||||
db().execute(query().compile());
|
|
||||||
}
|
|
||||||
|
|
||||||
query_create_drop_finish query_create_intermediate::table(const std::string &table, std::initializer_list<column> columns)
|
|
||||||
{
|
{
|
||||||
return {db(), query().table(table, columns)};
|
return {db(), query().table(table, columns)};
|
||||||
}
|
}
|
||||||
|
|
||||||
query_create_drop_finish query_drop_intermediate::table(const std::string &table)
|
query_execute_finish query_drop_intermediate::table(const std::string &table)
|
||||||
{
|
{
|
||||||
return {db(), query().table(table)};
|
return {db(), query().table(table)};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,75 @@
|
||||||
|
#include "matador/sql/record.hpp"
|
||||||
|
|
||||||
|
namespace matador::sql {
|
||||||
|
|
||||||
|
record::record(std::initializer_list<column> columns)
|
||||||
|
: columns_(columns) {
|
||||||
|
size_t index{0};
|
||||||
|
for(auto &col : columns_) {
|
||||||
|
columns_by_name_.emplace(col.name(), column_index_pair {std::ref(col), index++});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const column &record::at(const std::string &name) const
|
||||||
|
{
|
||||||
|
return columns_by_name_.at(name).first;
|
||||||
|
}
|
||||||
|
|
||||||
|
const column &record::at(size_t index)
|
||||||
|
{
|
||||||
|
return columns_.at(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
record::iterator record::find(const std::string &column_name)
|
||||||
|
{
|
||||||
|
auto it = columns_by_name_.find(column_name);
|
||||||
|
return it != columns_by_name_.end() ? columns_.begin() + it->second.second : columns_.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
record::const_iterator record::find(const std::string &column_name) const {
|
||||||
|
auto it = columns_by_name_.find(column_name);
|
||||||
|
return it != columns_by_name_.end() ? columns_.begin() + it->second.second : columns_.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
void record::append(column col)
|
||||||
|
{
|
||||||
|
auto &ref = columns_.emplace_back(std::move(col));
|
||||||
|
columns_by_name_.emplace(ref.name(), column_index_pair{std::ref(ref), columns_.size()-1});
|
||||||
|
}
|
||||||
|
|
||||||
|
record::iterator record::begin()
|
||||||
|
{
|
||||||
|
return columns_.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
record::const_iterator record::begin() const
|
||||||
|
{
|
||||||
|
return columns_.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
record::const_iterator record::cbegin() const
|
||||||
|
{
|
||||||
|
return columns_.cbegin();
|
||||||
|
}
|
||||||
|
|
||||||
|
record::iterator record::end()
|
||||||
|
{
|
||||||
|
return columns_.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
record::const_iterator record::end() const
|
||||||
|
{
|
||||||
|
return columns_.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
record::const_iterator record::cend() const
|
||||||
|
{
|
||||||
|
return columns_.cend();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t record::size() const
|
||||||
|
{
|
||||||
|
return columns_.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -9,6 +9,7 @@ FetchContent_Declare(
|
||||||
FetchContent_MakeAvailable(Catch2)
|
FetchContent_MakeAvailable(Catch2)
|
||||||
|
|
||||||
add_executable(tests builder.cpp
|
add_executable(tests builder.cpp
|
||||||
connection.cpp)
|
connection.cpp
|
||||||
|
record.cpp)
|
||||||
target_link_libraries(tests PRIVATE Catch2::Catch2WithMain matador)
|
target_link_libraries(tests PRIVATE Catch2::Catch2WithMain matador)
|
||||||
target_include_directories(tests PUBLIC $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>/include)
|
target_include_directories(tests PUBLIC $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>/include)
|
||||||
|
|
@ -9,7 +9,7 @@ using namespace matador::sql;
|
||||||
TEST_CASE("Execute create table statement", "[connection]") {
|
TEST_CASE("Execute create table statement", "[connection]") {
|
||||||
connection c;
|
connection c;
|
||||||
|
|
||||||
c.create()
|
const auto res = c.create()
|
||||||
.table("person", {
|
.table("person", {
|
||||||
make_pk_column<unsigned long>("id"),
|
make_pk_column<unsigned long>("id"),
|
||||||
make_column<std::string>("name", 255),
|
make_column<std::string>("name", 255),
|
||||||
|
|
@ -17,17 +17,17 @@ TEST_CASE("Execute create table statement", "[connection]") {
|
||||||
}).execute();
|
}).execute();
|
||||||
|
|
||||||
REQUIRE(true);
|
REQUIRE(true);
|
||||||
// REQUIRE(res.sql == R"(SELECT "id", "name", "color" FROM "person" WHERE "id" = 8)");
|
REQUIRE(res.second == R"(CREATE TABLE "person" ("id" BIGINT NOT NULL PRIMARY KEY, "name" VARCHAR(255), "age" INTEGER))");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("Execute drop table statement", "[connection]") {
|
TEST_CASE("Execute drop table statement", "[connection]") {
|
||||||
connection c;
|
connection c;
|
||||||
|
|
||||||
c.drop()
|
const auto res = c.drop()
|
||||||
.table("person").execute();
|
.table("person")
|
||||||
|
.execute();
|
||||||
|
|
||||||
REQUIRE(true);
|
REQUIRE(res.second == R"(DROP TABLE "person")");
|
||||||
// REQUIRE(res.sql == R"(SELECT "id", "name", "color" FROM "person" WHERE "id" = 8)");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("Execute select statement with where clause", "[connection]") {
|
TEST_CASE("Execute select statement with where clause", "[connection]") {
|
||||||
|
|
@ -38,7 +38,7 @@ TEST_CASE("Execute select statement with where clause", "[connection]") {
|
||||||
.where("id"_col == 8)
|
.where("id"_col == 8)
|
||||||
.fetch_all();
|
.fetch_all();
|
||||||
|
|
||||||
REQUIRE(res.sql == R"(SELECT "id", "name", "color" FROM "person" WHERE "id" = 8)");
|
REQUIRE(res.str() == R"(SELECT "id", "name", "color" FROM "person" WHERE "id" = 8)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("Execute select statement with order by", "[connection]") {
|
TEST_CASE("Execute select statement with order by", "[connection]") {
|
||||||
|
|
@ -50,7 +50,7 @@ TEST_CASE("Execute select statement with order by", "[connection]") {
|
||||||
.order_by("name").desc()
|
.order_by("name").desc()
|
||||||
.fetch_all();
|
.fetch_all();
|
||||||
|
|
||||||
REQUIRE(res.sql == R"(SELECT "id", "name", "color" FROM "person" WHERE "id" = 8 ORDER BY "name" DESC)");
|
REQUIRE(res.str() == R"(SELECT "id", "name", "color" FROM "person" WHERE "id" = 8 ORDER BY "name" DESC)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("Execute select statement with group by and order by", "[connection]") {
|
TEST_CASE("Execute select statement with group by and order by", "[connection]") {
|
||||||
|
|
@ -63,7 +63,7 @@ TEST_CASE("Execute select statement with group by and order by", "[connection]")
|
||||||
.order_by("name").asc()
|
.order_by("name").asc()
|
||||||
.fetch_all();
|
.fetch_all();
|
||||||
|
|
||||||
REQUIRE(res.sql == R"(SELECT "id", "name", "color" FROM "person" WHERE "id" = 8 GROUP BY "color" ORDER BY "name" ASC)");
|
REQUIRE(res.str() == R"(SELECT "id", "name", "color" FROM "person" WHERE "id" = 8 GROUP BY "color" ORDER BY "name" ASC)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("Execute insert statement", "[connection]") {
|
TEST_CASE("Execute insert statement", "[connection]") {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
#include <catch2/catch_test_macros.hpp>
|
||||||
|
|
||||||
|
#include <matador/sql/record.hpp>
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
|
||||||
|
using namespace matador::sql;
|
||||||
|
|
||||||
|
TEST_CASE("Create record", "[record]") {
|
||||||
|
record rec({
|
||||||
|
make_pk_column<unsigned long>("id"),
|
||||||
|
make_column<std::string>("name", 255),
|
||||||
|
make_column<std::string>("color", 255)
|
||||||
|
});
|
||||||
|
|
||||||
|
REQUIRE(rec.size() == 3);
|
||||||
|
|
||||||
|
std::list<std::string> expected_columns = {"id", "name", "color"};
|
||||||
|
for(const auto &col : expected_columns) {
|
||||||
|
REQUIRE(rec.find(col) != rec.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
for(const auto& col : rec) {
|
||||||
|
expected_columns.remove(col.name());
|
||||||
|
}
|
||||||
|
|
||||||
|
REQUIRE(expected_columns.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Append to record", "[record]") {
|
||||||
|
record rec;
|
||||||
|
|
||||||
|
rec.append(make_pk_column<unsigned long>("id"));
|
||||||
|
rec.append<std::string>("name", 255);
|
||||||
|
rec.append<std::string>("color", 63);
|
||||||
|
|
||||||
|
REQUIRE(rec.size() == 3);
|
||||||
|
|
||||||
|
std::list<std::string> expected_columns = {"id", "name", "color"};
|
||||||
|
for(const auto &col : expected_columns) {
|
||||||
|
REQUIRE(rec.find(col) != rec.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
for(const auto& col : rec) {
|
||||||
|
expected_columns.remove(col.name());
|
||||||
|
}
|
||||||
|
|
||||||
|
REQUIRE(expected_columns.empty());
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue