Skip to content

Commit ff5626d

Browse files
committed
raw sql queries
1 parent 6401fb2 commit ff5626d

File tree

6 files changed

+46
-2
lines changed

6 files changed

+46
-2
lines changed

include/database.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,9 @@ namespace sqlite_reflection {
169169
const auto& record = GetRecord(type_id);
170170
Delete(record, predicate);
171171
}
172+
173+
/// Executes a raw SQL query. A trailing semicolon is added if needed
174+
void Sql(const std::string& raw_sql_query) const;
172175

173176
private:
174177
explicit Database(const char* path);

include/queries.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,18 @@ namespace sqlite_reflection {
7575
std::vector<std::string> GetValues(void* p) const;
7676
};
7777

78+
/// A query for which direct SQL prompts are used
79+
class REFLECTION_EXPORT SqlQuery : public ExecutionQuery
80+
{
81+
public:
82+
~SqlQuery() override = default;
83+
explicit SqlQuery(sqlite3* db, const std::string& sql);
84+
85+
protected:
86+
std::string PrepareSql() const override;
87+
const std::string& sql_;
88+
};
89+
7890
/// A query for creating a table for a given reflectable struct. When the database
7991
/// is initialized, a table for every registered reflectable struct is created
8092
/// This maps to CREATE TABLE IF NOT EXISTS in SQL

include/reflection.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,7 @@
3636
#endif
3737

3838
// todo: BETWEEN / IN / NOT IN predicate
39-
// todo: raw sql queries
4039
// todo: save with automatic id
41-
4240
// todo: nullable types
4341
// todo: relations
4442

src/database.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,4 +95,9 @@ namespace sqlite_reflection {
9595
DeleteQuery query(db_, record, predicate);
9696
query.Execute();
9797
}
98+
99+
void Database::Sql(const std::string& raw_sql_query) const {
100+
SqlQuery sql(db_, raw_sql_query);
101+
sql.Execute();
102+
}
98103
}

src/queries.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,15 @@ std::vector<std::string> ExecutionQuery::GetValues(void* p) const {
127127
return values;
128128
}
129129

130+
SqlQuery::SqlQuery(sqlite3* db, const std::string& sql)
131+
: ExecutionQuery(db, Reflection()), sql_(sql) {}
132+
133+
std::string SqlQuery::PrepareSql() const {
134+
return sql_.length() > 0 && sql_[sql_.length() - 1] != ';'
135+
? sql_ + ";"
136+
: sql_;
137+
}
138+
130139
CreateTableQuery::CreateTableQuery(sqlite3* db, const Reflection& record)
131140
: ExecutionQuery(db, record) { }
132141

tests/database_test.cc

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,3 +414,20 @@ TEST_F(DatabaseTest, ReadMaxId) {
414414
const auto max_id_pet = db.GetMaxId<Pet>();
415415
EXPECT_EQ(0, max_id_pet);
416416
}
417+
418+
TEST_F(DatabaseTest, RawSqlQueryForPersistedRecord) {
419+
const auto& db = Database::Instance();
420+
421+
std::vector<Person> persons;
422+
423+
persons.push_back({52, L"johnie", L"appleseed", 28});
424+
persons.push_back({156, L"mary", L"poppins", 20});
425+
426+
db.Save(persons);
427+
db.Sql("DELETE FROM Person WHERE length(first_name) <= 4");
428+
429+
const auto fetched_persons = db.FetchAll<Person>();
430+
EXPECT_EQ(1, fetched_persons.size());
431+
EXPECT_EQ(52, fetched_persons[0].id);
432+
EXPECT_EQ(L"johnie", fetched_persons[0].first_name);
433+
}

0 commit comments

Comments
 (0)