some fixes

This commit is contained in:
Bartosz Wieczorek 2018-03-14 12:43:19 +01:00
parent c8dcb41f1b
commit c34f7c5a07
15 changed files with 145 additions and 90 deletions

View File

@ -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 its 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 its 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"(

View File

@ -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;
};

View File

@ -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 >

View File

@ -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));
}

View File

@ -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));
}

View File

@ -8,8 +8,7 @@
#include <nlohmann/json.hpp>
#include <sqlpp11/sqlpp11.h>
#include <sqlpp11/in.h>
#include <spdlog/spdlog.h>
#include <eedb/db/pg/Stats.hpp>
@ -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,33 +37,38 @@ 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)) //
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();
}
@ -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 {

View File

@ -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};

View File

@ -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) {

View File

@ -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){

View File

@ -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;
};

View File

@ -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)

View File

@ -5,9 +5,12 @@
#include <optional>
#include <string_view>
#include <boost/range/iterator_range.hpp>
#include <any_iterator/any_iterator.hpp>
#include <boost/range/iterator_range.hpp>
#include <boost/units/systems/si/mass.hpp>
#include <boost/units/quantity.hpp>
#include <eedb/Value.hpp>
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
/**

View File

@ -13,7 +13,7 @@ class Parameter;
class Parameters;
namespace parameter {
enum class Type {
enum class Type : uint64_t {
Numeric = 0x1 << 0,
NumericList,
NumericRange,

View File

@ -1,13 +0,0 @@
#pragma once
#include <string>
namespace eedb{
class StatInfo {
public:
StatInfo() : _id{} {}
private:
int _id;
};
}

View File

@ -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;