mirror of https://github.com/SeanOMik/libki.git
dml: Simple implementation
Still missing specializations for each DML type
This commit is contained in:
parent
18b6aeb407
commit
be07d23ecf
|
@ -7,18 +7,25 @@ namespace ki
|
||||||
namespace dml
|
namespace dml
|
||||||
{
|
{
|
||||||
template <typename ValueT>
|
template <typename ValueT>
|
||||||
class Field : public FieldBase
|
class Field final : public FieldBase
|
||||||
{
|
{
|
||||||
friend Record;
|
friend Record;
|
||||||
public:
|
public:
|
||||||
ValueT get_value() const;
|
virtual ~Field() = default;
|
||||||
void set_value(ValueT value);
|
|
||||||
|
|
||||||
Field<ValueT> *clone(const Record &record) const;
|
ValueT get_value() const
|
||||||
|
{
|
||||||
|
return m_value;
|
||||||
|
}
|
||||||
|
|
||||||
void write_to(std::ostream &ostream) const;
|
void set_value(ValueT value)
|
||||||
void read_from(std::istream &istream);
|
{
|
||||||
size_t get_size() const;
|
m_value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_to(std::ostream &ostream) const final;
|
||||||
|
void read_from(std::istream &istream) final;
|
||||||
|
size_t get_size() const final;
|
||||||
protected:
|
protected:
|
||||||
Field(std::string name, const Record &record)
|
Field(std::string name, const Record &record)
|
||||||
: FieldBase(name, record)
|
: FieldBase(name, record)
|
||||||
|
@ -28,6 +35,14 @@ namespace dml
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
ValueT m_value;
|
ValueT m_value;
|
||||||
|
|
||||||
|
Field<ValueT> *clone(const Record &record) const final
|
||||||
|
{
|
||||||
|
auto *clone = new Field<ValueT>(m_name, record);
|
||||||
|
clone->m_transferable = true;
|
||||||
|
clone->m_value = m_value;
|
||||||
|
return clone;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef Field<BYT> BytField;
|
typedef Field<BYT> BytField;
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <typeinfo>
|
||||||
#include "../util/Serializable.h"
|
#include "../util/Serializable.h"
|
||||||
|
|
||||||
namespace ki
|
namespace ki
|
||||||
|
@ -14,6 +15,8 @@ namespace dml
|
||||||
{
|
{
|
||||||
friend Record;
|
friend Record;
|
||||||
public:
|
public:
|
||||||
|
virtual ~FieldBase() = default;
|
||||||
|
|
||||||
const Record &get_record() const;
|
const Record &get_record() const;
|
||||||
std::string get_name() const;
|
std::string get_name() const;
|
||||||
bool is_transferable() const;
|
bool is_transferable() const;
|
||||||
|
@ -24,18 +27,15 @@ namespace dml
|
||||||
return (typeid(ValueT).hash_code() == m_type_hash);
|
return (typeid(ValueT).hash_code() == m_type_hash);
|
||||||
}
|
}
|
||||||
protected:
|
protected:
|
||||||
|
std::string m_name;
|
||||||
|
bool m_transferable;
|
||||||
size_t m_type_hash;
|
size_t m_type_hash;
|
||||||
|
|
||||||
FieldBase(std::string name, const Record& record);
|
FieldBase(std::string name, const Record& record);
|
||||||
|
|
||||||
void set_name(std::string name);
|
|
||||||
void set_transferable(bool transferable);
|
|
||||||
|
|
||||||
virtual FieldBase *clone(const Record &record) const = 0;
|
virtual FieldBase *clone(const Record &record) const = 0;
|
||||||
private:
|
private:
|
||||||
const Record &m_record;
|
const Record &m_record;
|
||||||
std::string m_name;
|
|
||||||
bool m_transferable;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<FieldBase *> FieldList;
|
typedef std::vector<FieldBase *> FieldList;
|
||||||
|
|
|
@ -6,11 +6,12 @@ namespace ki
|
||||||
{
|
{
|
||||||
namespace dml
|
namespace dml
|
||||||
{
|
{
|
||||||
class Record : public util::Serializable
|
class Record final : public util::Serializable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Record();
|
Record();
|
||||||
Record(const Record &record);
|
Record(const Record &record);
|
||||||
|
virtual ~Record();
|
||||||
|
|
||||||
bool has_field(std::string name) const;
|
bool has_field(std::string name) const;
|
||||||
|
|
||||||
|
@ -19,33 +20,35 @@ namespace dml
|
||||||
{
|
{
|
||||||
if (!has_field(name))
|
if (!has_field(name))
|
||||||
return false;
|
return false;
|
||||||
return m_field_map[name]->is_type<ValueT>();
|
return m_field_map.at(name)->is_type<ValueT>();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ValueT>
|
template <typename ValueT>
|
||||||
Field<ValueT> &get_field(std::string name) const
|
Field<ValueT> *get_field(std::string name) const
|
||||||
{
|
{
|
||||||
if (has_field<ValueT>(name))
|
if (has_field<ValueT>(name))
|
||||||
return dynamic_cast<Field<ValueT> *>(m_fields[name]);
|
return dynamic_cast<Field<ValueT> *>(m_field_map.at(name));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ValueT>
|
template <typename ValueT>
|
||||||
Field<ValueT> &add_field(std::string name, bool transferable = true)
|
Field<ValueT> *add_field(std::string name, bool transferable = true)
|
||||||
{
|
{
|
||||||
|
// Does this field already exist?
|
||||||
if (has_field<ValueT>(name))
|
if (has_field<ValueT>(name))
|
||||||
return nullptr;
|
return get_field<ValueT>(name);
|
||||||
Field<ValueT> *field = new Field<ValueT>(name, *this);
|
|
||||||
auto *base = static_cast<FieldBase *>(field);
|
// Create the field
|
||||||
m_fields.push_back(base);
|
auto *field = new Field<ValueT>(name, *this);
|
||||||
m_field_map.insert({ base->get_name(), base });
|
field->m_transferable = transferable;
|
||||||
|
add_field(field);
|
||||||
return field;
|
return field;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t get_field_count() const;
|
size_t get_field_count() const;
|
||||||
|
|
||||||
FieldList::iterator fields_begin() const;
|
FieldList::const_iterator fields_begin() const;
|
||||||
FieldList::iterator fields_end() const;
|
FieldList::const_iterator fields_end() const;
|
||||||
|
|
||||||
void write_to(std::ostream &ostream) const;
|
void write_to(std::ostream &ostream) const;
|
||||||
void read_from(std::istream &istream);
|
void read_from(std::istream &istream);
|
||||||
|
@ -53,6 +56,8 @@ namespace dml
|
||||||
private:
|
private:
|
||||||
FieldList m_fields;
|
FieldList m_fields;
|
||||||
FieldNameMap m_field_map;
|
FieldNameMap m_field_map;
|
||||||
|
|
||||||
|
void add_field(FieldBase *field);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
#include "ki/dml/FieldBase.h"
|
||||||
|
|
||||||
|
namespace ki
|
||||||
|
{
|
||||||
|
namespace dml
|
||||||
|
{
|
||||||
|
FieldBase::FieldBase(std::string name, const Record& record)
|
||||||
|
: m_record(record)
|
||||||
|
{
|
||||||
|
m_name = name;
|
||||||
|
m_transferable = true;
|
||||||
|
m_type_hash = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Record &FieldBase::get_record() const
|
||||||
|
{
|
||||||
|
return m_record;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string FieldBase::get_name() const
|
||||||
|
{
|
||||||
|
return m_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FieldBase::is_transferable() const
|
||||||
|
{
|
||||||
|
return m_transferable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
#include "ki/dml/Record.h"
|
||||||
|
|
||||||
|
namespace ki
|
||||||
|
{
|
||||||
|
namespace dml
|
||||||
|
{
|
||||||
|
Record::Record()
|
||||||
|
{
|
||||||
|
m_fields = FieldList();
|
||||||
|
m_field_map = FieldNameMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
Record::~Record()
|
||||||
|
{
|
||||||
|
m_fields.clear();
|
||||||
|
m_field_map.clear();
|
||||||
|
for (auto it = m_fields.begin(); it != m_fields.end(); ++it)
|
||||||
|
delete *it;
|
||||||
|
}
|
||||||
|
|
||||||
|
Record::Record(const Record& record)
|
||||||
|
{
|
||||||
|
for (auto it = record.fields_begin(); it != record.fields_end(); ++it)
|
||||||
|
add_field((*it)->clone(*this));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Record::has_field(std::string name) const
|
||||||
|
{
|
||||||
|
return m_field_map.count(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Record::get_field_count() const
|
||||||
|
{
|
||||||
|
return m_fields.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
FieldList::const_iterator Record::fields_begin() const
|
||||||
|
{
|
||||||
|
return m_fields.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
FieldList::const_iterator Record::fields_end() const
|
||||||
|
{
|
||||||
|
return m_fields.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Record::write_to(std::ostream &ostream) const
|
||||||
|
{
|
||||||
|
for (auto it = m_fields.begin(); it != m_fields.end(); ++it)
|
||||||
|
(*it)->write_to(ostream);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Record::read_from(std::istream &istream)
|
||||||
|
{
|
||||||
|
for (auto it = m_fields.begin(); it != m_fields.end(); ++it)
|
||||||
|
(*it)->read_from(istream);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Record::get_size() const
|
||||||
|
{
|
||||||
|
size_t size = 0;
|
||||||
|
for (auto it = m_fields.begin(); it != m_fields.end(); ++it)
|
||||||
|
size += (*it)->get_size();
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Record::add_field(FieldBase* field)
|
||||||
|
{
|
||||||
|
m_fields.push_back(field);
|
||||||
|
m_field_map.insert({ field->get_name(), field });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue