#include #include #include // std::iota using namespace sqlite_orm; TEST_CASE("Iterate blob") { struct Test { int64_t id; std::vector key; }; struct TestComparator { bool operator()(const Test& lhs, const Test& rhs) const { return lhs.id == rhs.id && lhs.key == rhs.key; } }; auto db = make_storage("", make_table("Test", make_column("key", &Test::key), make_column("id", &Test::id, primary_key()))); db.sync_schema(true); std::vector key(255); iota(key.begin(), key.end(), '\0'); Test v{5, key}; db.replace(v); TestComparator testComparator; for(auto& obj: db.iterate()) { REQUIRE(testComparator(obj, v)); } // test that view_t and iterator_t compile for(const auto& obj: db.iterate()) { REQUIRE(testComparator(obj, v)); } // test that view_t and iterator_t compile { auto keysCount = db.count(where(c(&Test::key) == key)); auto keysCountRows = db.select(count(), where(c(&Test::key) == key)); REQUIRE(keysCountRows.size() == 1); REQUIRE(keysCountRows.front() == 1); REQUIRE(keysCount == keysCountRows.front()); REQUIRE(db.get_all(where(c(&Test::key) == key)).size() == 1); } { int iterationsCount = 0; for(auto& w: db.iterate(where(c(&Test::key) == key))) { REQUIRE(testComparator(w, v)); ++iterationsCount; } REQUIRE(iterationsCount == 1); } } TEST_CASE("Threadsafe") { threadsafe(); } TEST_CASE("Different getters and setters") { struct User { int id; std::string name; int getIdByValConst() const { return this->id; } void setIdByVal(int id_) { this->id = id_; } std::string getNameByVal() { return this->name; } void setNameByConstRef(const std::string& name_) { this->name = name_; } const int& getConstIdByRefConst() const { return this->id; } void setIdByRef(int& id_) { this->id = id_; } const std::string& getConstNameByRefConst() const { return this->name; } void setNameByRef(std::string& name_) { this->name = std::move(name_); } }; auto filename = "different.sqlite"; auto storage0 = make_storage( filename, make_table("users", make_column("id", &User::id, primary_key()), make_column("name", &User::name))); auto storage1 = make_storage(filename, make_table("users", make_column("id", &User::getIdByValConst, &User::setIdByVal, primary_key()), make_column("name", &User::setNameByConstRef, &User::getNameByVal))); auto storage2 = make_storage(filename, make_table("users", make_column("id", &User::getConstIdByRefConst, &User::setIdByRef, primary_key()), make_column("name", &User::getConstNameByRefConst, &User::setNameByRef))); storage0.sync_schema(); storage0.remove_all(); REQUIRE(storage0.count() == 0); REQUIRE(storage1.count() == 0); REQUIRE(storage2.count() == 0); storage0.replace(User{1, "Da buzz"}); REQUIRE(storage0.count() == 1); REQUIRE(storage1.count() == 1); REQUIRE(storage2.count() == 1); { auto ids = storage0.select(&User::id); REQUIRE(ids.size() == 1); REQUIRE(ids.front() == 1); auto ids2 = storage1.select(&User::getIdByValConst); REQUIRE(ids == ids2); auto ids3 = storage1.select(&User::setIdByVal); REQUIRE(ids3 == ids2); auto ids4 = storage2.select(&User::getConstIdByRefConst); REQUIRE(ids4 == ids3); auto ids5 = storage2.select(&User::setIdByRef); REQUIRE(ids5 == ids4); } { auto ids = storage0.select(&User::id, where(is_equal(&User::name, "Da buzz"))); REQUIRE(ids.size() == 1); REQUIRE(ids.front() == 1); auto ids2 = storage1.select(&User::getIdByValConst, where(is_equal(&User::setNameByConstRef, "Da buzz"))); REQUIRE(ids == ids2); auto ids3 = storage1.select(&User::setIdByVal, where(is_equal(&User::getNameByVal, "Da buzz"))); REQUIRE(ids3 == ids2); auto ids4 = storage2.select(&User::getConstIdByRefConst, where(is_equal(&User::getConstNameByRefConst, "Da buzz"))); REQUIRE(ids4 == ids3); auto ids5 = storage2.select(&User::setIdByRef, where(is_equal(&User::setNameByRef, "Da buzz"))); REQUIRE(ids5 == ids4); } { auto ids = storage0.select(columns(&User::id), where(is_equal(&User::name, "Da buzz"))); REQUIRE(ids.size() == 1); REQUIRE(std::get<0>(ids.front()) == 1); auto ids2 = storage1.select(columns(&User::getIdByValConst), where(is_equal(&User::setNameByConstRef, "Da buzz"))); REQUIRE(ids == ids2); auto ids3 = storage1.select(columns(&User::setIdByVal), where(is_equal(&User::getNameByVal, "Da buzz"))); REQUIRE(ids3 == ids2); auto ids4 = storage2.select(columns(&User::getConstIdByRefConst), where(is_equal(&User::getConstNameByRefConst, "Da buzz"))); REQUIRE(ids4 == ids3); auto ids5 = storage2.select(columns(&User::setIdByRef), where(is_equal(&User::setNameByRef, "Da buzz"))); REQUIRE(ids5 == ids4); } { auto avgValue = storage0.avg(&User::id); REQUIRE(avgValue == storage1.avg(&User::getIdByValConst)); REQUIRE(avgValue == storage1.avg(&User::setIdByVal)); REQUIRE(avgValue == storage2.avg(&User::getConstIdByRefConst)); REQUIRE(avgValue == storage2.avg(&User::setIdByRef)); } { auto count = storage0.count(&User::id); REQUIRE(count == storage1.count(&User::getIdByValConst)); REQUIRE(count == storage1.count(&User::setIdByVal)); REQUIRE(count == storage2.count(&User::getConstIdByRefConst)); REQUIRE(count == storage2.count(&User::setIdByRef)); } { auto groupConcat = storage0.group_concat(&User::id); REQUIRE(groupConcat == storage1.group_concat(&User::getIdByValConst)); REQUIRE(groupConcat == storage1.group_concat(&User::setIdByVal)); REQUIRE(groupConcat == storage2.group_concat(&User::getConstIdByRefConst)); REQUIRE(groupConcat == storage2.group_concat(&User::setIdByRef)); } { auto arg = "ototo"; auto groupConcat = storage0.group_concat(&User::id, arg); REQUIRE(groupConcat == storage1.group_concat(&User::getIdByValConst, arg)); REQUIRE(groupConcat == storage1.group_concat(&User::setIdByVal, arg)); REQUIRE(groupConcat == storage2.group_concat(&User::getConstIdByRefConst, arg)); REQUIRE(groupConcat == storage2.group_concat(&User::setIdByRef, arg)); } { auto max = storage0.max(&User::id); REQUIRE(max); REQUIRE(*max == *storage1.max(&User::getIdByValConst)); REQUIRE(*max == *storage1.max(&User::setIdByVal)); REQUIRE(*max == *storage2.max(&User::getConstIdByRefConst)); REQUIRE(*max == *storage2.max(&User::setIdByRef)); } { auto min = storage0.min(&User::id); REQUIRE(min); REQUIRE(*min == *storage1.min(&User::getIdByValConst)); REQUIRE(*min == *storage1.min(&User::setIdByVal)); REQUIRE(*min == *storage2.min(&User::getConstIdByRefConst)); REQUIRE(*min == *storage2.min(&User::setIdByRef)); } { auto sum = storage0.sum(&User::id); REQUIRE(sum); REQUIRE(*sum == *storage1.sum(&User::getIdByValConst)); REQUIRE(*sum == *storage1.sum(&User::setIdByVal)); REQUIRE(*sum == *storage2.sum(&User::getConstIdByRefConst)); REQUIRE(*sum == *storage2.sum(&User::setIdByRef)); } { auto total = storage0.total(&User::id); REQUIRE(total == storage1.total(&User::getIdByValConst)); REQUIRE(total == storage1.total(&User::setIdByVal)); REQUIRE(total == storage2.total(&User::getConstIdByRefConst)); REQUIRE(total == storage2.total(&User::setIdByRef)); } } #ifdef SQLITE_ORM_OPTIONAL_SUPPORTED TEST_CASE("Dump") { struct User { int id = 0; std::optional carYear; // will be empty if user takes the bus. }; auto storage = make_storage( {}, make_table("users", make_column("id", &User::id, primary_key()), make_column("car_year", &User::carYear))); storage.sync_schema(); auto userId_1 = storage.insert(User{0, {}}); auto userId_2 = storage.insert(User{0, 2006}); std::ignore = userId_2; REQUIRE(storage.count(where(is_not_null(&User::carYear))) == 1); auto rows = storage.select(&User::carYear, where(is_equal(&User::id, userId_1))); REQUIRE(rows.size() == 1); REQUIRE(!rows.front().has_value()); auto allUsers = storage.get_all(); REQUIRE(allUsers.size() == 2); const std::string dumpUser1 = storage.dump(allUsers[0]); REQUIRE(dumpUser1 == std::string{"{ id : '1', car_year : 'null' }"}); const std::string dumpUser2 = storage.dump(allUsers[1]); REQUIRE(dumpUser2 == std::string{"{ id : '2', car_year : '2006' }"}); } #endif // SQLITE_ORM_OPTIONAL_SUPPORTED TEST_CASE("issue730") { struct Table { int64_t id; std::string a; std::string b; std::string c; }; auto storage = make_storage({}, make_table("table", make_column("id", &Table::id), make_column("a", &Table::a), make_column("b", &Table::b), make_column("c", &Table::c), sqlite_orm::unique(&Table::a, &Table::b, &Table::c))); storage.sync_schema(); auto rows = storage.select(asterisk()); using Rows = decltype(rows); using ExpectedRows = std::vector>; STATIC_REQUIRE(std::is_same::value); } TEST_CASE("issue822") { class A { public: A() = default; A(const uint8_t& address, const uint8_t& type, const uint8_t& idx, std::shared_ptr value) : address(address), type(type), idx(idx), value(std::move(value)){}; const uint8_t& getAddress() const { return this->address; } void setAddress(const uint8_t& address) { this->address = address; } const uint8_t& getType() const { return this->type; } void setType(const uint8_t& type) { this->type = type; } const uint8_t& getIndex() const { return this->idx; } void setIndex(const uint8_t& index) { this->idx = index; } std::shared_ptr getValue() const { return this->value; } void setValue(std::shared_ptr value) { this->value = std::move(value); } private: uint8_t address; uint8_t type; uint8_t idx; std::shared_ptr value; }; auto storage = make_storage("", make_table("A", make_column("address", &A::getAddress, &A::setAddress), make_column("type", &A::getType, &A::setType), make_column("idx", &A::getIndex, &A::setIndex), make_column("value", &A::getValue, &A::setValue), primary_key(&A::getAddress, &A::getType, &A::getIndex))); storage.sync_schema(); storage.replace(A(1, 1, 0, std::make_shared(55.5))); auto records = storage.get_all(where(c(&A::getAddress) == 1 and c(&A::getType) == 1 and c(&A::getIndex) == 0)); if(records.size() != 0) { A a = records[0]; a.setValue(std::make_shared(10)); storage.update(a); records = storage.get_all(where(c(&A::getAddress) == 1 and c(&A::getType) == 1 and c(&A::getIndex) == 0)); REQUIRE(records.size() == 1); REQUIRE(*records[0].getValue() == 10); } }