move start to removie uid method from user
This commit is contained in:
parent
e440049c4b
commit
d2229ca498
@ -22,6 +22,24 @@ END $$
|
||||
LANGUAGE plpgsql IMMUtable COST 1;
|
||||
|
||||
|
||||
-- set session "eedb.user.id" = '1234';
|
||||
create or replace function app_current_user_id()
|
||||
returns int as $$
|
||||
begin
|
||||
return current_setting('eedb.user.id', TRUE)::int;
|
||||
end $$ --
|
||||
language plpgsql stable cost 1;
|
||||
|
||||
|
||||
-- set session "eedb.user.name" = 'user';
|
||||
create or replace function app_current_user_name()
|
||||
returns int as $$
|
||||
begin
|
||||
return current_setting('eedb.user.name', TRUE)::text;
|
||||
end $$ --
|
||||
language plpgsql stable cost 1;
|
||||
|
||||
|
||||
create OR REPLACE function last_update_column()
|
||||
RETURNS trigger AS $$
|
||||
BEGIN
|
||||
|
||||
@ -16,9 +16,9 @@ namespace eedb {
|
||||
class PgItemsRepository : public ItemsRepository {
|
||||
// ItemsRepository interface
|
||||
public:
|
||||
PgItemsRepository(db::PgConnection & db, User * owner);
|
||||
PgItemsRepository(db::PgConnection & db);
|
||||
|
||||
void create(item::Identyfier id, Values values, std::optional< item::Foto >) const override;
|
||||
void create(item::Identyfier id, item::Attributes attributes, std::optional< item::Foto >) const override;
|
||||
|
||||
std::unique_ptr< Items > search(const ItemQueryFilters & filer) const override;
|
||||
|
||||
|
||||
@ -1,7 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
namespace eedb::details {
|
||||
#include <eedb/db/User.hpp>
|
||||
|
||||
template < typename Row, typename Data >
|
||||
auto readStats(Data & data, Row & row) {}
|
||||
} // namespace eedb::details
|
||||
#include <sqlpp11/sqlpp11.h>
|
||||
|
||||
namespace eedb::db::details {
|
||||
|
||||
template < typename Table >
|
||||
auto insert_user_stat(const Table & table) {
|
||||
return std::tuple{//
|
||||
table.owner = sqlpp::verbatim< sqlpp::integer >("app_current_user_id()")};
|
||||
}
|
||||
|
||||
template < typename Db >
|
||||
auto session_set_user_id(Db & db, int64_t id) {
|
||||
db.execute(R"(set session "eedb.user.id" = ')" + std::to_string(id) + R"(';)");
|
||||
}
|
||||
|
||||
} // namespace eedb::db::details
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <stack>
|
||||
|
||||
#include <sqlpp11/postgresql/postgresql.h>
|
||||
#include <sqlpp11/transaction.h>
|
||||
@ -21,28 +22,18 @@ class PgConnection {
|
||||
return _conn.execute(query);
|
||||
}
|
||||
|
||||
void start_transaction(sqlpp::isolation_level level = sqlpp::isolation_level::undefined) {
|
||||
_in_transaction_count++;
|
||||
_conn.start_transaction(level);
|
||||
}
|
||||
void start_transaction(sqlpp::isolation_level level = sqlpp::isolation_level::undefined);
|
||||
|
||||
void commit_transaction() {
|
||||
_in_transaction_count--;
|
||||
_conn.commit_transaction();
|
||||
}
|
||||
void commit_transaction();
|
||||
|
||||
void report_rollback_failure(const std::string & message) noexcept {
|
||||
_conn.report_rollback_failure(message);
|
||||
}
|
||||
void report_rollback_failure(const std::string & message) noexcept;
|
||||
|
||||
void rollback_transaction(bool report) {
|
||||
_in_transaction_count--;
|
||||
_conn.rollback_transaction(report);
|
||||
}
|
||||
void rollback_transaction(bool report);
|
||||
|
||||
private:
|
||||
sqlpp::postgresql::connection _conn;
|
||||
int _in_transaction_count{0};
|
||||
std::stack<std::string> _savepoints;
|
||||
};
|
||||
|
||||
} // namespace eedb::db
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
#include <eedb/db/pg/model/auth_token.h>
|
||||
#include <eedb/db/pg/model/category.h>
|
||||
#include <eedb/db/pg/model/group.h>
|
||||
#include <eedb/db/pg/model/item.h>
|
||||
#include <eedb/db/pg/model/parameter.h>
|
||||
#include <eedb/db/pg/model/stat.h>
|
||||
#include <eedb/db/pg/model/system_info.h>
|
||||
@ -16,6 +17,7 @@ static constexpr eedb::db::auth_info t_auth_info;
|
||||
static constexpr eedb::db::auth_token t_auth_token;
|
||||
static constexpr eedb::db::category t_category;
|
||||
static constexpr eedb::db::group t_group;
|
||||
static constexpr eedb::db::item t_item;
|
||||
static constexpr eedb::db::parameter t_parameter;
|
||||
static constexpr eedb::db::stat t_stat;
|
||||
static constexpr eedb::db::system_info t_system_info;
|
||||
|
||||
@ -6,84 +6,84 @@
|
||||
|
||||
namespace eedb::db {
|
||||
|
||||
namespace auth_identity_ {
|
||||
namespace auth_identity_ {
|
||||
|
||||
struct Id {
|
||||
struct _alias_t {
|
||||
static constexpr const char _literal[] = R"("id")";
|
||||
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
|
||||
template<typename T>
|
||||
struct _member_t {
|
||||
T id;
|
||||
T &operator()() { return id; }
|
||||
const T &operator()() const { return id; }
|
||||
};
|
||||
};
|
||||
struct Id {
|
||||
struct _alias_t {
|
||||
static constexpr const char _literal[] = R"("id")";
|
||||
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
|
||||
template<typename T>
|
||||
struct _member_t {
|
||||
T id;
|
||||
T &operator()() { return id; }
|
||||
const T &operator()() const { return id; }
|
||||
};
|
||||
};
|
||||
|
||||
using _traits = ::sqlpp::make_traits<::sqlpp::integer, sqlpp::tag::must_not_insert, sqlpp::tag::must_not_update>;
|
||||
};
|
||||
using _traits = ::sqlpp::make_traits<::sqlpp::integer, sqlpp::tag::must_not_insert, sqlpp::tag::must_not_update>;
|
||||
};
|
||||
|
||||
struct Auth_info_id {
|
||||
struct _alias_t {
|
||||
static constexpr const char _literal[] = R"("auth_info_id")";
|
||||
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
|
||||
template<typename T>
|
||||
struct _member_t {
|
||||
T auth_info_id;
|
||||
T &operator()() { return auth_info_id; }
|
||||
const T &operator()() const { return auth_info_id; }
|
||||
};
|
||||
};
|
||||
struct Auth_info_id {
|
||||
struct _alias_t {
|
||||
static constexpr const char _literal[] = R"("auth_info_id")";
|
||||
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
|
||||
template<typename T>
|
||||
struct _member_t {
|
||||
T auth_info_id;
|
||||
T &operator()() { return auth_info_id; }
|
||||
const T &operator()() const { return auth_info_id; }
|
||||
};
|
||||
};
|
||||
|
||||
using _traits = ::sqlpp::make_traits<::sqlpp::bigint, sqlpp::tag::can_be_null>;
|
||||
};
|
||||
using _traits = ::sqlpp::make_traits<::sqlpp::bigint, sqlpp::tag::can_be_null>;
|
||||
};
|
||||
|
||||
struct Provider {
|
||||
struct _alias_t {
|
||||
static constexpr const char _literal[] = R"("provider")";
|
||||
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
|
||||
template<typename T>
|
||||
struct _member_t {
|
||||
T provider;
|
||||
T &operator()() { return provider; }
|
||||
const T &operator()() const { return provider; }
|
||||
};
|
||||
};
|
||||
struct Provider {
|
||||
struct _alias_t {
|
||||
static constexpr const char _literal[] = R"("provider")";
|
||||
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
|
||||
template<typename T>
|
||||
struct _member_t {
|
||||
T provider;
|
||||
T &operator()() { return provider; }
|
||||
const T &operator()() const { return provider; }
|
||||
};
|
||||
};
|
||||
|
||||
using _traits = ::sqlpp::make_traits<::sqlpp::varchar, sqlpp::tag::require_insert>;
|
||||
};
|
||||
using _traits = ::sqlpp::make_traits<::sqlpp::varchar, sqlpp::tag::require_insert>;
|
||||
};
|
||||
|
||||
struct Identity {
|
||||
struct _alias_t {
|
||||
static constexpr const char _literal[] = R"("identity")";
|
||||
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
|
||||
template<typename T>
|
||||
struct _member_t {
|
||||
T identity;
|
||||
T &operator()() { return identity; }
|
||||
const T &operator()() const { return identity; }
|
||||
};
|
||||
};
|
||||
struct Identity {
|
||||
struct _alias_t {
|
||||
static constexpr const char _literal[] = R"("identity")";
|
||||
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
|
||||
template<typename T>
|
||||
struct _member_t {
|
||||
T identity;
|
||||
T &operator()() { return identity; }
|
||||
const T &operator()() const { return identity; }
|
||||
};
|
||||
};
|
||||
|
||||
using _traits = ::sqlpp::make_traits<::sqlpp::varchar, sqlpp::tag::require_insert>;
|
||||
};
|
||||
}
|
||||
using _traits = ::sqlpp::make_traits<::sqlpp::varchar, sqlpp::tag::require_insert>;
|
||||
};
|
||||
}
|
||||
|
||||
struct auth_identity : sqlpp::table_t<auth_identity,
|
||||
auth_identity_::Id,
|
||||
auth_identity_::Auth_info_id,
|
||||
auth_identity_::Provider,
|
||||
auth_identity_::Identity> {
|
||||
using _value_type = sqlpp::no_value_t;
|
||||
struct _alias_t {
|
||||
static constexpr const char _literal[] = R"("auth_identity")";
|
||||
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
|
||||
template<typename T>
|
||||
struct _member_t {
|
||||
T auth_identity;
|
||||
T &operator()() { return auth_identity; }
|
||||
const T &operator()() const { return auth_identity; }
|
||||
};
|
||||
};
|
||||
};
|
||||
struct auth_identity : sqlpp::table_t<auth_identity,
|
||||
auth_identity_::Id,
|
||||
auth_identity_::Auth_info_id,
|
||||
auth_identity_::Provider,
|
||||
auth_identity_::Identity> {
|
||||
using _value_type = sqlpp::no_value_t;
|
||||
struct _alias_t {
|
||||
static constexpr const char _literal[] = R"("auth_identity")";
|
||||
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
|
||||
template<typename T>
|
||||
struct _member_t {
|
||||
T auth_identity;
|
||||
T &operator()() { return auth_identity; }
|
||||
const T &operator()() const { return auth_identity; }
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
#ifndef EEDB::DB_ITEM_H
|
||||
#define EEDB::DB_ITEM_H
|
||||
#pragma once
|
||||
|
||||
#include <sqlpp11/table.h>
|
||||
#include <sqlpp11/char_sequence.h>
|
||||
@ -249,4 +248,3 @@ namespace eedb::db {
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -10,8 +10,6 @@
|
||||
#include <sqlpp11/postgresql/insert.h>
|
||||
#include <sqlpp11/sqlpp11.h>
|
||||
|
||||
#include <eedb/db/User.hpp>
|
||||
|
||||
namespace eedb::db::pg {
|
||||
|
||||
class CategoryMock : public ::eedb::CategoryMock {
|
||||
@ -29,7 +27,7 @@ class CategoryMock : public ::eedb::CategoryMock {
|
||||
}
|
||||
|
||||
public:
|
||||
CategoryMock(PgConnection & db, User *u) : _db{db}, _u{u} {}
|
||||
CategoryMock(PgConnection & db) : _db{db} {}
|
||||
|
||||
void _init_simple(std::string name) {
|
||||
_root_guard();
|
||||
@ -41,7 +39,7 @@ class CategoryMock : public ::eedb::CategoryMock {
|
||||
_root_id = _db(sqlpp::postgresql::insert_into(t_category) //
|
||||
.set(t_category.name = "root", //
|
||||
t_category.parent_id = sqlpp::null,
|
||||
t_category.owner = _u->uid())
|
||||
t_category.owner = sqlpp::verbatim< sqlpp::integer >(" app_current_user_id() ") )
|
||||
.returning(t_category.id))
|
||||
.front()
|
||||
.id;
|
||||
@ -49,8 +47,6 @@ class CategoryMock : public ::eedb::CategoryMock {
|
||||
|
||||
private:
|
||||
PgConnection & _db;
|
||||
User * _u{nullptr};
|
||||
|
||||
int64_t _root_id{0};
|
||||
};
|
||||
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
#include <sqlpp11/sqlpp11.h>
|
||||
|
||||
#include <eedb/db/AuthIdentityConst.hpp>
|
||||
#include <eedb/db/pg/Stats.hpp>
|
||||
|
||||
namespace eedb::db::pg {
|
||||
|
||||
@ -32,6 +33,8 @@ class UserMock : public ::eedb::UserMock {
|
||||
.returning(t_auth_info.id))
|
||||
.front()
|
||||
.id;
|
||||
|
||||
details::session_set_user_id(_db, _id);
|
||||
}
|
||||
|
||||
void _createIdentity(const ::eedb::AuthIdentityConst & id) {
|
||||
|
||||
@ -1,7 +1,35 @@
|
||||
#include "eedb/db/pg/config.hpp"
|
||||
#include "eedb/db/pg/connection.hpp"
|
||||
#include "eedb/db/pg/config.hpp"
|
||||
|
||||
namespace eedb::db {
|
||||
|
||||
PgConnection::PgConnection(std::shared_ptr< eedb::db::PgConfig > config) : _conn(config) {}
|
||||
|
||||
void PgConnection::start_transaction(sqlpp::isolation_level level) {
|
||||
using namespace std::string_literals;
|
||||
_in_transaction_count++;
|
||||
if(_in_transaction_count == 1) // start transaction only at first level
|
||||
_conn.start_transaction(level);
|
||||
else {
|
||||
auto savepointName = "_savepoint_" + std::to_string(_savepoints.size() + 1);
|
||||
_conn.savepoint(savepointName);
|
||||
_savepoints.push(std::move(savepointName));
|
||||
}
|
||||
}
|
||||
|
||||
void PgConnection::commit_transaction() {
|
||||
_in_transaction_count--;
|
||||
if(!_in_transaction_count)
|
||||
_conn.commit_transaction();
|
||||
}
|
||||
|
||||
void PgConnection::report_rollback_failure(const std::string & message) noexcept {
|
||||
_conn.report_rollback_failure(message);
|
||||
}
|
||||
|
||||
void PgConnection::rollback_transaction(bool report) {
|
||||
_in_transaction_count--;
|
||||
if(!_in_transaction_count)
|
||||
_conn.rollback_transaction(report);
|
||||
}
|
||||
} // namespace eedb::db
|
||||
|
||||
@ -1,21 +1,73 @@
|
||||
#include <eedb/db/pg/PgItemsRepository.hpp>
|
||||
|
||||
#include <eedb/db/Parameter.hpp>
|
||||
#include <eedb/Value.hpp>
|
||||
#include <eedb/db/Parameter.hpp>
|
||||
#include <eedb/db/User.hpp>
|
||||
#include <eedb/db/pg/connection.hpp>
|
||||
#include <eedb/db/pg/model/all.hpp>
|
||||
|
||||
#include <sqlpp11/sqlpp11.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <sqlpp11/sqlpp11.h>
|
||||
|
||||
#include <sqlpp11/in.h>
|
||||
|
||||
#include <eedb/db/pg/Stats.hpp>
|
||||
|
||||
SQLPP_ALIAS_PROVIDER(_match);
|
||||
|
||||
namespace eedb {
|
||||
struct PgItemsRepository::PgItemsRepositoryPriv {};
|
||||
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()};
|
||||
}
|
||||
|
||||
PgItemsRepository::PgItemsRepository(db::PgConnection & db, User * owner) : _priv{spimpl::make_unique_impl< PgItemsRepositoryPriv >()} {}
|
||||
public:
|
||||
PgItemsRepositoryPriv(db::PgConnection & db) : _db{db} {}
|
||||
|
||||
void PgItemsRepository::create(item::Identyfier id, Values values, std::optional< item::Foto >) const {
|
||||
auto attributes = nlohmann::json();
|
||||
bool parametersAvalible(const Values & values) {
|
||||
std::vector< std::string > _parameters;
|
||||
_parameters.reserve(std::distance(values.begin(), values.end()));
|
||||
std::transform(values.begin(), values.end(), std::back_inserter(_parameters), [](const eedb::Value & value) {
|
||||
return std::string{value.parameter()->name()};
|
||||
});
|
||||
|
||||
values.serialize(attributes);
|
||||
using namespace sqlpp;
|
||||
return _db(select((count(t_parameter.id) == 2).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) {
|
||||
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))));
|
||||
}
|
||||
|
||||
void do_insert(item::Identyfier id, Values values, std::optional< item::Foto > f) {
|
||||
auto transaction = sqlpp::start_transaction(_db);
|
||||
if(not parametersAvalible(values)) {
|
||||
transaction.rollback();
|
||||
/// TODO throw exception
|
||||
} else {
|
||||
insert(std::move(id), std::move(values), std::move(f));
|
||||
}
|
||||
transaction.commit();
|
||||
}
|
||||
|
||||
db::PgConnection & _db;
|
||||
};
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
std::unique_ptr< Items > PgItemsRepository::search(const ItemQueryFilters & filer) const {
|
||||
|
||||
@ -44,13 +44,17 @@ class DockerRunner {
|
||||
system(search_path("docker"), "start", _name);
|
||||
} else if(status == Status::Missing) {
|
||||
system(search_path("docker"),
|
||||
"run --detach",
|
||||
"run",
|
||||
"--detach",
|
||||
"--name",
|
||||
_name,
|
||||
"-p 5432:5432",
|
||||
"-e POSTGRES_PASSWORD=postgres",
|
||||
"-e POSTGRES_DB=eedb",
|
||||
"postgres:9.5-alpine");
|
||||
"-p",
|
||||
"5432:5432",
|
||||
"-e",
|
||||
"POSTGRES_PASSWORD=postgres",
|
||||
"-e",
|
||||
"POSTGRES_DB=eedb",
|
||||
"postgres:9.6-alpine");
|
||||
}
|
||||
}
|
||||
|
||||
@ -111,10 +115,8 @@ class DbTestBase : public testing::Test {
|
||||
|
||||
static void SetUpTestCase() {
|
||||
_test_db = std::make_unique< PgTestDatabasePrepare >();
|
||||
// _test_db->db().native()->start_transaction();
|
||||
_test_db->db().execute("SET synchronous_commit=off;");
|
||||
eedb::db::exec_file(_test_db->db(), "/home/bwieczor/src/eedb/sql/schema.sql");
|
||||
// _test_db->db().native()->commit_transaction();
|
||||
}
|
||||
|
||||
static void TearDownTestCase() {
|
||||
|
||||
@ -14,16 +14,15 @@
|
||||
|
||||
class PgItemsRepositoryTest : public DbTestBase< PgItemsRepositoryTest > {
|
||||
public:
|
||||
PgItemsRepositoryTest() : user{db()}, category{db(), &user}, numericParameter{db()}, textParameter{db()}, listParameter{db()} {
|
||||
PgItemsRepositoryTest() : user{db()}, category{db()}, numericParameter{db()}, textParameter{db()}, listParameter{db()} {
|
||||
using namespace testing;
|
||||
user._init(); // create fake user
|
||||
user._expect_call_uid();
|
||||
category._init_simple("main");
|
||||
numericParameter._init("numeric");
|
||||
textParameter._init("text");
|
||||
listParameter._init("list");
|
||||
|
||||
sut = std::make_unique< eedb::PgItemsRepository >(db(), &user);
|
||||
sut = std::make_unique< eedb::PgItemsRepository >(db());
|
||||
}
|
||||
|
||||
auto some_id() {
|
||||
@ -54,7 +53,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_val(), {}));
|
||||
}
|
||||
|
||||
// TEST_F(PgItemsRepositoryTest, createReturnsValidParameter) {
|
||||
|
||||
@ -153,6 +153,12 @@ class Values {
|
||||
return true;
|
||||
}
|
||||
|
||||
nlohmann::json serialize() const {
|
||||
nlohmann::json json;
|
||||
serialize(json);
|
||||
return json;
|
||||
}
|
||||
|
||||
private:
|
||||
template < typename V, typename... VList >
|
||||
void emplace_(V && v, VList &&... vs) {
|
||||
|
||||
@ -48,6 +48,11 @@ namespace item {
|
||||
std::string _prod;
|
||||
};
|
||||
|
||||
class Attributes {
|
||||
Attributes(Values values, std::string producer, std::string unit = "szt", double weight = 0);
|
||||
|
||||
};
|
||||
|
||||
class Foto {
|
||||
using path = std::experimental::filesystem::path;
|
||||
|
||||
@ -75,7 +80,7 @@ class ItemsRepository {
|
||||
* @param id
|
||||
* @param values
|
||||
*/
|
||||
virtual void create(item::Identyfier id, Values values, std::optional< item::Foto >) const = 0;
|
||||
virtual void create(item::Identyfier id, item::Attributes attributes, std::optional< item::Foto >) const = 0;
|
||||
|
||||
/**
|
||||
* @brief search
|
||||
|
||||
Loading…
Reference in New Issue
Block a user