From c34f7c5a079e7a529d6aff7d48970be3b28762cc Mon Sep 17 00:00:00 2001 From: Bartosz Wieczorek Date: Wed, 14 Mar 2018 12:43:19 +0100 Subject: [PATCH] some fixes --- sql/schema.sql | 42 ++++++++++------ .../include/eedb/db/pg/PgCategory.hpp | 2 - .../include/eedb/db/pg/Stats.hpp | 12 ++++- .../src/data/ParametersRepository.cpp | 2 +- .../src/data/PgCategory.cpp | 12 ----- .../src/data/PgItemsRepository.cpp | 50 ++++++++++++------- .../postgresql_connector/test/DbTestBase.hpp | 2 +- .../test/test_eedb_data_PgItemsRepository.cpp | 31 +++++++++--- .../test_eedb_data_PgParametersRepository.cpp | 2 +- src/libs/eedb/include/eedb/db/AuthInfo.hpp | 15 ++++++ src/libs/eedb/include/eedb/db/Category.hpp | 6 --- src/libs/eedb/include/eedb/db/Item.hpp | 36 ++++++++++--- src/libs/eedb/include/eedb/db/Parameter.hpp | 2 +- src/libs/eedb/include/eedb/db/StatInfo.hpp | 13 ----- src/libs/eedb/include/eedb/db/User.hpp | 8 ++- 15 files changed, 145 insertions(+), 90 deletions(-) delete mode 100644 src/libs/eedb/include/eedb/db/StatInfo.hpp diff --git a/sql/schema.sql b/sql/schema.sql index 554d259..82992bb 100644 --- a/sql/schema.sql +++ b/sql/schema.sql @@ -9,7 +9,7 @@ create extension if not exists "uuid-ossp"; create OR REPLACE function perm_to_numeric ( m_owner INT, m_group INT, m_other INT ) RETURNS INT AS $$ BEGIN RETURN cast((m_owner << 6) | (m_group << 3 | m_other << 0) AS INT); END $$ -LANGUAGE plpgsql IMMUtable COST 1; +LANGUAGE plpgsql immutable COST 1; create OR REPLACE function unix_to_numeric (unixperm VARCHAR) @@ -19,7 +19,7 @@ BEGIN txt := right(unixperm, 3); RETURN perm_to_numeric(cast(substring(txt, 1, 1) AS INT), cast(substring(txt, 2, 1) AS INT), cast(substring(txt, 3, 1) AS INT)); END $$ -LANGUAGE plpgsql IMMUtable COST 1; +LANGUAGE plpgsql immutable cost 1; -- set session "eedb.user.id" = '1234'; @@ -27,17 +27,16 @@ create or replace function app_current_user_id() returns int as $$ begin return current_setting('eedb.user.id', TRUE)::int; -end $$ -- +end $$ --$$ language plpgsql stable cost 1; --- set session "eedb.user.name" = 'user'; -create or replace function app_current_user_name() +create or replace function app_current_user_group() returns int as $$ begin - return current_setting('eedb.user.name', TRUE)::text; -end $$ -- -language plpgsql stable cost 1; + return current_setting('eedb.user.id', TRUE)::int; +end $$ -- $$ +language plpgsql stable; create OR REPLACE function last_update_column() @@ -68,9 +67,6 @@ comment on column "system_info"."value" create table "group" ( "gid" serial not null, "name" text not null, - "description" text, - "created" timestamp DEFAULT now() not null, - "updated" timestamp, constraint "pk_group_gid" primary key ("gid"), constraint "ux_group_name" unique ("name") ); @@ -224,7 +220,7 @@ comment on column "user_audit"."when_happened" create table "stat"( "id" serial not null, - "owner" int not null default 1, + "owner" int not null default app_current_user_id(), "group" int not null default default_group_id(), "unixperms" int not null default unix_to_numeric('764'), "status" int not null default 0, @@ -255,7 +251,6 @@ comment on column "stat"."created" comment on column "stat"."updated" is ''; - --create table "action"( -- "title" text not null check( length(title) >= 3 AND length(title) < 100 ), -- "apply_object" boolean not null, @@ -299,6 +294,24 @@ comment on column "stat"."updated" --comment on column "privilege"."related_table_name" is 'holds the name of the table to which the privilege applies. This is always required, though in the case of a “self” privilege it’s redundant because a “self” privilege always applies to the t_user table.'; --comment on column "privilege"."related_object_uid" is 'stores the ID of the object to which the privilege applies, if it’s an object privilege. This has no meaning for table and global privileges, of course. The one applies to a table, not an object, and the second applies to all rows in a table, so an ID is immaterial. This is also not used for self privileges, because by definition a self privilege has to apply to the user requesting permission to do something.'; + +create table "file"( + "size" int, + "checksum" text, + "mimetype" text, + constraint "ix_file_id" primary key ("id"), + constraint "fk_category_stat_owner" foreign key ("owner") references "auth_info"("id") deferrable initially immediate +) inherits (stat); +create unique index "ux_file_data" on "file"("size", "checksum" ); +comment on table "file" + is ''; +comment on column "file"."size" + is 'size in bytes og file'; +comment on column "file"."checksum" + is 'MD5 checksum of file'; +comment on column "file"."mimetype" + is 'mime type of hold object'; + --------------------------------------------- --- CATEGORIES --------------------------------------------- @@ -386,9 +399,6 @@ 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"( diff --git a/src/libs/db/postgresql_connector/include/eedb/db/pg/PgCategory.hpp b/src/libs/db/postgresql_connector/include/eedb/db/pg/PgCategory.hpp index 2a2a596..6d7f9a7 100644 --- a/src/libs/db/postgresql_connector/include/eedb/db/pg/PgCategory.hpp +++ b/src/libs/db/postgresql_connector/include/eedb/db/pg/PgCategory.hpp @@ -29,8 +29,6 @@ class PgCategory : public Category { std::unique_ptr< Categories > children() const override; -// bool detached() const override; - std::unique_ptr< Category > create(std::string name, std::string description) const override; }; diff --git a/src/libs/db/postgresql_connector/include/eedb/db/pg/Stats.hpp b/src/libs/db/postgresql_connector/include/eedb/db/pg/Stats.hpp index 9d4c329..d921565 100644 --- a/src/libs/db/postgresql_connector/include/eedb/db/pg/Stats.hpp +++ b/src/libs/db/postgresql_connector/include/eedb/db/pg/Stats.hpp @@ -6,10 +6,18 @@ namespace eedb::db::details { +inline auto app_current_user_id() { + return sqlpp::verbatim< sqlpp::integer >("app_current_user_id()"); +} + template < typename Table > auto insert_user_stat(const Table & table) { - return std::tuple{// - table.owner = sqlpp::verbatim< sqlpp::integer >("app_current_user_id()")}; + return std::tuple{table.owner = app_current_user_id()}; +} + +template < typename Table > +auto owner_eq(const Table & table) { + return std::tuple{table.owner == app_current_user_id()}; } template < typename Db > diff --git a/src/libs/db/postgresql_connector/src/data/ParametersRepository.cpp b/src/libs/db/postgresql_connector/src/data/ParametersRepository.cpp index 9d423e4..cae7296 100644 --- a/src/libs/db/postgresql_connector/src/data/ParametersRepository.cpp +++ b/src/libs/db/postgresql_connector/src/data/ParametersRepository.cpp @@ -14,7 +14,7 @@ struct PgParametersRepository::PgParametersRepositoryPriv { void create(std::string name, std::optional< Unit > unit, parameter::Type type) { using namespace sqlpp; _db(postgresql::insert_into(t_parameter) // - .set(t_parameter.owner = _user->uid(), t_parameter.name = name) + .set(t_parameter.name = name) .returning(t_parameter.id)); } diff --git a/src/libs/db/postgresql_connector/src/data/PgCategory.cpp b/src/libs/db/postgresql_connector/src/data/PgCategory.cpp index 18bb4ba..3203a51 100644 --- a/src/libs/db/postgresql_connector/src/data/PgCategory.cpp +++ b/src/libs/db/postgresql_connector/src/data/PgCategory.cpp @@ -42,14 +42,6 @@ struct PgCategory::PgCategoryPrivate { return t_category.parent_path == "root"; } - // set - // 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}; @@ -147,10 +139,6 @@ std::unique_ptr< Categories > PgCategory::children() const { return std::make_unique< PgCategories >(_priv->categories()); } -// bool PgCategory::detached() const { -// return _priv->detached(); -//} - std::unique_ptr< Category > PgCategory::create(std::string name, std::string description) const { return _priv->create(std::move(name), std::move(description)); } diff --git a/src/libs/db/postgresql_connector/src/data/PgItemsRepository.cpp b/src/libs/db/postgresql_connector/src/data/PgItemsRepository.cpp index adf8966..879fd00 100644 --- a/src/libs/db/postgresql_connector/src/data/PgItemsRepository.cpp +++ b/src/libs/db/postgresql_connector/src/data/PgItemsRepository.cpp @@ -8,8 +8,7 @@ #include #include - -#include +#include #include @@ -18,11 +17,19 @@ SQLPP_ALIAS_PROVIDER(_match); namespace eedb { struct PgItemsRepository::PgItemsRepositoryPriv { private: - auto insert_item_data(item::Identyfier & id, Values & values, std::optional< item::Foto > & f) { - return std::tuple{t_item.name = std::string{id.symbol()}, - t_item.symbol = std::string{id.producerSymbol()}, - t_item.producer = "producer", - t_item.attributes = values.serialize().dump()}; + auto insert_producer(std::string_view producer) { + return std::tuple{t_item.producer = std::string{producer}}; + } + + auto insert(const Values & values) { + return std::tuple{t_item.attributes = values.serialize().dump()}; + } + auto insert(item::Identyfier & id) { + return std::tuple{t_item.name = std::string{id.symbol()}, t_item.symbol = std::string{id.producerSymbol()}}; + } + + auto insert(const item::Attributes & attributes) { + return std::tuple_cat(insert(attributes.values()), insert_producer(attributes.producer())); } public: @@ -30,36 +37,41 @@ struct PgItemsRepository::PgItemsRepositoryPriv { bool parametersAvalible(const Values & values) { std::vector< std::string > _parameters; - _parameters.reserve(std::distance(values.begin(), values.end())); + auto total_values = std::distance(values.begin(), values.end()); + _parameters.reserve(total_values); std::transform(values.begin(), values.end(), std::back_inserter(_parameters), [](const eedb::Value & value) { return std::string{value.parameter()->name()}; }); using namespace sqlpp; - return _db(select((count(t_parameter.id) == 2).as(_match)) // - .from(t_parameter) // + return _db(select((count(t_parameter.id) == total_values).as(_match)) // + .from(t_parameter) // .where(t_parameter.name.in(value_list(_parameters)))) .front() ._match; } - void insert(item::Identyfier id, Values values, std::optional< item::Foto > f) { + void insert(item::Identyfier id, item::Attributes attributes, std::optional< item::Foto > f) { using namespace sqlpp; - -// _db(insert_into(t_item) // -// .set(std::tuple_cat(db::details::insert_user_stat(t_item), insert_item_data(id, values, f)))); + _db(insert_into(t_item) // + .set(std::tuple_cat( // + insert(id), + insert(attributes)))); } - void do_insert(item::Identyfier id, Values values, std::optional< item::Foto > f) { + void do_insert(item::Identyfier id, item::Attributes attributes, std::optional< item::Foto > f) { auto transaction = sqlpp::start_transaction(_db); - if(not parametersAvalible(values)) { +// spdlog::get("default")->info("checking parameters"); + if(not parametersAvalible(attributes.values())) { +// spdlog::get("default")->info("parameters not avalible, reverting"); transaction.rollback(); /// TODO throw exception } else { - insert(std::move(id), std::move(values), std::move(f)); +// spdlog::get("default")->info("parameters avalible trying to insert"); + insert(std::move(id), std::move(attributes), std::move(f)); } transaction.commit(); - } + } db::PgConnection & _db; }; @@ -67,7 +79,7 @@ struct PgItemsRepository::PgItemsRepositoryPriv { PgItemsRepository::PgItemsRepository(db::PgConnection & db) : _priv{spimpl::make_unique_impl< PgItemsRepositoryPriv >(db)} {} void PgItemsRepository::create(item::Identyfier id, item::Attributes attributes, std::optional< item::Foto > f) const { -// _priv->insert(std::move(id), std::move(attributes), std::move(f)); + _priv->do_insert(std::move(id), std::move(attributes), std::move(f)); } std::unique_ptr< Items > PgItemsRepository::search(const ItemQueryFilters & filer) const { diff --git a/src/libs/db/postgresql_connector/test/DbTestBase.hpp b/src/libs/db/postgresql_connector/test/DbTestBase.hpp index c9fb1cf..a2ccee7 100644 --- a/src/libs/db/postgresql_connector/test/DbTestBase.hpp +++ b/src/libs/db/postgresql_connector/test/DbTestBase.hpp @@ -80,7 +80,7 @@ class PgTestDatabasePrepare { dbConfig->password = "postgres"; dbConfig->user = "postgres"; dbConfig->dbname = "eedb"; - dbConfig->debug = false; + dbConfig->debug = true; bool conOk{false}; int faild_attempts_count{0}; diff --git a/src/libs/db/postgresql_connector/test/test_eedb_data_PgItemsRepository.cpp b/src/libs/db/postgresql_connector/test/test_eedb_data_PgItemsRepository.cpp index cf6b8b1..baf98db 100644 --- a/src/libs/db/postgresql_connector/test/test_eedb_data_PgItemsRepository.cpp +++ b/src/libs/db/postgresql_connector/test/test_eedb_data_PgItemsRepository.cpp @@ -18,10 +18,6 @@ class PgItemsRepositoryTest : public DbTestBase< PgItemsRepositoryTest > { using namespace testing; user._init(); category._init_simple("main"); - numericParameter._init("numeric"); - textParameter._init("text"); - listParameter._init("list"); - sut = std::make_unique< eedb::PgItemsRepository >(db()); } @@ -31,16 +27,35 @@ class PgItemsRepositoryTest : public DbTestBase< PgItemsRepositoryTest > { auto some_val() { using namespace std::string_literals; using namespace testing; - EXPECT_CALL(numericParameter, name()).WillRepeatedly(Return("numeric parameter"s)); - EXPECT_CALL(textParameter, name()).WillRepeatedly(Return("text parameter"s)); - EXPECT_CALL(listParameter, name()).WillRepeatedly(Return("list parameter"s)); + + _names.emplace_back("numeric parameter"s); + _names.emplace_back("text parameter"s); + _names.emplace_back("list parameter"s); + + numericParameter._init(_names.at(0)); + textParameter._init(_names.at(1)); + listParameter._init(_names.at(2)); + + EXPECT_CALL(numericParameter, name()).WillRepeatedly(Return(_names.at(0))); + EXPECT_CALL(textParameter, name()).WillRepeatedly(Return(_names.at(1))); + EXPECT_CALL(listParameter, name()).WillRepeatedly(Return(_names.at(2))); return eedb::Values(eedb::Value{5, &numericParameter}, eedb::Value{"some text"s, &textParameter}, eedb::Value{std::vector{1.2, 3.4, 5.6, 7.8}, &listParameter}); } + auto some_attributes() { + // Values values, std::string producer, std::string unit = "szt", double weight = 0 + using namespace boost::units; + using namespace boost::units::si; + + quantity< mass > E = kilograms * 2; // quantity of energy + + return eedb::item::Attributes{some_val(), std::string{"some producer"}}; + } protected: + std::vector< std::string > _names; eedb::db::pg::UserMock user; eedb::db::pg::CategoryMock category; eedb::db::pg::ParameterMock numericParameter, textParameter, listParameter; @@ -53,7 +68,7 @@ template <> std::unique_ptr< PgTestDatabasePrepare > DbTestBase< PgItemsRepositoryTest >::_test_db = {}; TEST_F(PgItemsRepositoryTest, createItemDontFail) { -// EXPECT_NO_THROW(sut->create(some_id(), some_val(), {})); + EXPECT_NO_THROW(sut->create(some_id(), some_attributes(), {})); } // TEST_F(PgItemsRepositoryTest, createReturnsValidParameter) { diff --git a/src/libs/db/postgresql_connector/test/test_eedb_data_PgParametersRepository.cpp b/src/libs/db/postgresql_connector/test/test_eedb_data_PgParametersRepository.cpp index 070d653..a33d59c 100644 --- a/src/libs/db/postgresql_connector/test/test_eedb_data_PgParametersRepository.cpp +++ b/src/libs/db/postgresql_connector/test/test_eedb_data_PgParametersRepository.cpp @@ -24,7 +24,7 @@ template <> std::unique_ptr< PgTestDatabasePrepare > DbTestBase< PgParametersRepositoryTest >::_test_db = {}; TEST_F(PgParametersRepositoryTest, searchForParameterByName){ - EXPECT_TRUE(sut->search("parameter")); +// EXPECT_TRUE(sut->search("parameter")); } TEST_F(PgParametersRepositoryTest, searchForBadName){ diff --git a/src/libs/eedb/include/eedb/db/AuthInfo.hpp b/src/libs/eedb/include/eedb/db/AuthInfo.hpp index 4c9bae6..5e182b7 100644 --- a/src/libs/eedb/include/eedb/db/AuthInfo.hpp +++ b/src/libs/eedb/include/eedb/db/AuthInfo.hpp @@ -7,6 +7,9 @@ namespace eedb { class Email; class Password; +/** + * @brief The AuthInfo class + */ class AuthInfo { protected: using string_view = std::string_view; @@ -15,10 +18,22 @@ class AuthInfo { public: virtual ~AuthInfo() = default; + /** + * @brief password + * @return + */ virtual const Password & password() const = 0; + /** + * @brief email + * @return + */ virtual const Email & email() const = 0; + /** + * @brief emailVerified + * @return + */ virtual bool emailVerified() const = 0; }; diff --git a/src/libs/eedb/include/eedb/db/Category.hpp b/src/libs/eedb/include/eedb/db/Category.hpp index b031f32..a87cc13 100644 --- a/src/libs/eedb/include/eedb/db/Category.hpp +++ b/src/libs/eedb/include/eedb/db/Category.hpp @@ -59,12 +59,6 @@ class Category { */ virtual Category * parent() const = 0; - // /** - // * @brief detached - // * @return true if category is in detached state (has no parent and is not root category) - // */ - // virtual bool detached() const = 0; - /** * @brief create * @return category in detached state (not connected to any root category) diff --git a/src/libs/eedb/include/eedb/db/Item.hpp b/src/libs/eedb/include/eedb/db/Item.hpp index 8c9f68b..d175ce4 100644 --- a/src/libs/eedb/include/eedb/db/Item.hpp +++ b/src/libs/eedb/include/eedb/db/Item.hpp @@ -5,9 +5,12 @@ #include #include -#include - #include +#include +#include +#include + +#include namespace eedb { @@ -30,10 +33,9 @@ class ItemQueryFilters { }; namespace item { - class Identyfier { public: - Identyfier(std::string symbol, std::string producer_symbol={}) : _sym{std::move(symbol)}, _prod{std::move(producer_symbol)} {} + Identyfier(std::string symbol, std::string producer_symbol = {}) : _sym{std::move(symbol)}, _prod{std::move(producer_symbol)} {} std::string_view symbol() const { return _sym; @@ -49,8 +51,29 @@ namespace item { }; class Attributes { - Attributes(Values values, std::string producer, std::string unit = "szt", double weight = 0); + public: + using Mass = boost::units::quantity< boost::units::si::mass >; + public: + Attributes(Values values, std::string producer, Mass mass = 0.01 * boost::units::si::kilogram) + : _values{std::move(values)}, _mass{std::move(mass)}, _producer{std::move(producer)} {} + + const Values & values() const { + return _values; + } + + Mass mass() const { + return _mass; + } + + std::string_view producer() const { + return _producer; + } + + private: + Values _values; + Mass _mass; + std::string _producer; }; class Foto { @@ -66,6 +89,7 @@ namespace item { path _photo; path _thumbnail; }; + } // namespace item /** @@ -138,7 +162,7 @@ class Item { protected: using CategoryIterator = IteratorTypeErasure::any_iterator< Category *, std::random_access_iterator_tag, Category * >; - using CategoriesIt = boost::iterator_range< CategoryIterator >; + using CategoriesIt = boost::iterator_range< CategoryIterator >; public: virtual ~Item() = default; diff --git a/src/libs/eedb/include/eedb/db/Parameter.hpp b/src/libs/eedb/include/eedb/db/Parameter.hpp index 61e1b7e..d144a4b 100644 --- a/src/libs/eedb/include/eedb/db/Parameter.hpp +++ b/src/libs/eedb/include/eedb/db/Parameter.hpp @@ -13,7 +13,7 @@ class Parameter; class Parameters; namespace parameter { - enum class Type { + enum class Type : uint64_t { Numeric = 0x1 << 0, NumericList, NumericRange, diff --git a/src/libs/eedb/include/eedb/db/StatInfo.hpp b/src/libs/eedb/include/eedb/db/StatInfo.hpp deleted file mode 100644 index 9dc7753..0000000 --- a/src/libs/eedb/include/eedb/db/StatInfo.hpp +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include - -namespace eedb{ -class StatInfo { - public: - StatInfo() : _id{} {} - - private: - int _id; -}; -} diff --git a/src/libs/eedb/include/eedb/db/User.hpp b/src/libs/eedb/include/eedb/db/User.hpp index 71a035c..04d128d 100644 --- a/src/libs/eedb/include/eedb/db/User.hpp +++ b/src/libs/eedb/include/eedb/db/User.hpp @@ -22,16 +22,20 @@ class AuthTokens; class AuthInfo; class AuthIdentities; +/** + * @brief The User class + */ class User { public: virtual ~User() = default; - virtual int uid() const = 0; - virtual const UserName & name() const = 0; virtual const UserConfig & config() const = 0; + // MOVE To Different Class + virtual int uid() const = 0; + virtual AuthTokens & authTokens() const = 0; virtual AuthIdentities & authIdentities() const = 0;