From 070ce923574dcc57435cb3fb2dfe86b6a38cd249 Mon Sep 17 00:00:00 2001 From: MDBijman Date: Tue, 24 Jan 2017 12:15:26 +0100 Subject: Initial code commit with organized dependencies --- Simulator/include/database/QueryExecuter.h | 155 +++++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 Simulator/include/database/QueryExecuter.h (limited to 'Simulator/include/database/QueryExecuter.h') diff --git a/Simulator/include/database/QueryExecuter.h b/Simulator/include/database/QueryExecuter.h new file mode 100644 index 00000000..d66f9e85 --- /dev/null +++ b/Simulator/include/database/QueryExecuter.h @@ -0,0 +1,155 @@ +#pragma once +#include "Query.h" +#include "QueryResult.h" + +#include +#include +#include +#include + +namespace Database +{ + template + class QueryExecuter + { + public: + /* + Creates a prepared statement and initializes the query. + */ + explicit QueryExecuter(sqlite3* db) : database(db) {} + + /* + Sets the query this executer will execute. + */ + QueryExecuter& setQuery(Query query) + { + this->query = std::make_unique>(query); + this->query->prepare(database); + return *this; + } + + /* + Binds the given name-value pairs to the statement. + Recursive case. + */ + template + QueryExecuter& bindParams(BindType locationValuePair, int depth = 1) + { + query->template bind(locationValuePair, depth); + return *this; + } + + /* + Binds the given name-value pairs to the statement. + Recursive case. + */ + template + QueryExecuter& bindParams(BindType locationValuePair, BindTypes... locationValuePairs, int depth = 1) + { + query->template bind(locationValuePair, depth); + bindParams(locationValuePairs..., depth + 1); + return *this; + } + + /* + Executes the query and returns a tuple with an entry for each type. Use this to recieve only the first result. + Multiple calls, or calls when there are no rows in the db, can lead to exceptions. + This is functionally equivalent to stepping and then calling getResult + */ + QueryResult executeOnce() + { + query->step(); + return QueryResult(getResult()); + } + + /* + Steps the query. + */ + bool step() + { + return query->step(); + } + + /* + Returns the result. + */ + QueryResult result() + { + return QueryResult(getResult()); + } + + /* + Executes the query and returns a vector of tuples for each result. + */ + std::vector> execute(int limit = 0) + { + std::vector> result; + + // Return code + bool more; + + int limiter = 0; + + do + { + // Execution of the statement + more = query->step(); + + if (!more || (limiter >= limit && limit > 0)) + break; + + limiter++; + std::tuple row = getResult(); + result.emplace_back(row); + + } while (more); + + return result; + } + + /* + Resets the sqlite3 query object. + */ + QueryExecuter& reset() + { + query->reset(); + return *this; + } + + private: + /* + Returns the results after executing the query. + Base case. + */ + template + std::tuple getResult(int depth = 0) + { + return std::tuple(query->template getResult(depth)); + } + + /* + Returns the results after executing the query. + Recursive Case. + */ + template + std::tuple getResult(int depth = 0) + { + std::tuple first = std::tuple(query->template getResult(depth)); + std::tuple rest = getResult(depth + 1); + return std::tuple_cat(first, rest); + } + + /* + Returns an empty tuple for when there are no return values. + */ + template + std::tuple<> getResult(int depth = 0) const + { + return std::tuple<>(); + } + + std::unique_ptr> query; + sqlite3* database; + }; +} + -- cgit v1.2.3