summaryrefslogtreecommitdiff
path: root/Simulator/include/database/Query.h
diff options
context:
space:
mode:
authorMDBijman <matthijs@bijman.org>2017-01-24 12:15:26 +0100
committerMDBijman <matthijs@bijman.org>2017-01-24 12:15:26 +0100
commit070ce923574dcc57435cb3fb2dfe86b6a38cd249 (patch)
treeffd69a842ac4ad22aaf7161f923b9f0b47c7147a /Simulator/include/database/Query.h
Initial code commit with organized dependencies
Diffstat (limited to 'Simulator/include/database/Query.h')
-rw-r--r--Simulator/include/database/Query.h124
1 files changed, 124 insertions, 0 deletions
diff --git a/Simulator/include/database/Query.h b/Simulator/include/database/Query.h
new file mode 100644
index 00000000..46ce0ee2
--- /dev/null
+++ b/Simulator/include/database/Query.h
@@ -0,0 +1,124 @@
+#pragma once
+#include <assert.h>
+#include <sqlite3.h>
+
+namespace Database
+{
+
+ namespace Specializations
+ {
+ template<typename ReturnType>
+ ReturnType getResult(int location, sqlite3_stmt* statement);
+
+ template<>
+ inline int getResult<int>(int location, sqlite3_stmt* statement)
+ {
+ return sqlite3_column_int(statement, location);
+ }
+
+ template<>
+ inline std::string getResult<std::string>(int location, sqlite3_stmt* statement)
+ {
+ return std::string(reinterpret_cast<const char*>(sqlite3_column_text(statement, location)));
+ }
+
+ template<typename ValueType>
+ void bind(ValueType value, int location, sqlite3_stmt* statement);
+
+ template<>
+ inline void bind<int>(int value, int location, sqlite3_stmt* statement)
+ {
+ int rc = sqlite3_bind_int(statement, location, value);
+ assert(rc == SQLITE_OK);
+ }
+
+ template<>
+ inline void bind<float>(float value, int location, sqlite3_stmt* statement)
+ {
+ int rc = sqlite3_bind_double(statement, location, static_cast<double>(value));
+ assert(rc == SQLITE_OK);
+ }
+ }
+
+
+
+ template<typename ...ReturnTypes>
+ class Query
+ {
+ public:
+ explicit Query(std::string query) : statement(nullptr), content(query)
+ {}
+
+ /*
+ Calls sqlite3_finalize on the statement.
+ */
+ ~Query()
+ {
+ int rc = sqlite3_finalize(statement);
+ assert(rc == SQLITE_OK);
+ }
+
+ /*
+ Calls sqlite3_prepare_v2 to prepare this query.
+ */
+ void prepare(sqlite3* db)
+ {
+ // Preparation of the statement.
+ int rc = sqlite3_prepare_v2(db, content.c_str(), static_cast<int>(content.size()), &statement, NULL);
+ assert(rc == SQLITE_OK);
+ }
+
+ /*
+ Steps the execution of this query once. Returns true if the return code is SQLITE_ROW.
+ */
+ bool step() const
+ {
+ // Execution of the statement
+ int rc = sqlite3_step(statement);
+ if(rc == SQLITE_ROW)
+ return true;
+ if(rc == SQLITE_DONE)
+ return false;
+
+ assert(!"The return code of step was not SQLITE_ROW (100) or SQLITE_DONE (101)!");
+ return false;
+ }
+
+ /*
+ Resets this query back to its initial state.
+ */
+ void reset() const
+ {
+ sqlite3_reset(statement);
+ }
+
+ /*
+ A template for implementing the binding of values to parameters in the sqlite statement.
+ */
+ template<typename ValueType>
+ void bind(ValueType value, int location)
+ {
+ Specializations::bind<ValueType>(value, location, statement);
+ }
+
+ /**
+ * \brief Returns the result of ReturnType at the given location in the query result row.
+ * \tparam ReturnType The type of the entry in the row.
+ * \param location The index of the entry in the row.
+ * \return The result of the query at the given location.
+ */
+ template<typename ReturnType>
+ ReturnType getResult(int location)
+ {
+ return Specializations::getResult<ReturnType>(location, statement);
+ }
+
+ private:
+ // The sqlite3 statement that corresponds to this query.
+ sqlite3_stmt* statement;
+ // The sql string that will be executed.
+ std::string content;
+
+ };
+
+}