modyfi items

This commit is contained in:
Bartosz Wieczorek 2018-03-20 12:19:03 +01:00
parent 4b64a9a86a
commit 6438abef65
8 changed files with 158 additions and 43 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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