modyfi items
This commit is contained in:
parent
4b64a9a86a
commit
6438abef65
@ -48,7 +48,7 @@ mkdir date-build; cd date-build
|
||||
${CMAKE_COMMAND} -G${CMAKE_GENERATOR} ../date\
|
||||
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}\
|
||||
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} \
|
||||
-DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}\
|
||||
-DCMAKE_INSTALL_PREFIX="${CMAKE_INSTALL_PREFIX}"\
|
||||
-DTZ_CXX_STANDARD=14
|
||||
${CMAKE_COMMAND} --build . --target install
|
||||
cd ../
|
||||
@ -57,7 +57,7 @@ mkdir sqlpp11-build; cd sqlpp11-build
|
||||
${CMAKE_COMMAND} -G${CMAKE_GENERATOR} ../sqlpp11\
|
||||
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}\
|
||||
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}\
|
||||
-DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}\
|
||||
-DCMAKE_INSTALL_PREFIX="${CMAKE_INSTALL_PREFIX}"\
|
||||
-DENABLE_TESTS=FALSE
|
||||
${CMAKE_COMMAND} --build . --target install
|
||||
cd ../
|
||||
@ -66,8 +66,9 @@ mkdir sqlpp11-connector-postgresql-build; cd sqlpp11-connector-postgresql-build
|
||||
${CMAKE_COMMAND} -G${CMAKE_GENERATOR} ../sqlpp11-connector-postgresql\
|
||||
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}\
|
||||
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}\
|
||||
-DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}\
|
||||
-DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH}\
|
||||
-DCMAKE_INSTALL_PREFIX="${CMAKE_INSTALL_PREFIX}"\
|
||||
-DCMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE}"\
|
||||
-DCMAKE_PREFIX_PATH="${CMAKE_PREFIX_PATH}"\
|
||||
-DENABLE_TESTS=FALSE
|
||||
${CMAKE_COMMAND} --build . --target install
|
||||
cd ../
|
||||
@ -76,10 +77,10 @@ mkdir wt-build; cd wt-build
|
||||
${CMAKE_COMMAND} -G${CMAKE_GENERATOR} ../wt\
|
||||
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}\
|
||||
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}\
|
||||
-DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}\
|
||||
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}\
|
||||
-DCMAKE_INSTALL_RPATH=${CMAKE_RPATH}\
|
||||
-DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH}\
|
||||
-DCMAKE_INSTALL_PREFIX="${CMAKE_INSTALL_PREFIX}"\
|
||||
-DCMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE}"\
|
||||
-DCMAKE_INSTALL_RPATH="${CMAKE_RPATH}"\
|
||||
-DCMAKE_PREFIX_PATH="${CMAKE_PREFIX_PATH}"\
|
||||
-DBoost_NO_BOOST_CMAKE=FALSE\
|
||||
-DBoost_NO_SYSTEM_PATHS=TRUE\
|
||||
-DBUILD_EXAMPLES=OFF\
|
||||
@ -104,8 +105,9 @@ mkdir ChaiScript-build; cd ChaiScript-build
|
||||
${CMAKE_COMMAND} -G${CMAKE_GENERATOR} ../ChaiScript\
|
||||
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}\
|
||||
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}\
|
||||
-DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}\
|
||||
-DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH}\
|
||||
-DCMAKE_INSTALL_PREFIX="${CMAKE_INSTALL_PREFIX}"\
|
||||
-DCMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE}"\
|
||||
-DCMAKE_PREFIX_PATH="${CMAKE_PREFIX_PATH}"\
|
||||
-DMULTITHREAD_SUPPORT_ENABLED=TRUE\
|
||||
-DDYNLOAD_ENABLED=FALSE\
|
||||
-DBUILD_MODULES=TRUE\
|
||||
|
||||
@ -12,6 +12,8 @@ namespace eedb {
|
||||
class PgItem : public Item {
|
||||
// Item interface
|
||||
public:
|
||||
PgItem(db::PgConnection & db, item::Attributes attributes);
|
||||
|
||||
PgItem(db::PgConnection & db, int64_t uid, item::Attributes attributes);
|
||||
|
||||
std::string_view displayName() const override;
|
||||
@ -24,6 +26,6 @@ class PgItem : public Item {
|
||||
|
||||
private:
|
||||
struct ItemPriv;
|
||||
spimpl::impl_ptr< ItemPriv > _priv;
|
||||
spimpl::unique_impl_ptr< ItemPriv > _priv;
|
||||
};
|
||||
} // namespace eedb
|
||||
|
||||
@ -18,7 +18,7 @@ class PgItemsRepository : public ItemsRepository {
|
||||
public:
|
||||
PgItemsRepository(db::PgConnection & db);
|
||||
|
||||
void create(item::Identyfier id, item::Attributes attributes, std::optional< item::Foto >) const override;
|
||||
std::unique_ptr< Item > create(item::Identyfier id, item::Attributes attributes, std::optional< item::Foto >) const override;
|
||||
|
||||
std::unique_ptr< Items > search(const ItemQueryFilters & filer) const override;
|
||||
|
||||
|
||||
@ -1,13 +1,58 @@
|
||||
#include <eedb/db/pg/PgItem.hpp>
|
||||
|
||||
#include <eedb/Value.hpp>
|
||||
#include <eedb/db/Category.hpp>
|
||||
|
||||
#include <eedb/db/pg/connection.hpp>
|
||||
#include <eedb/db/pg/model/all.hpp>
|
||||
|
||||
#include <sqlpp11/sqlpp11.h>
|
||||
|
||||
using namespace sqlpp;
|
||||
|
||||
namespace eedb {
|
||||
|
||||
struct PgItem::ItemPriv {};
|
||||
struct PgItem::ItemPriv {
|
||||
ItemPriv(db::PgConnection & db, int64_t uid, item::Attributes attributes) : _db{db}, _uid{uid}, _attributes{std::move(attributes)} {}
|
||||
|
||||
PgItem::PgItem(db::PgConnection & db, int64_t uid, item::Attributes attributes) : _priv{spimpl::make_impl< ItemPriv >()} {}
|
||||
bool attachToCategory(const Category * category) {
|
||||
assert(category);
|
||||
auto x = sqlpp::cte(sqlpp::alias::x)
|
||||
.as(select(t_category.parent_id) //
|
||||
.from(t_category) //
|
||||
.where(t_category.parent_path == std::string{category->path()})
|
||||
.limit(1u));
|
||||
|
||||
_db(insert_into(t_category_items) //
|
||||
.set(t_category_items.category_id = 1, t_category_items.item_id = _uid));
|
||||
return true;
|
||||
}
|
||||
|
||||
db::PgConnection & _db;
|
||||
int64_t _uid;
|
||||
item::Attributes _attributes;
|
||||
};
|
||||
|
||||
PgItem::PgItem(db::PgConnection & db, item::Attributes attributes)
|
||||
: _priv{spimpl::make_unique_impl< ItemPriv >(db, 0, std::move(attributes))} {}
|
||||
|
||||
PgItem::PgItem(db::PgConnection & db, int64_t uid, item::Attributes attributes)
|
||||
: _priv{spimpl::make_unique_impl< ItemPriv >(db, uid, std::move(attributes))} {}
|
||||
|
||||
std::string_view PgItem::displayName() const {
|
||||
return std::string_view{"item"};
|
||||
}
|
||||
|
||||
Values PgItem::values() const {
|
||||
return {};
|
||||
}
|
||||
|
||||
Item::CategoriesIt PgItem::attachedToCategories() const {
|
||||
return {};
|
||||
}
|
||||
|
||||
bool PgItem::attach(const Category * category) {
|
||||
return _priv->attachToCategory(category);
|
||||
}
|
||||
|
||||
} // namespace eedb
|
||||
|
||||
@ -3,7 +3,9 @@
|
||||
#include <eedb/Value.hpp>
|
||||
#include <eedb/db/Parameter.hpp>
|
||||
#include <eedb/db/User.hpp>
|
||||
#include <eedb/db/pg/ParametersRepository.hpp>
|
||||
#include <eedb/db/pg/PgCategory.hpp>
|
||||
#include <eedb/db/pg/PgItem.hpp>
|
||||
#include <eedb/db/pg/connection.hpp>
|
||||
#include <eedb/db/pg/model/all.hpp>
|
||||
|
||||
@ -14,6 +16,8 @@
|
||||
|
||||
#include <eedb/db/pg/Stats.hpp>
|
||||
|
||||
#include <boost/iterator/transform_iterator.hpp>
|
||||
|
||||
SQLPP_ALIAS_PROVIDER(_match);
|
||||
|
||||
namespace eedb {
|
||||
@ -34,12 +38,20 @@ struct PgItemsRepository::PgItemsRepositoryPriv {
|
||||
return std::tuple_cat(insert(attributes.values()), insert_producer(attributes.producer()));
|
||||
}
|
||||
|
||||
void insert(item::Identyfier id, item::Attributes attributes, std::optional< item::Foto > f) {
|
||||
auto insert(item::Identyfier id, item::Attributes attributes, std::optional< item::Foto > f) {
|
||||
using namespace sqlpp;
|
||||
_db(insert_into(t_item) //
|
||||
.set(std::tuple_cat( //
|
||||
insert(id),
|
||||
insert(attributes))));
|
||||
try {
|
||||
auto uid = _db(sqlpp::postgresql::insert_into(t_item) //
|
||||
.set(std::tuple_cat( //
|
||||
insert(id),
|
||||
insert(attributes))) //
|
||||
.returning(t_item.id))
|
||||
.front()
|
||||
.id;
|
||||
return std::make_unique< PgItem >(_db, uid, std::move(attributes));
|
||||
} catch(const sqlpp::postgresql::unique_violation & e) {
|
||||
throw item::UniqueSymbolValidation(e.what());
|
||||
}
|
||||
}
|
||||
|
||||
bool parametersAvalible(const Values & values) {
|
||||
@ -59,30 +71,60 @@ struct PgItemsRepository::PgItemsRepositoryPriv {
|
||||
}
|
||||
|
||||
public:
|
||||
PgItemsRepositoryPriv(db::PgConnection & db) : _db{db} {}
|
||||
PgItemsRepositoryPriv(db::PgConnection & db) : _db{db}, _parameters{_db} {}
|
||||
|
||||
void do_insert(item::Identyfier id, item::Attributes attributes, std::optional< item::Foto > f) {
|
||||
auto do_insert(item::Identyfier id, item::Attributes attributes, std::optional< item::Foto > f) {
|
||||
auto transaction = sqlpp::start_transaction(_db);
|
||||
if(not parametersAvalible(attributes.values())) {
|
||||
transaction.rollback();
|
||||
/// TODO throw exception
|
||||
} else {
|
||||
insert(std::move(id), std::move(attributes), std::move(f));
|
||||
auto new_item = insert(std::move(id), std::move(attributes), std::move(f));
|
||||
transaction.commit();
|
||||
return new_item;
|
||||
}
|
||||
transaction.commit();
|
||||
}
|
||||
|
||||
auto _cte_categoryIdByPath(const ItemQueryFilters & filer) const {
|
||||
return sqlpp::cte(sqlpp::alias::x)
|
||||
.as(select(t_category.parent_id) //
|
||||
.from(t_category) //
|
||||
.where(t_category.parent_path == std::string{filer.category() ? filer.category()->path() : std::string_view{""}})
|
||||
.limit(1u));
|
||||
}
|
||||
|
||||
auto _titem() const {
|
||||
return t_item.inner_join(t_category_items).on(t_item.id == t_category_items.item_id);
|
||||
}
|
||||
|
||||
auto parameterByName(const std::string & name) const {
|
||||
// return eedb::Parameter{};
|
||||
}
|
||||
|
||||
auto readAttribute(nlohmann::json & attribute) const {
|
||||
// auto value = eedb::Value{0, parameterByName()};
|
||||
}
|
||||
|
||||
template < typename Row >
|
||||
auto readAttributes(Row & row) const {
|
||||
const auto & attributes_raw = row.attributes.value();
|
||||
const auto & producer = row.producer;
|
||||
|
||||
auto attributes = nlohmann::json::parse({attributes_raw.begin(), attributes_raw.end()});
|
||||
auto values = std::vector< eedb::Value >{};
|
||||
for(auto & attribute : attributes) {
|
||||
readAttribute(attribute);
|
||||
}
|
||||
return eedb::item::Attributes{std::move(values), producer};
|
||||
}
|
||||
|
||||
auto search(const ItemQueryFilters & filer) {
|
||||
using namespace sqlpp;
|
||||
|
||||
auto x = sqlpp::cte(sqlpp::alias::x)
|
||||
.as(select(t_category.parent_id) //
|
||||
.from(t_category) //
|
||||
.where(t_category.parent_path == std::string{filer.category() ? filer.category()->path() : std::string_view{""}})
|
||||
.limit(1u));
|
||||
auto x = _cte_categoryIdByPath(filer);
|
||||
|
||||
auto s = dynamic_select(_db.native(), all_of(t_item)) //
|
||||
.dynamic_from(t_item.inner_join(t_category_items).on(t_item.id == t_category_items.item_id)) //
|
||||
auto s = dynamic_select(_db.native(), all_of(t_item)) //
|
||||
.dynamic_from(_titem()) //
|
||||
.dynamic_where()
|
||||
.limit(100u);
|
||||
|
||||
@ -91,24 +133,34 @@ struct PgItemsRepository::PgItemsRepositoryPriv {
|
||||
}
|
||||
|
||||
auto rows = _db(with(x)(s));
|
||||
|
||||
_items.clear();
|
||||
for(const auto & row : rows) {
|
||||
std::cout << row.name << " ";
|
||||
std::cout << row.attributes << "\n";
|
||||
const auto & uid = row.id;
|
||||
_items.emplace_back(std::make_unique< eedb::PgItem >(_db, uid, readAttributes(row)));
|
||||
}
|
||||
|
||||
auto transform = [](
|
||||
std::unique_ptr< eedb::PgItem > & pgitem) { return static_cast< std::unique_ptr< eedb::Item > >(pgitem.get()); };
|
||||
auto begin = boost::make_transform_iterator(_items.begin(), transform);
|
||||
auto end = boost::make_transform_iterator(_items.end(), transform);
|
||||
|
||||
return std::make_unique< eedb::Items >(begin, end);
|
||||
}
|
||||
|
||||
std::vector< std::unique_ptr< eedb::PgItem > > _items;
|
||||
eedb::PgParametersRepository _parameters;
|
||||
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->do_insert(std::move(id), std::move(attributes), std::move(f));
|
||||
std::unique_ptr< Item > PgItemsRepository::create(item::Identyfier id, item::Attributes attributes, std::optional< item::Foto > f) const {
|
||||
return _priv->do_insert(std::move(id), std::move(attributes), std::move(f));
|
||||
}
|
||||
|
||||
std::unique_ptr< Items > PgItemsRepository::search(const ItemQueryFilters & filer) const {
|
||||
_priv->search(filer);
|
||||
return {};
|
||||
return _priv->search(filer);
|
||||
}
|
||||
|
||||
Parameters PgItemsRepository::listParameters(const Category *) const {
|
||||
|
||||
@ -19,6 +19,10 @@ class PgItemsRepositoryTest : public DbTestBase< PgItemsRepositoryTest > {
|
||||
user._init();
|
||||
category._init_simple("main");
|
||||
|
||||
numericParameter._init("numeric parameter");
|
||||
textParameter._init("text parameter");
|
||||
listParameter._init("list parameter");
|
||||
|
||||
sut = std::make_unique< eedb::PgItemsRepository >(db());
|
||||
}
|
||||
|
||||
@ -29,10 +33,6 @@ class PgItemsRepositoryTest : public DbTestBase< PgItemsRepositoryTest > {
|
||||
using namespace std::string_literals;
|
||||
using namespace testing;
|
||||
|
||||
numericParameter._init("numeric parameter");
|
||||
textParameter._init("text parameter");
|
||||
listParameter._init("list parameter");
|
||||
|
||||
EXPECT_CALL(numericParameter, name()).WillRepeatedly(Return(std::string_view{"numeric parameter"}));
|
||||
EXPECT_CALL(textParameter, name()).WillRepeatedly(Return(std::string_view{"text parameter"}));
|
||||
EXPECT_CALL(listParameter, name()).WillRepeatedly(Return(std::string_view{"list parameter"}));
|
||||
@ -61,6 +61,11 @@ TEST_F(PgItemsRepositoryTest, createItemDontFail) {
|
||||
EXPECT_NO_THROW(sut->create(some_id(), some_attributes(), {}));
|
||||
}
|
||||
|
||||
TEST_F(PgItemsRepositoryTest, createTwiceThrowsException){
|
||||
EXPECT_NO_THROW(sut->create(some_id(), some_attributes(), {}));
|
||||
EXPECT_THROW(sut->create(some_id(), some_attributes(), {}), eedb::item::UniqueSymbolValidation);
|
||||
}
|
||||
|
||||
TEST_F(PgItemsRepositoryTest, createReturnsValidParameter) {
|
||||
EXPECT_NO_THROW(sut->create(some_id(), some_attributes(), {}));
|
||||
category._expect_call_path();
|
||||
|
||||
@ -46,7 +46,7 @@ class ItemQueryFilters {
|
||||
};
|
||||
|
||||
namespace item {
|
||||
using Iterator = IteratorTypeErasure::any_iterator< Item *, std::forward_iterator_tag, Item * >;
|
||||
using Iterator = IteratorTypeErasure::any_iterator< std::unique_ptr<Item> , std::forward_iterator_tag, std::unique_ptr<Item> >;
|
||||
using IteratorRange = boost::iterator_range< Iterator >;
|
||||
|
||||
class Identyfier {
|
||||
@ -106,6 +106,16 @@ namespace item {
|
||||
path _thumbnail;
|
||||
};
|
||||
|
||||
class UniqueSymbolValidation : public std::exception {
|
||||
public:
|
||||
UniqueSymbolValidation(std::string what) : _what{std::move(what)} {}
|
||||
const char * what() const noexcept override {
|
||||
return _what.data();
|
||||
}
|
||||
|
||||
private:
|
||||
std::string _what;
|
||||
};
|
||||
} // namespace item
|
||||
|
||||
/**
|
||||
@ -120,7 +130,7 @@ class ItemsRepository {
|
||||
* @param id
|
||||
* @param values
|
||||
*/
|
||||
virtual void create(item::Identyfier id, item::Attributes attributes, std::optional< item::Foto >) const = 0;
|
||||
virtual std::unique_ptr< Item > create(item::Identyfier id, item::Attributes attributes, std::optional< item::Foto >) const = 0;
|
||||
|
||||
/**
|
||||
* @brief search
|
||||
@ -147,7 +157,6 @@ class Items : public item::IteratorRange {
|
||||
using _base::_base;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The Item class
|
||||
*/
|
||||
|
||||
Loading…
Reference in New Issue
Block a user