Skip to content

Commit dd1947e

Browse files
authored
Merge pull request #386 from LASTRADA-Software/improvement/exist_api
[DataMapper] Add Exist api that reuse First() implementation
2 parents 6821644 + 14f338d commit dd1947e

File tree

5 files changed

+46
-0
lines changed

5 files changed

+46
-0
lines changed

src/Lightweight/DataMapper/DataMapper.hpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,26 @@ size_t SqlCoreDataMapperQueryBuilder<Record, Derived, QueryOptions>::Count()
628628
return 0;
629629
}
630630

631+
template <typename Record, typename Derived, DataMapperOptions QueryOptions>
632+
bool SqlCoreDataMapperQueryBuilder<Record, Derived, QueryOptions>::Exist()
633+
{
634+
auto stmt = SqlStatement { _dm.Connection() };
635+
636+
auto const query = _formatter.SelectFirst(this->_query.distinct,
637+
_fields,
638+
RecordTableName<Record>,
639+
this->_query.searchCondition.tableAlias,
640+
this->_query.searchCondition.tableJoins,
641+
this->_query.searchCondition.condition,
642+
this->_query.orderBy,
643+
1);
644+
645+
stmt.ExecuteDirect(query);
646+
if (SqlResultCursor reader = stmt.GetResultCursor(); reader.FetchRow())
647+
return true;
648+
return false;
649+
}
650+
631651
template <typename Record, typename Derived, DataMapperOptions QueryOptions>
632652
std::vector<Record> SqlCoreDataMapperQueryBuilder<Record, Derived, QueryOptions>::All()
633653
{

src/Lightweight/DataMapper/QueryBuilders.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ class [[nodiscard]] SqlCoreDataMapperQueryBuilder: public SqlBasicSelectQueryBui
5252
LIGHTWEIGHT_FORCE_INLINE explicit SqlCoreDataMapperQueryBuilder(DataMapper& dm, std::string fields) noexcept;
5353

5454
public:
55+
/// Executes a SELECT 1 ... query and returns true if a record exists
56+
/// We do not provide db specific syntax to check this but reuse the First() implementation
57+
[[nodiscard]] bool Exist();
58+
5559
/// Executes a SELECT COUNT query and returns the number of records found.
5660
[[nodiscard]] size_t Count();
5761

src/tests/DataMapper/CreateTests.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,19 @@ TEST_CASE_METHOD(SqlTestFixture, "Create table with default values", "[DataMappe
6262
CHECK(actual.int2 == record.int2);
6363
}
6464

65+
TEST_CASE_METHOD(SqlTestFixture, "Check that record exist", "[DataMapper]")
66+
{
67+
auto dm = DataMapper::Create();
68+
dm->CreateTable<RecordWithDefaults>();
69+
70+
auto record = RecordWithDefaults {};
71+
dm->Create(record);
72+
73+
CHECK(
74+
dm->Query<RecordWithDefaults>().Where(FieldNameOf<Member(RecordWithDefaults::id)>, "=", record.id.Value()).Exist());
75+
CHECK(!dm->Query<RecordWithDefaults>().Where(FieldNameOf<Member(RecordWithDefaults::id)>, "=", -1).Exist());
76+
}
77+
6578
struct TestRecord
6679
{
6780
Field<uint64_t, PrimaryKey::AutoAssign> id {};

src/tests/DataMapper/ReadTests.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,15 @@ TEST_CASE_METHOD(SqlTestFixture, "Query", "[DataMapper]")
4747
CHECK(countAll == 4);
4848
}
4949

50+
SECTION("Exist()")
51+
{
52+
auto const existSome = dm->Query<Person>().Where(FieldNameOf<Member(Person::is_active)>, "=", true).Exist();
53+
CHECK(existSome);
54+
55+
auto const notExist = dm->Query<Person>().Where(FieldNameOf<Member(Person::id)>, SqlGuid::Create()).Exist();
56+
CHECK(!notExist);
57+
}
58+
5059
SECTION("All()")
5160
{
5261
auto const records = dm->Query<Person>()

test.db

76 KB
Binary file not shown.

0 commit comments

Comments
 (0)