add value and values classes that holds all the data

This commit is contained in:
Bartosz Wieczorek 2018-03-09 12:50:56 +01:00
parent f18a99f651
commit 451b0bbebb
18 changed files with 560 additions and 160 deletions

View File

@ -37,10 +37,15 @@ create table "system_info"(
"when" timestamp,
constraint "pk_system_info" primary key ("id")
);
create index "ix_system_info_name" on "system_info"("name") with ( FILLFACTOR=100 );
comment on table "system_info" is 'table introduced to save information about system e.g. actual db version / application version etc';
comment on column "system_info"."name" is '';
comment on column "system_info"."value" is '';
create index "ix_system_info_name"
on "system_info"("name")
with ( FILLFACTOR=100 );
comment on table "system_info"
is 'table introduced to save information about system e.g. actual db version / application version etc';
comment on column "system_info"."name"
is '';
comment on column "system_info"."value"
is '';
create table "group" (
"gid" serial not null,
@ -51,7 +56,8 @@ create table "group" (
constraint "pk_group_gid" primary key ("gid"),
constraint "ux_group_name" unique ("name")
);
create trigger "update_user_group_last_update" before update on "group" for each row execute PROCEDURE last_update_column();
create trigger "update_user_group_last_update"
before update on "group" for each row execute procedure last_update_column();
insert into "group"("name") values ('nogroup'), ('admins'), ('moderators'), ('users');
create or replace function default_group_id()
@ -95,12 +101,18 @@ create table "auth_info" (
constraint "pk_auth_into_id" primary key("id"),
constraint "ux_auth_info_email" unique ("email")
);
create trigger "update_auth_info_updated" before update on "auth_info" for each row execute PROCEDURE last_update_column();
comment on table "auth_info" is '';
comment on column "auth_info"."id" is '';
comment on column "auth_info"."group" is 'default user group';
comment on column "auth_info"."created" is 'time of created';
comment on column "auth_info"."config" is 'user configuration';
create trigger "update_auth_info_updated"
before update on "auth_info" for each row execute procedure last_update_column();
comment on table "auth_info"
is '';
comment on column "auth_info"."id"
is '';
comment on column "auth_info"."group"
is 'default user group';
comment on column "auth_info"."created"
is 'time of created';
comment on column "auth_info"."config"
is 'user configuration';
create table "auth_identity" (
@ -111,11 +123,16 @@ create table "auth_identity" (
constraint "pk_auth_identity_id" primary key("id"),
constraint "fk_auth_identity_auth_info_id" foreign key ("auth_info_id") references "auth_info" ("id") on delete cascade deferrable initially immediate
);
comment on table "auth_identity" is '';
comment on column "auth_identity"."id" is '';
comment on column "auth_identity"."auth_info_id" is '';
comment on column "auth_identity"."provider" is '';
comment on column "auth_identity"."identity" is '';
comment on table "auth_identity"
is '';
comment on column "auth_identity"."id"
is '';
comment on column "auth_identity"."auth_info_id"
is '';
comment on column "auth_identity"."provider"
is '';
comment on column "auth_identity"."identity"
is '';
create table "auth_token" (
"id" serial not null,
@ -126,12 +143,18 @@ create table "auth_token" (
constraint "pk_auth_token_id" primary key("id"),
constraint "fk_auth_token_auth_info_id" foreign key ("auth_info_id") references "auth_info" ("id") on delete cascade deferrable initially immediate
);
create index "ix_auth_token_value" ON "auth_token" ("value");
comment on table "auth_token" is '';
comment on column "auth_token"."id" is '';
comment on column "auth_token"."auth_info_id" is '';
comment on column "auth_token"."value" is '';
comment on column "auth_token"."expires" is '';
create index "ix_auth_token_value"
on "auth_token"("value");
comment on table "auth_token"
is '';
comment on column "auth_token"."id"
is '';
comment on column "auth_token"."auth_info_id"
is '';
comment on column "auth_token"."value"
is '';
comment on column "auth_token"."expires"
is '';
create table "user_audit_action" (
@ -140,9 +163,12 @@ create table "user_audit_action" (
constraint "pk_user_audit_action_id" primary key ("id"),
constraint "ux_user_audit_action_name" unique ("name" )
);
comment on table "user_audit_action" is 'action that user can take (like login/logout/config change?)';
comment on column "user_audit_action"."id" is '';
comment on column "user_audit_action"."name" is 'action name';
comment on table "user_audit_action"
is 'action that user can take (like login/logout/config change?)';
comment on column "user_audit_action"."id"
is '';
comment on column "user_audit_action"."name"
is 'action name';
insert into "user_audit_action"("name") values ('login'), ('logout');
@ -158,11 +184,16 @@ create UNLOGGED table "user_audit" (
);
create index "ix_user_history_data" ON "user_audit" ((("data" ->> 'status')::text)) WHERE ("data" ->> 'status') IS not null;
comment on table "user_audit" IS 'saves user actions like login/logout';
comment on column "user_audit"."id" is '';
comment on column "user_audit"."auth_info_id" is '';
comment on column "user_audit"."action_id" is '';
comment on column "user_audit"."data" is 'data column contains information about taken action (if login was successful? if not, from what ip this action was taken?)';
comment on column "user_audit"."when_happened" is '';
comment on column "user_audit"."id"
is '';
comment on column "user_audit"."auth_info_id"
is '';
comment on column "user_audit"."action_id"
is '';
comment on column "user_audit"."data"
is 'data column contains information about taken action (if login was successful? if not, from what ip this action was taken?)';
comment on column "user_audit"."when_happened"
is '';
--create table "user_groups"(
@ -186,16 +217,25 @@ create table "stat"(
constraint "fk_stat_user" foreign key ("owner") references "auth_info" ("id") on delete cascade deferrable initially immediate,
constraint "fk_stat_primary_group" foreign key ("group") references "group" ("gid") on delete cascade deferrable initially immediate
);
create trigger update_stat_last_update before update on stat for each row execute PROCEDURE last_update_column();
comment on table "stat" is '';
comment on column "stat"."id" is 'unique id for all objects in database';
comment on column "stat"."owner" is 'uid of object''s owner';
comment on column "stat"."group" is 'groups of object';
comment on column "stat"."unixperms" is 'Unixpermissions';
comment on column "stat"."status" is 'status in which object is in (login, logout, removed etc)';
comment on column "stat"."name" is '';
comment on column "stat"."created" is '';
comment on column "stat"."updated" is '';
create trigger update_stat_last_update before update on stat for each row execute procedure last_update_column();
comment on table "stat"
is '';
comment on column "stat"."id"
is 'unique id for all objects in database';
comment on column "stat"."owner"
is 'uid of object''s owner';
comment on column "stat"."group"
is 'groups of object';
comment on column "stat"."unixperms"
is 'Unixpermissions';
comment on column "stat"."status"
is 'status in which object is in (login, logout, removed etc)';
comment on column "stat"."name"
is '';
comment on column "stat"."created"
is '';
comment on column "stat"."updated"
is '';
--create table "action"(
@ -276,11 +316,16 @@ create index "ix_category_parent_path" on "category" using GIST ("parent_path");
create unique index "ux_category_name" on "category"("parent_id", "name" );
create trigger "update_category_last_update" before update on "category" for each row execute procedure last_update_column();
create trigger "update_category_parent_path" before insert or update on "category" for each row execute procedure update_category_parent_path();
comment on table "category" is 'categories of items';
comment on column "category"."parent_id" is '';
comment on column "category"."parent_path" is '';
comment on column "category"."description" is '';
comment on column "category"."thumbnail" is '';
comment on table "category"
is 'categories of items';
comment on column "category"."parent_id"
is '';
comment on column "category"."parent_path"
is '';
comment on column "category"."description"
is '';
comment on column "category"."thumbnail"
is '';
create table "unit"(
@ -291,46 +336,71 @@ create table "unit"(
constraint "pk_unit" primary key ("id")
) inherits(stat);
create unique index "uk_unit_name" on "unit"("name", "symbol");
create trigger update_unit_last_update before update on "unit" for each row execute PROCEDURE last_update_column();
comment on table "unit" is 'categories of items';
comment on column "unit"."symbol" is '';
comment on column "unit"."description" is '';
comment on column "unit"."dimension_symbol" is '';
create trigger update_unit_last_update before update on "unit" for each row execute procedure last_update_column();
comment on table "unit"
is 'categories of items';
comment on column "unit"."symbol"
is '';
comment on column "unit"."description"
is '';
comment on column "unit"."dimension_symbol"
is '';
create table "parameter"(
"unit_id" int,
"type" text,
"description" text,
constraint "pk_parameter" primary key ("id"),
constraint "fk_parameter_unit" foreign key ("unit_id") references "unit"("id") on delete cascade deferrable initially immediate
) inherits(stat);
create unique index "uk_parameter_name" on "parameter"("name");
create trigger update_parameter_last_update before update on "parameter" for each row execute PROCEDURE last_update_column();
comment on table "parameter" is 'Parameter';
comment on column "parameter"."unit_id" is '';
comment on column "parameter"."description" is '';
create trigger update_parameter_last_update before update on "parameter" for each row execute procedure last_update_column();
comment on table "parameter"
is 'Parameter data';
comment on table "parameter"."name"
is 'name of parameter e.g. Max power';
comment on column "parameter"."unit_id"
is 'id of assigned unit (for range types, unit/list types indicated type of single value)';
comment on column "parameter"."type"
is 'Type ot the parameter numeric/text or some variations e.g. list->"numeric[]", range->"numeric..."';
comment on column "parameter"."description"
is '';
--create table "producer"(
--) inherits ("stat");
-- TODO create fulltext search on short_desc column
-- TODO create "producer" table to save producers there insted in items table
create table "item"(
"symbol" text not null,
"original_symbol" text,
"producer_symbol" text,
"producer" text,
"attributes" jsonb not null DEFAULT('{}'),
"short_desc" text,
"description" text,
constraint "pk_items" primary key ("id"),
constraint "fk_item_auth_info" foreign key ("owner") references "auth_info"("id") deferrable initially immediate
) inherits (stat);
) inherits ("stat");
create index "ix_item_attributes" on "item" USING GIN ("attributes");
create unique index "ux_item" on "item"("name", "symbol");
create trigger update_item_last_update before update on item for each row execute PROCEDURE last_update_column();
comment on table "item" is '';
comment on column "item"."symbol" is '';
comment on column "item"."original_symbol" is '';
comment on column "item"."producer" is '';
comment on column "item"."attributes" is '';
comment on column "item"."short_desc" is '';
comment on column "item"."description" is '';
create index "ix_item_producer" on "item"("producer");
create index "ix_item_producer_symbol" on "item"("producer_symbol");
create unique index "ux_item_symbol" on "item"("name");
create trigger update_item_last_update before update on item for each row execute procedure last_update_column();
comment on table "item"
is '';
comment on column "item"."name"
is 'Item symbol saved in database';
comment on column "item"."producer_symbol"
is 'symbol of the producent';
comment on column "item"."producer"
is 'producent';
comment on column "item"."attributes"
is 'JSON list of values';
comment on column "item"."short_desc"
is '';
comment on column "item"."description"
is '';
create table "category_items"(
@ -340,7 +410,8 @@ create table "category_items"(
constraint "fk_category_id" foreign key ("category_id") references "category"("id") on delete cascade deferrable initially immediate,
constraint "fk_item_id" foreign key ("item_id") references "item"("id") on delete cascade deferrable initially immediate
);
comment on table "category_items" is '';
comment on table "category_items"
is '';
--create table "inventory"(
@ -349,7 +420,7 @@ comment on table "category_items" is '';
-- constraint "fk_inventory_owner" foreign key ("owner") references "auth_info" ("id") deferrable initially immediate,
-- constraint "chk_inventory_name_length" check (length(name) < 100)
--) inherits (stat);
--create trigger update_inventory_last_update before update on inventory for each row execute PROCEDURE last_update_column();
--create trigger update_inventory_last_update before update on inventory for each row execute procedure last_update_column();
--create table "user_inventory"(
@ -366,12 +437,14 @@ comment on table "category_items" is '';
--);
--comment on table in_stock IS 'Table contains information about items being available in storage';
--create table inventory_operations(
-- constraint inventory_operations_pkey primary key (uid),
-- constraint OperationOwner_fk foreign key (owner) references users (uid) deferrable initially IMMEDIATE,
-- constraint inventory_operation_unique UNIQUE (name)
--) inherits(stat);
--create table inventory_history(
-- inventory_from_id INTEGER not null references inventory on DELETE CASCADE,
-- inventory_to_id INTEGER not null references inventory on DELETE CASCADE,

View File

@ -1,12 +1,12 @@
set(LIB postgres_connector)
file(GLOB_RECURSE postgres_connector_SOURCE src/*)
file(GLOB_RECURSE ${LIB}_SOURCE src/*)
# find packages
find_package(Sqlpp-connector-postgresql REQUIRED)
# create library
add_library(${LIB} ${postgres_connector_SOURCE})
add_library(${LIB} ${${LIB}_SOURCE})
# link all
target_include_directories (${LIB}

View File

@ -2,11 +2,22 @@
#include <eedb/db/Parameter.hpp>
#include <utils/spimpl.hpp>
namespace eedb::db{
class PgConnection;
}
namespace eedb {
class PgParametersRepository : public ParametersRepository {
// ParametersRepository interface
public:
PgParametersRepository(db::PgConnection&db);
std::unique_ptr< Parameter > create(std::string name, std::string description) const override;
std::unique_ptr< Parameter > search(std::string name) const override;
private:
struct PgParametersRepositoryPriv;
spimpl::unique_impl_ptr< PgParametersRepositoryPriv > _priv;
};
} // namespace eedb

View File

@ -11,13 +11,13 @@
#include <eedb/db/pg/model/unit.h>
#include <eedb/db/pg/model/user_audit.h>
constexpr eedb::auth_identity t_auth_identity;
constexpr eedb::auth_info t_auth_info;
constexpr eedb::auth_token t_auth_token;
constexpr eedb::category t_category;
constexpr eedb::group t_group;
constexpr eedb::parameter t_parameter;
constexpr eedb::stat t_stat;
constexpr eedb::system_info t_system_info;
constexpr eedb::unit t_unit;
constexpr eedb::user_audit t_user_audit;
static constexpr eedb::auth_identity t_auth_identity;
static constexpr eedb::auth_info t_auth_info;
static constexpr eedb::auth_token t_auth_token;
static constexpr eedb::category t_category;
static constexpr eedb::group t_group;
static constexpr eedb::parameter t_parameter;
static constexpr eedb::stat t_stat;
static constexpr eedb::system_info t_system_info;
static constexpr eedb::unit t_unit;
static constexpr eedb::user_audit t_user_audit;

View File

@ -2,7 +2,29 @@
#include <eedb/mock/db/ParameterMock.hpp>
#include <sqlpp11/postgresql/insert.h>
#include <sqlpp11/sqlpp11.h>
#include <eedb/db/pg/connection.hpp>
#include <eedb/db/pg/model/all.hpp>
namespace eedb::db::pg {
class ParameterMock : public ::eedb::ParameterMock {};
class ParameterMock : public ::eedb::ParameterMock {
public:
ParameterMock(db::PgConnection & db) : _db{db} {}
void _init(std::string name) {
using namespace sqlpp;
_id = _db(sqlpp::postgresql::insert_into(t_parameter) //
.set(t_parameter.name = name) //
.returning(t_parameter.id))
.front()
.id;
}
private:
db::PgConnection & _db;
int64_t _id{0};
};
} // namespace eedb::db::pg

View File

@ -0,0 +1,19 @@
#include <eedb/db/pg/ParametersRepository.hpp>
#include <sqlpp11/sqlpp11.h>
#include <eedb/db/pg/model/all.hpp>
namespace eedb{
struct PgParametersRepository::PgParametersRepositoryPriv {};
PgParametersRepository::PgParametersRepository(db::PgConnection & db) : _priv{spimpl::make_unique_impl< PgParametersRepositoryPriv >()} {}
std::unique_ptr<Parameter> PgParametersRepository::create(std::string name, std::string description) const
{
}
std::unique_ptr<Parameter> PgParametersRepository::search(std::string name) const
{
}
} // namespace eedb

View File

@ -15,10 +15,10 @@ struct PgCategories::PgCategoriesPriv {
return [](auto & cat) { return cat.get(); };
}
PgCategoriesPriv(std::unique_ptr<std::vector< std::unique_ptr< Category > > > data) : _cache{std::move(data)} {}
PgCategoriesPriv(std::unique_ptr< std::vector< std::unique_ptr< Category > > > data) : _cache{std::move(data)} {}
private:
std::unique_ptr<std::vector< std::unique_ptr< Category > > > _cache;
std::unique_ptr< std::vector< std::unique_ptr< Category > > > _cache;
};
PgCategories::PgCategories(std::unique_ptr< std::vector< std::unique_ptr< Category > > > data)

View File

@ -15,11 +15,11 @@ struct PgCategory::PgCategoryPrivate {
private:
// select
constexpr auto stat_columns() const {
return std::make_tuple(t_category.name, t_category.status);
return std::tuple{t_category.name, t_category.status};
}
constexpr auto category_columns() const {
return std::make_tuple(t_category.description, t_category.id, t_category.parent_path);
return std::tuple{t_category.description, t_category.id, t_category.parent_path};
}
constexpr auto columns() const {
@ -41,12 +41,12 @@ struct PgCategory::PgCategoryPrivate {
}
// set
auto set_stat() const {
return std::make_tuple( //
t_category.owner = _owner->uid(),
t_category.status = 0,
t_category.unixperms = sqlpp::verbatim< sqlpp::integer >(R"(unix_to_numeric("764"))"));
}
// auto set_stat() const {
// return std::tuple{//
// t_category.owner = _owner->uid(),
// t_category.status = 0,
// t_category.unixperms = sqlpp::verbatim< sqlpp::integer >(R"(unix_to_numeric("764"))")};
// }
public:
Category * _self{nullptr};
@ -102,6 +102,10 @@ struct PgCategory::PgCategoryPrivate {
return _parent;
}
auto displayName() const {
return _name;
}
protected:
template < typename Row >
void init_data(Row & row) {
@ -130,7 +134,9 @@ PgCategory::PgCategory(spimpl::impl_ptr< PgCategoryPrivate > priv) : _priv{std::
_priv->_self = this;
}
Category::string_view PgCategory::displayName() const {}
Category::string_view PgCategory::displayName() const {
return _priv->displayName();
}
Category * PgCategory::parent() const {
return _priv->parent();

View File

@ -4,13 +4,22 @@
#include <eedb/Value.hpp>
#include <eedb/db/User.hpp>
#include <sqlpp11/sqlpp11.h>
#include <nlohmann/json.hpp>
namespace eedb {
struct PgItemsRepository::PgItemsRepositoryPriv {};
PgItemsRepository::PgItemsRepository(db::PgConnection & db, User * owner) : _priv{spimpl::make_unique_impl< PgItemsRepositoryPriv >()} {}
std::unique_ptr< Item > PgItemsRepository::create(item::Identyfier id, Values values, std::optional< item::Foto >) const {
//
auto attributes = nlohmann::json();
values.serialize(attributes);
std::cout<<attributes.dump(2);
return {};
}
std::unique_ptr< Items > PgItemsRepository::search(const ItemQueryFilters & filer) const {

View File

@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.0.2)
find_package(GMock CONFIG REQUIRED)
set(TEST_EXECUTABLE_NAME postgres_connector-test )
set(TEST_EXECUTABLE_NAME test-postgres_connector)
#add test files
file(GLOB_RECURSE TEST_FILES test_*.cpp )

View File

@ -14,11 +14,23 @@
class PgItemsRepositoryTest : public DbTestBase< PgItemsRepositoryTest > {
public:
PgItemsRepositoryTest() : user{db()}, category{db()} {
PgItemsRepositoryTest() : user{db()}, category{db()}, numericParameter{db()}, textParameter{db()} {
using namespace testing;
db().native()->start_transaction();
user._init(); // create fake user
category._init_simple("main");
numericParameter._init("numeric");
textParameter._init("text");
sut = std::make_unique< eedb::PgItemsRepository >(db(), &user);
}
auto some_id() {
return eedb::item::Identyfier{"AM2DM-2415SH60", "AM2DM-2415SH60"};
}
auto some_val() {
using namespace std::string_literals;
return eedb::Values(eedb::Value{5, &numericParameter}, eedb::Value{"some text"s, &textParameter});
}
~PgItemsRepositoryTest() {
@ -28,7 +40,7 @@ class PgItemsRepositoryTest : public DbTestBase< PgItemsRepositoryTest > {
protected:
eedb::db::pg::UserMock user;
eedb::db::pg::CategoryMock category;
eedb::db::pg::ParameterMock parameter;
eedb::db::pg::ParameterMock numericParameter, textParameter;
int64_t sutId;
std::unique_ptr< eedb::PgItemsRepository > sut;
@ -37,4 +49,13 @@ class PgItemsRepositoryTest : public DbTestBase< PgItemsRepositoryTest > {
template <>
std::unique_ptr< PgTestDatabasePrepare > DbTestBase< PgItemsRepositoryTest >::_test_db = {};
TEST_F(PgItemsRepositoryTest, getListOfParameters) {}
TEST_F(PgItemsRepositoryTest, createParameterDontfail) {
EXPECT_TRUE(sut->create(some_id(), some_val(), {}));
}
TEST_F(PgItemsRepositoryTest, createReturnsValidParameter) {
auto item = sut->create(some_id(), some_val(), {});
ASSERT_TRUE(item);
EXPECT_EQ(item->displayName(), "AM2DM-2415SH60");
// EXPECT_EQ(item->values())
}

View File

@ -7,6 +7,17 @@
class PgParametersRepositoryTest : public DbTestBase< PgParametersRepositoryTest > {
public:
PgParametersRepositoryTest() : user{db()}, parameter{db()} {
db().native()->start_transaction();
user._init();
parameter._init("paraemter");
sut = std::make_unique< eedb::PgParametersRepository >(db());
}
~PgParametersRepositoryTest() {
db().native()->rollback_transaction(false);
}
protected:
eedb::db::pg::UserMock user;
eedb::db::pg::ParameterMock parameter;
@ -16,3 +27,19 @@ class PgParametersRepositoryTest : public DbTestBase< PgParametersRepositoryTest
template <>
std::unique_ptr< PgTestDatabasePrepare > DbTestBase< PgParametersRepositoryTest >::_test_db = {};
TEST_F(PgParametersRepositoryTest, searchForParameterByName){
EXPECT_TRUE(sut->search("parameter"));
}
TEST_F(PgParametersRepositoryTest, searchForBadName){
EXPECT_FALSE(sut->search("bad_parameter"));
}
TEST_F(PgParametersRepositoryTest, init3){
}
TEST_F(PgParametersRepositoryTest, init4){
}

View File

@ -13,3 +13,4 @@ target_include_directories(${LIB}
# add tests
add_subdirectory(mock)
add_subdirectory(test)

View File

@ -6,71 +6,168 @@
#include <eedb/db/Parameter.hpp>
#include <nlohmann/json.hpp>
namespace eedb {
class Value;
namespace details {
class ValueBase {
public:
virtual ~ValueBase() = default;
virtual nlohmann::json serializeValue() const = 0;
};
template < typename T_ >
class Value : public ValueBase {
public:
template < typename T >
explicit Value(T t) : _value{static_cast< T_ >(t)} {}
nlohmann::json serializeValue() const override {
return _value;
}
private:
T_ _value;
};
template < typename V >
class Range : public ValueBase {
static_assert(std::is_base_of_v< ValueBase, V >);
public:
template < class T, class U >
Range(std::pair< T, U > value) : _value{std::move(value)} {}
nlohmann::json serializeValue() const override {
return {{"min", _value.first.serializeValue()}, {"max", _value.second.serializeValue()}};
}
private:
// min / max pair of values
std::pair< V, V > _value;
};
using NumericValue = Value< double >;
using TextValue = Value< std::string >;
using NumericList = Value< std::vector< double > >;
using TextList = Value< std::vector< std::string > >;
using NumericRange = Range< NumericValue >;
} // namespace details
class Value {
public:
template < typename T >
Value(T attribute, //
Parameter * parameter,
typename std::enable_if_t< std::is_same_v< std::string, T > > * = nullptr)
: _value{std::make_unique< details::TextValue >(std::move(attribute))}, _parameter{parameter} {}
template < typename T >
Value(T number,
Parameter * parameter,
typename std::enable_if_t< std::is_integral_v< T > || std::is_floating_point_v< T > > * = nullptr)
: _value{std::make_unique< details::NumericValue >(number)}, _parameter{parameter} {}
template < typename T >
Value(std::pair< T, T > range,
Parameter * parameter,
typename std::enable_if_t< std::is_integral_v< T > || std::is_floating_point_v< T > > * = nullptr)
: _value{std::make_unique< details::NumericRange >(range)}, _parameter{parameter} {}
template < typename T >
Value(std::vector< T > attributes, //
Parameter * parameter,
typename std::enable_if_t< std::is_same_v< std::string, T > > * = nullptr)
: _value{std::make_unique< details::TextList >(std::move(attributes))}, _parameter{parameter} {}
template < typename T >
Value(std::vector< T > numbers,
Parameter * parameter,
typename std::enable_if_t< std::is_integral_v< T > || std::is_floating_point_v< T > > * = nullptr)
: _value{std::make_unique< details::NumericList >(std::move(numbers))}, _parameter{parameter} {}
Value(const Value &) = default;
Value & operator=(const Value &) = delete;
Value(Value &&) = default;
Value & operator=(Value &&) = default;
void serialize(nlohmann::json & json) const {
json["value"] = _value->serializeValue();
if(_parameter)
json["parameter"] = std::string{_parameter->name()};
}
nlohmann::json serialize() const {
nlohmann::json json;
serialize(json);
return json;
}
Parameter * parameter() const {
return _parameter;
}
private:
std::unique_ptr< details::ValueBase > _value;
Parameter * _parameter{nullptr};
};
/**
* @brief The Values class
*/
class Values {
public:
virtual ~Values() = default;
};
Values() {}
class NumericValue {
public:
explicit NumericValue(double t) : _value{t} {}
std::string to_string() const {
return std::to_string(_value);
template < typename... VList >
Values(VList &&... vs) {
_values.reserve(sizeof...(vs));
emplace_(std::forward< VList >(vs)...);
}
double value() const {
return _value;
Values(std::vector< Value > values) : _values{std::move(values)} {}
auto begin() {
return _values.begin();
}
auto begin() const {
return _values.begin();
}
auto end() {
return _values.end();
}
auto end() const {
return _values.end();
}
bool serialize(nlohmann::json & json) const {
json["values"] = nlohmann::json::array();
for(const auto & value : *this) {
value.serialize(json);
}
return true;
}
private:
double _value;
};
class TextValue {
public:
explicit TextValue(std::string_view value) : _value{value} {}
std::string to_string() const {
return _value;
template < typename V, typename... VList >
void emplace_(V && v, VList &&... vs) {
_values.emplace_back(std::forward< V >(v));
if constexpr(sizeof...(vs)) {
emplace_(std::forward< VList >(vs)...);
}
}
std::string_view value() const {
return _value;
}
private:
std::string _value;
};
/**
* @brief The Value class
*/
class Value {
public:
enum class Type { Numeric, Text };
/**
* @brief to_string
* @return returns value as string
*/
std::string to_string() const;
Type type() const {
return Type::Numeric;
}
Parameter * parameter() const {}
private:
std::variant< TextValue, NumericValue > _value;
std::vector< Value > _values;
};
} // namespace eedb

View File

@ -33,22 +33,19 @@ namespace item {
class Identyfier {
public:
std::string_view name() const {
return _name;
}
std::string_view producerSymbol() const {
return _prod;
}
Identyfier(std::string symbol, std::string producer_symbol={}) : _sym{std::move(symbol)}, _prod{std::move(producer_symbol)} {}
std::string_view symbol() const {
return _sym;
}
std::string_view producerSymbol() const {
return _prod.empty() ? _sym : _prod;
}
private:
std::string _name;
std::string _prod;
std::string _sym;
std::string _prod;
};
class Foto {

View File

@ -37,6 +37,17 @@ namespace details {
class Parameters : public details::ParameterPtrIteratorRange {};
enum class Type {
Numeric = 0x1 << 0,
NumericList,
NumericRange,
Text = 0x1 << 4,
TextList,
Script = 0x1 << 8
};
/**
* @brief The Parameter class
*/
@ -45,21 +56,32 @@ class Parameter {
virtual ~Parameter() = default;
/**
* @brief unit
* @return
* @brief type
* @return supported type od data
*/
Type type() const noexcept(true) {
return _type;
}
/**
* @brief unit of given parameter, probably make sanse to have it only for numeric types of parameter
* @return unit for given parameter e.g. If the Parameter is "Max current" the Unit can be "A"
*/
virtual std::optional< Unit > unit() const = 0;
/**
* @brief name
* @return
* @return display name of parameter e.g. "Max current"
*/
virtual std::string_view name() const = 0;
/**
* @brief description
* @return
* @return parameter description
*/
virtual std::string_view description() const = 0;
protected:
Type _type;
};
} // namespace eedb

View File

@ -0,0 +1,17 @@
cmake_minimum_required(VERSION 3.0.2)
find_package(GMock CONFIG REQUIRED)
set(TEST_EXECUTABLE_NAME test-eedb_api )
#add test files
file(GLOB_RECURSE TEST_FILES test_*.cpp )
add_executable( ${TEST_EXECUTABLE_NAME} ${TEST_FILES})
target_link_libraries(${TEST_EXECUTABLE_NAME}
PRIVATE eedb-api
PRIVATE eedb-mock
PRIVATE GMock::main
)
add_test( ${TEST_EXECUTABLE_NAME} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${TEST_EXECUTABLE_NAME})

View File

@ -0,0 +1,78 @@
#include <gmock/gmock.h>
#include <eedb/Value.hpp>
#include <eedb/mock/db/ParameterMock.hpp>
class ValueTest : public testing::Test {
protected:
eedb::ParameterMock parameter;
};
using namespace testing;
TEST_F(ValueTest, init) {
eedb::Value _int{int{1}, &parameter};
eedb::Value _flo{float{2}, &parameter};
eedb::Value _dou{double{3}, &parameter};
}
TEST_F(ValueTest, serializeInt) {
EXPECT_CALL(parameter, name()).WillOnce(Return("parameter name"));
eedb::Value _int{4, &parameter};
auto json = nlohmann::json{};
_int.serialize(json);
EXPECT_EQ(json, (nlohmann::json{{"value", 4.0}, {"parameter", "parameter name"}}));
}
TEST_F(ValueTest, serializeDouble) {
EXPECT_CALL(parameter, name()).WillOnce(Return("parameter name"));
eedb::Value _double{4.0, &parameter};
auto json = nlohmann::json{};
_double.serialize(json);
EXPECT_EQ(json, (nlohmann::json{{"value", 4.0}, {"parameter", "parameter name"}}));
}
TEST_F(ValueTest, serializeString) {
EXPECT_CALL(parameter, name()).WillOnce(Return("parameter name"));
eedb::Value _string{std::string{"asdfghjkl"}, &parameter};
auto json = nlohmann::json{};
_string.serialize(json);
EXPECT_EQ(json, (nlohmann::json{{"value", "asdfghjkl"}, {"parameter", "parameter name"}}));
}
TEST_F(ValueTest, serializeListOfInts) {
EXPECT_CALL(parameter, name()).WillOnce(Return("parameter name"));
eedb::Value _intList{std::vector<double>{1, 2, 3, 4, 5, 6}, &parameter};
EXPECT_EQ(_intList.serialize(), (nlohmann::json{{"value", {1, 2, 3, 4, 5, 6}}, {"parameter", "parameter name"}}));
}
TEST_F(ValueTest, serializeListOfStrings) {
using namespace std::string_literals;
EXPECT_CALL(parameter, name()).WillOnce(Return("parameter name"));
eedb::Value _stringList{std::vector{"a"s, "b"s, "c"s}, &parameter};
auto json = nlohmann::json{};
_stringList.serialize(json);
EXPECT_EQ(json, (nlohmann::json{{"value", {"a"s, "b"s, "c"s}}, {"parameter", "parameter name"}}));
}
TEST_F(ValueTest, serializeListOfRange) {
EXPECT_CALL(parameter, name()).WillOnce(Return("parameter name"));
eedb::Value _range{std::pair{0.001, 1000.0}, &parameter};
auto json = nlohmann::json{};
_range.serialize(json);
EXPECT_EQ(json, (nlohmann::json{{"value", {{"min", 0.001}, {"max", 1000.0}}}, {"parameter", "parameter name"}}));
}