Skip to content

Commit 6401fb2

Browse files
committed
delete with custom predicate
1 parent d636fb6 commit 6401fb2

File tree

7 files changed

+52
-13
lines changed

7 files changed

+52
-13
lines changed

include/database.h

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,8 @@ namespace sqlite_reflection {
147147
void Delete(const T& model) const {
148148
const auto type_id = typeid(T).name();
149149
const auto& record = GetRecord(type_id);
150-
Delete(model.id, record);
150+
const auto equal_id_predicate = Equal(&T::id, model.id);
151+
Delete(record, &equal_id_predicate);
151152
}
152153

153154
/// Deletes a given record from the database, which matches a given id.
@@ -156,8 +157,18 @@ namespace sqlite_reflection {
156157
void Delete(int64_t id) const {
157158
const auto type_id = typeid(T).name();
158159
const auto& record = GetRecord(type_id);
159-
Delete(id, record);
160+
const auto equal_id_predicate = Equal(&T::id, id);
161+
Delete(record, &equal_id_predicate);
160162
}
163+
164+
/// Deletes multiple records of a given type from the database, which match a given predicate.
165+
/// This corresponds to an DELETE query in the SQL syntax, with an additional WHERE clause
166+
template <typename T>
167+
void Delete(const QueryPredicateBase* predicate) const {
168+
const auto type_id = typeid(T).name();
169+
const auto& record = GetRecord(type_id);
170+
Delete(record, predicate);
171+
}
161172

162173
private:
163174
explicit Database(const char* path);
@@ -189,7 +200,7 @@ namespace sqlite_reflection {
189200
void Update(void* p, const Reflection& record) const;
190201

191202
/// Deletes a single record from the database
192-
void Delete(int64_t id, const Reflection& record) const;
203+
void Delete(const Reflection& record, const QueryPredicateBase* predicate) const;
193204

194205
static Database* instance_;
195206
sqlite3* db_;

include/queries.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,11 +95,11 @@ namespace sqlite_reflection {
9595
{
9696
public:
9797
~DeleteQuery() override = default;
98-
explicit DeleteQuery(sqlite3* db, const Reflection& record, int64_t id);
98+
explicit DeleteQuery(sqlite3* db, const Reflection& record, const QueryPredicateBase* predicate);
9999

100100
protected:
101101
std::string PrepareSql() const override;
102-
int64_t id_;
102+
const QueryPredicateBase* predicate_;
103103
};
104104

105105
/// A query to insert a given record to the database, by supplying a given type-erased struct instance

include/reflection.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,6 @@
3535
#include <stddef.h>
3636
#endif
3737

38-
// todo: delete with custom predicate
39-
4038
// todo: BETWEEN / IN / NOT IN predicate
4139
// todo: raw sql queries
4240
// todo: save with automatic id

src/database.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,8 @@ namespace sqlite_reflection {
9191
query.Execute();
9292
}
9393

94-
void Database::Delete(int64_t id, const Reflection& record) const {
95-
DeleteQuery query(db_, record, id);
94+
void Database::Delete(const Reflection& record, const QueryPredicateBase* predicate) const {
95+
DeleteQuery query(db_, record, predicate);
9696
query.Execute();
9797
}
9898
}

src/queries.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -146,12 +146,12 @@ std::string CreateTableQuery::CustomizedColumnName(size_t index) const {
146146
: name;
147147
}
148148

149-
DeleteQuery::DeleteQuery(sqlite3* db, const Reflection& record, int64_t id)
150-
: ExecutionQuery(db, record), id_(id) {}
149+
DeleteQuery::DeleteQuery(sqlite3* db, const Reflection& record, const QueryPredicateBase* predicate)
150+
: ExecutionQuery(db, record), predicate_(predicate) {}
151151

152152
std::string DeleteQuery::PrepareSql() const {
153153
std::string sql("DELETE FROM ");
154-
sql += record_.name + " WHERE id = " + StringUtilities::FromInt(id_) + ";";
154+
sql += record_.name + " WHERE " + predicate_->Evaluate() + ";";
155155
return sql;
156156
}
157157

src/query_predicates.cc

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ std::string QueryPredicate::GetStringForValue(void* v, SqliteStorageClass storag
6060
auto value = *(int64_t*)(v);
6161
return StringUtilities::FromInt(value);
6262
}
63+
case SqliteStorageClass::kBool:
64+
{
65+
auto value = *(bool*)(v);
66+
return StringUtilities::FromInt(value ? 1 : 0);
67+
}
6368
case SqliteStorageClass::kReal:
6469
{
6570
auto value = *(double*)(v);
@@ -115,4 +120,4 @@ OrPredicate::OrPredicate(const QueryPredicateBase& left, const QueryPredicateBas
115120

116121
QueryPredicateBase* OrPredicate::Clone() const {
117122
return new OrPredicate(*left_.get(), *right_.get());
118-
}
123+
}

tests/database_test.cc

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,31 @@ TEST_F(DatabaseTest, DeleteWithId) {
205205
EXPECT_EQ(20, saved_persons[i].age);
206206
}
207207

208+
TEST_F(DatabaseTest, DeleteWithPredicate) {
209+
const auto& db = Database::Instance();
210+
211+
std::vector<Person> persons;
212+
213+
persons.push_back({3, L"παναγιώτης", L"ανδριανόπουλος", 28, true});
214+
persons.push_back({5, L"peter", L"meier", 32, false});
215+
persons.push_back({13, L"mary", L"poppins", 20, true});
216+
217+
db.Save(persons);
218+
219+
const auto age_match_predicate = SmallerThan(&Person::age, 30)
220+
.And(Equal(&Person::isVaccinated, true));
221+
222+
db.Delete<Person>(&age_match_predicate);
223+
const auto fetched_persons = db.FetchAll<Person>();
224+
EXPECT_EQ(1, fetched_persons.size());
225+
226+
EXPECT_EQ(5, fetched_persons[0].id);
227+
EXPECT_EQ(L"peter", fetched_persons[0].first_name);
228+
EXPECT_EQ(L"meier", fetched_persons[0].last_name);
229+
EXPECT_EQ(32, fetched_persons[0].age);
230+
EXPECT_EQ(false, fetched_persons[0].isVaccinated);
231+
}
232+
208233
TEST_F(DatabaseTest, SingleFetch) {
209234
const auto& db = Database::Instance();
210235

0 commit comments

Comments
 (0)