Last active
October 26, 2017 23:44
-
-
Save multiplemonomials/3b82de8bb114e85441b93f720c278d34 to your computer and use it in GitHub Desktop.
Wrapper around a Soci (SQL library for C++) statement that allows you to bind variables at execution time, and not before then. Helps you improve performance by making statements class variables.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Created by Jamie on 5/12/2017. | |
// | |
#ifndef SOCI_LAZYSTATEMENT_H | |
#define SOCI_LAZYSTATEMENT_H | |
#include <soci/core/soci.h> | |
#include <soci/core/session.h> | |
/* | |
* With soci, sql statements have one HUGE problem: | |
* they must be bound to a variable at CONSTRUCTION time, and at EXECUTE time | |
* they suck in the value of that variable. So, even though the value isn't needed until later, | |
* it has to be available early on. So much for declaring statements as static and | |
* using them inside for loops. | |
* Bluh. | |
* | |
* Lazy statements allow you to just provide the type of the variable at | |
* construction time, and you apply the value at execute time. | |
* | |
* I've created 0-3 agument implementations, if you need more arguments, you can just copy-pase the lower | |
* argument versions and add another argument. | |
*/ | |
namespace soci | |
{ | |
template <typename ...Dummy> class lazy_statement; // base case, never instantiated! | |
// one argument version | |
template<typename param1_t> | |
class lazy_statement<param1_t> | |
{ | |
param1_t param1; | |
statement _statement; | |
public: | |
lazy_statement(soci::session & session, std::string sql) | |
: param1(), | |
_statement((session.prepare << sql, use(param1))) | |
{ | |
} | |
bool execute(param1_t value) | |
{ | |
param1 = value; | |
return _statement.execute(true); | |
} | |
}; | |
// two argument version | |
template<typename param1_t, typename param2_t> | |
class lazy_statement<param1_t, param2_t> | |
{ | |
param1_t param1; | |
param2_t param2; | |
statement _statement; | |
public: | |
lazy_statement(soci::session & session, std::string sql) | |
: param1(), | |
param2(), | |
_statement((session.prepare << sql, use(param1), use(param2))) | |
{ | |
} | |
bool execute(param1_t value1, param2_t value2) | |
{ | |
param1 = value1; | |
param2 = value2; | |
return _statement.execute(true); | |
} | |
}; | |
// three argument version | |
template<typename param1_t, typename param2_t, typename param3_t> | |
class lazy_statement<param1_t, param2_t, param3_t> | |
{ | |
param1_t param1; | |
param2_t param2; | |
param3_t param3; | |
statement _statement; | |
public: | |
lazy_statement(soci::session & session, std::string sql) | |
: param1(), | |
param2(), | |
param3(), | |
_statement((session.prepare << sql, use(param1), use(param2), use(param3))) | |
{ | |
} | |
bool execute(param1_t value1, param2_t value2, param3_t value3) | |
{ | |
param1 = value1; | |
param2 = value2; | |
param3 = value3; | |
return _statement.execute(true); | |
} | |
}; | |
} | |
#endif //SOCI_LAZYSTATEMENT_H |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void Foo::addToDatabase(Bar& bar) | |
{ | |
// this statement is only constructed once, which improves performance greatly vs constructing it each loop | |
// Or, you could put it in the class definition | |
soci::lazy_statement<std::string> barAddStatement(database, "INSERT INTO Baz(bar, barString) Values(:barid, :barString)"); | |
for (std::string & barString) | |
{ | |
barAddStatement.execute(bar.getId(), barString); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment