implemented sqlite fetch
This commit is contained in:
@@ -38,6 +38,15 @@ public:
|
||||
[[nodiscard]] const std::string& ref_column() const;
|
||||
|
||||
private:
|
||||
template<class Operator>
|
||||
void process(Operator &op)
|
||||
{
|
||||
op.on_attribute(name_.c_str(), value_, type_, attributes_);
|
||||
}
|
||||
|
||||
private:
|
||||
friend class record;
|
||||
|
||||
std::string name_;
|
||||
utils::field_attributes attributes_;
|
||||
data_type_t type_{};
|
||||
|
||||
@@ -10,29 +10,38 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace matador::utils {
|
||||
class identifiable;
|
||||
}
|
||||
|
||||
namespace matador::sql {
|
||||
|
||||
class fk_column_generator : public utils::identifier_serializer
|
||||
class fk_column_generator
|
||||
{
|
||||
public:
|
||||
fk_column_generator() = default;
|
||||
|
||||
column generate(const char *id, utils::identifiable &x);
|
||||
template<class Type>
|
||||
column generate(const char *id, Type &x)
|
||||
{
|
||||
utils::access::process(*this, x);
|
||||
return column{id, type_, { utils::constraints::FOREIGN_KEY }};
|
||||
}
|
||||
|
||||
void serialize(short &i, const utils::field_attributes &attributes) override;
|
||||
void serialize(int &i, const utils::field_attributes &attributes) override;
|
||||
void serialize(long &i, const utils::field_attributes &attributes) override;
|
||||
void serialize(long long int &i, const utils::field_attributes &attributes) override;
|
||||
void serialize(unsigned short &i, const utils::field_attributes &attributes) override;
|
||||
void serialize(unsigned int &i, const utils::field_attributes &attributes) override;
|
||||
void serialize(unsigned long &i, const utils::field_attributes &attributes) override;
|
||||
void serialize(unsigned long long int &i, const utils::field_attributes &attributes) override;
|
||||
void serialize(std::string &string, const utils::field_attributes &attributes) override;
|
||||
void serialize(utils::null_type_t &type, const utils::field_attributes &attributes) override;
|
||||
template<typename ValueType>
|
||||
void on_primary_key(const char *, ValueType &/*pk*/, typename std::enable_if<std::is_integral<ValueType>::value && !std::is_same<bool, ValueType>::value>::type* = 0)
|
||||
{
|
||||
type_ = data_type_traits<ValueType>::builtin_type(0);
|
||||
}
|
||||
void on_primary_key(const char * /*id*/, std::string &/*pk*/, size_t size);
|
||||
void on_revision(const char * /*id*/, unsigned long long &/*rev*/) {}
|
||||
template < class Type >
|
||||
void on_attribute(const char * /*id*/, Type &/*x*/, const utils::field_attributes &/*attr*/ = utils::null_attributes) {}
|
||||
void on_attribute(const char * /*id*/, char * /*x*/, const utils::field_attributes &/*attr*/ = utils::null_attributes) {}
|
||||
template<class Pointer>
|
||||
void on_belongs_to(const char * /*id*/, Pointer &/*x*/, utils::cascade_type) {}
|
||||
template<class Pointer>
|
||||
void on_has_one(const char * /*id*/, Pointer &/*x*/, utils::cascade_type) {}
|
||||
template<class ContainerType>
|
||||
void on_has_many(const char *, ContainerType &, const char *, const char *, utils::cascade_type) {}
|
||||
template<class ContainerType>
|
||||
void on_has_many(const char *, ContainerType &, utils::cascade_type) {}
|
||||
|
||||
private:
|
||||
data_type_t type_{};
|
||||
@@ -64,8 +73,16 @@ public:
|
||||
template<typename Type>
|
||||
void on_attribute(const char *id, Type &x, const utils::field_attributes &attr = utils::null_attributes);
|
||||
|
||||
void on_belongs_to(const char *id, utils::identifiable &x, utils::cascade_type);
|
||||
void on_has_one(const char *id, utils::identifiable &x, utils::cascade_type);
|
||||
template<class Pointer>
|
||||
void on_belongs_to(const char *id, Pointer &x, utils::cascade_type)
|
||||
{
|
||||
columns_.push_back(fk_column_generator_.generate(id, *x));
|
||||
}
|
||||
template<class Pointer>
|
||||
void on_has_one(const char *id, Pointer &x, utils::cascade_type)
|
||||
{
|
||||
columns_.push_back(fk_column_generator_.generate(id, *x));
|
||||
}
|
||||
template<class ContainerType>
|
||||
void on_has_many(const char *, ContainerType &, const char *, const char *, utils::cascade_type) {}
|
||||
template<class ContainerType>
|
||||
|
||||
@@ -7,10 +7,6 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace matador::utils {
|
||||
class identifiable;
|
||||
}
|
||||
|
||||
namespace matador::sql {
|
||||
|
||||
class column_name_generator
|
||||
@@ -45,8 +41,16 @@ public:
|
||||
column_names_.emplace_back(id);
|
||||
}
|
||||
|
||||
void on_belongs_to(const char *id, utils::identifiable &, utils::cascade_type);
|
||||
void on_has_one(const char *id, utils::identifiable &, utils::cascade_type);
|
||||
template<class Pointer>
|
||||
void on_belongs_to(const char *id, Pointer &, utils::cascade_type)
|
||||
{
|
||||
column_names_.emplace_back(id);
|
||||
}
|
||||
template<class Pointer>
|
||||
void on_has_one(const char *id, Pointer &, utils::cascade_type)
|
||||
{
|
||||
column_names_.emplace_back(id);
|
||||
}
|
||||
template<class ContainerType>
|
||||
void on_has_many(const char *, ContainerType &, const char *, const char *, utils::cascade_type) {}
|
||||
template<class ContainerType>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "matador/sql/connection_info.hpp"
|
||||
#include "matador/sql/query_result_impl.hpp"
|
||||
#include "matador/sql/record.hpp"
|
||||
|
||||
#include <memory>
|
||||
|
||||
@@ -23,6 +24,8 @@ public:
|
||||
virtual std::unique_ptr<query_result_impl> fetch(const std::string &stmt) = 0;
|
||||
virtual void prepare(const std::string &stmt) = 0;
|
||||
|
||||
virtual record describe(const std::string &table) = 0;
|
||||
|
||||
protected:
|
||||
explicit connection_impl(const connection_info &info);
|
||||
|
||||
|
||||
@@ -1,38 +1,18 @@
|
||||
#ifndef QUERY_FOREIGN_HPP
|
||||
#define QUERY_FOREIGN_HPP
|
||||
|
||||
#include "matador/utils/identifiable.hpp"
|
||||
#include <memory>
|
||||
|
||||
namespace matador::sql {
|
||||
|
||||
template < class Type >
|
||||
class foreign : public utils::identifiable
|
||||
class foreign
|
||||
{
|
||||
public:
|
||||
foreign() = default;
|
||||
explicit foreign(Type *obj)
|
||||
: obj_(obj) {}
|
||||
|
||||
void reset(const utils::identifier &id) override {
|
||||
id_ = id;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool has_primary_key() const override {
|
||||
return true;
|
||||
}
|
||||
|
||||
[[nodiscard]] const utils::identifier &primary_key() const override {
|
||||
return id_;
|
||||
}
|
||||
|
||||
utils::identifier &primary_key() override {
|
||||
return id_;
|
||||
}
|
||||
|
||||
[[nodiscard]] utils::identifier create_identifier() const override {
|
||||
return {id_};
|
||||
}
|
||||
|
||||
Type* operator->() { return obj_.get(); }
|
||||
const Type* operator->() const { return obj_.get(); }
|
||||
|
||||
@@ -40,7 +20,6 @@ public:
|
||||
const Type& operator*() const { return *obj_; }
|
||||
|
||||
private:
|
||||
utils::identifier id_;
|
||||
std::unique_ptr<Type> obj_;
|
||||
};
|
||||
|
||||
|
||||
@@ -6,10 +6,6 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace matador::utils {
|
||||
class identifiable;
|
||||
}
|
||||
|
||||
namespace matador::sql {
|
||||
|
||||
class key_value_generator
|
||||
|
||||
@@ -4,12 +4,14 @@
|
||||
#include "matador/sql/basic_condition.hpp"
|
||||
#include "matador/sql/column.hpp"
|
||||
#include "matador/sql/key_value_pair.hpp"
|
||||
#include "matador/sql/record.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace matador::sql {
|
||||
|
||||
class dialect;
|
||||
@@ -121,6 +123,8 @@ public:
|
||||
|
||||
std::string compile();
|
||||
|
||||
[[nodiscard]] const record& prototype() const;
|
||||
|
||||
private:
|
||||
void transition_to(state_t next);
|
||||
void initialize(command_t cmd, state_t state);
|
||||
@@ -135,6 +139,8 @@ private:
|
||||
|
||||
detail::any_type_to_string_visitor value_to_string_;
|
||||
|
||||
record prototype_;
|
||||
|
||||
using query_state_set = std::unordered_set<state_t>;
|
||||
using query_state_transition_map = std::unordered_map<state_t, query_state_set>;
|
||||
using query_state_to_string_map = std::unordered_map<state_t, std::string>;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef QUERY_QUERY_RESULT_HPP
|
||||
#define QUERY_QUERY_RESULT_HPP
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include "matador/sql/query_result_impl.hpp"
|
||||
|
||||
#include <memory>
|
||||
@@ -23,10 +25,10 @@ public:
|
||||
|
||||
public:
|
||||
query_result_iterator() = default;
|
||||
explicit query_result_iterator(query_result<Type> &res)
|
||||
explicit query_result_iterator(query_result<Type> *res)
|
||||
: result_(res)
|
||||
{}
|
||||
query_result_iterator(query_result<Type> &res, std::unique_ptr<Type> obj)
|
||||
query_result_iterator(query_result<Type> *res, std::unique_ptr<Type> obj)
|
||||
: obj_(std::move(obj))
|
||||
, result_(res)
|
||||
{}
|
||||
@@ -56,9 +58,9 @@ public:
|
||||
|
||||
self& operator++()
|
||||
{
|
||||
obj_.reset(result_.create());
|
||||
result_.bind(*obj_);
|
||||
if (!result_.fetch(*obj_)) {
|
||||
obj_.reset(result_->create());
|
||||
result_->bind(*obj_);
|
||||
if (!result_->fetch(*obj_)) {
|
||||
obj_.reset();
|
||||
}
|
||||
|
||||
@@ -69,9 +71,9 @@ public:
|
||||
{
|
||||
const self tmp(result_, obj_);
|
||||
|
||||
obj_.reset(result_.create());
|
||||
result_.bind(*obj_);
|
||||
if (!result_.fetch(*obj_)) {
|
||||
obj_.reset(result_->create());
|
||||
result_->bind(*obj_);
|
||||
if (!result_->fetch(*obj_)) {
|
||||
obj_.reset();
|
||||
}
|
||||
|
||||
@@ -100,7 +102,7 @@ public:
|
||||
|
||||
private:
|
||||
std::unique_ptr<Type> obj_;
|
||||
query_result<Type> &result_;
|
||||
query_result<Type> *result_{nullptr};
|
||||
};
|
||||
|
||||
template < typename Type >
|
||||
@@ -108,18 +110,22 @@ class query_result
|
||||
{
|
||||
public:
|
||||
using iterator = query_result_iterator<Type>;
|
||||
using creator_func = std::function<Type*()>;
|
||||
|
||||
public:
|
||||
explicit query_result(std::unique_ptr<query_result_impl> impl)
|
||||
: impl_(std::move(impl)) {}
|
||||
query_result(std::unique_ptr<query_result_impl> impl, creator_func creator)
|
||||
: creator_(creator)
|
||||
, impl_(std::move(impl)) {}
|
||||
|
||||
iterator begin() { return std::move(++iterator(*this)); }
|
||||
iterator begin() { return std::move(++iterator(this)); }
|
||||
iterator end() { return {}; }
|
||||
|
||||
private:
|
||||
friend class query_result_iterator<Type>;
|
||||
|
||||
Type* create() { return new Type; }
|
||||
Type* create() { return creator_(); }
|
||||
|
||||
void bind(const Type &obj)
|
||||
{
|
||||
@@ -132,6 +138,7 @@ private:
|
||||
}
|
||||
|
||||
private:
|
||||
creator_func creator_ = []{ return new Type; };
|
||||
std::unique_ptr<query_result_impl> impl_;
|
||||
};
|
||||
|
||||
|
||||
@@ -4,11 +4,10 @@
|
||||
#include "matador/utils/access.hpp"
|
||||
#include "matador/utils/field_attributes.hpp"
|
||||
|
||||
#include <string>
|
||||
#include "matador/sql/any_type.hpp"
|
||||
#include "matador/sql/types.hpp"
|
||||
|
||||
namespace matador::utils {
|
||||
class identifiable;
|
||||
}
|
||||
#include <string>
|
||||
|
||||
namespace matador::sql {
|
||||
|
||||
@@ -35,6 +34,7 @@ public:
|
||||
virtual void read_value(const char *id, size_t index, char *value, size_t s) = 0;
|
||||
virtual void read_value(const char *id, size_t index, std::string &value) = 0;
|
||||
virtual void read_value(const char *id, size_t index, std::string &value, size_t s) = 0;
|
||||
virtual void read_value(const char *id, size_t index, any_type &value, data_type_t type, size_t size) = 0;
|
||||
|
||||
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)
|
||||
@@ -51,9 +51,12 @@ public:
|
||||
}
|
||||
void on_attribute(const char *id, char *value, const utils::field_attributes &attr = utils::null_attributes);
|
||||
void on_attribute(const char *id, std::string &value, const utils::field_attributes &attr = utils::null_attributes);
|
||||
void on_attribute(const char *id, any_type &value, data_type_t type, const utils::field_attributes &attr = utils::null_attributes);
|
||||
|
||||
void on_belongs_to(const char *id, utils::identifiable &x, utils::cascade_type);
|
||||
void on_has_one(const char *id, utils::identifiable &x, utils::cascade_type);
|
||||
template < class Pointer >
|
||||
void on_belongs_to(const char *id, Pointer &x, utils::cascade_type) {}
|
||||
template < class Pointer >
|
||||
void on_has_one(const char *id, Pointer &x, utils::cascade_type) {}
|
||||
|
||||
template<class ContainerType>
|
||||
void on_has_many(const char *, ContainerType &, const char *, const char *, utils::cascade_type) {}
|
||||
@@ -66,15 +69,15 @@ public:
|
||||
template<class Type>
|
||||
bool fetch(Type &obj)
|
||||
{
|
||||
if (!next_row()) {
|
||||
if (!fetch()) {
|
||||
return false;
|
||||
}
|
||||
matador::utils::access::process(*this, obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
[[nodiscard]] virtual bool next_row() = 0;
|
||||
[[nodiscard]] virtual const char* column(size_t index) const = 0;
|
||||
[[nodiscard]] virtual bool fetch() = 0;
|
||||
|
||||
protected:
|
||||
size_t column_index_ = 0;
|
||||
|
||||
@@ -23,15 +23,17 @@ public:
|
||||
|
||||
record() = default;
|
||||
record(std::initializer_list<column> columns);
|
||||
record(const record&) = default;
|
||||
record& operator=(const record&) = default;
|
||||
record(record&&) noexcept = default;
|
||||
record& operator=(record&&) noexcept = default;
|
||||
~record() = default;
|
||||
|
||||
template<class Operator>
|
||||
void process(Operator &op)
|
||||
{
|
||||
for(auto &col : columns_) {
|
||||
// Todo: Find a solution to handle a column with process
|
||||
int todo{};
|
||||
matador::utils::access::attribute(op, col.name().c_str(), todo, col.attributes());
|
||||
col.process(op);
|
||||
}
|
||||
}
|
||||
template < typename Type >
|
||||
@@ -43,10 +45,10 @@ public:
|
||||
void append(column col);
|
||||
|
||||
[[nodiscard]] const column& at(const std::string &name) const;
|
||||
const column& at(size_t index);
|
||||
const column& at(size_t index) const;
|
||||
|
||||
iterator find(const std::string &column_name);
|
||||
const_iterator find(const std::string &column_name) const;
|
||||
[[nodiscard]] const_iterator find(const std::string &column_name) const;
|
||||
|
||||
iterator begin();
|
||||
[[nodiscard]] const_iterator begin() const;
|
||||
@@ -57,6 +59,8 @@ public:
|
||||
[[nodiscard]] const_iterator cend() const;
|
||||
|
||||
[[nodiscard]] size_t size() const;
|
||||
[[nodiscard]] bool empty() const;
|
||||
void clear();
|
||||
|
||||
private:
|
||||
column_by_index columns_;
|
||||
|
||||
Reference in New Issue
Block a user