summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2017-01-04 02:00:04 +0000
committerDan Goodliffe <dan@randomdan.homeip.net>2017-01-04 02:00:04 +0000
commit74fcbf827294bac907fffe57382e34359893f20f (patch)
treea20e7f29872515ca3cbba3f66c656aa119aeb1c9
parentTidy clearing of PGresults (diff)
downloadlibdbpp-postgresql-74fcbf827294bac907fffe57382e34359893f20f.tar.bz2
libdbpp-postgresql-74fcbf827294bac907fffe57382e34359893f20f.tar.xz
libdbpp-postgresql-74fcbf827294bac907fffe57382e34359893f20f.zip
C++ify the SQL preparer and skip it if no variables are being bound
-rw-r--r--libpqpp/pq-command.cpp20
-rw-r--r--libpqpp/pq-command.h2
-rw-r--r--libpqpp/pq-cursorselectcommand.cpp11
-rw-r--r--libpqpp/pq-prepared.cpp5
4 files changed, 22 insertions, 16 deletions
diff --git a/libpqpp/pq-command.cpp b/libpqpp/pq-command.cpp
index 84eaa43..af203cc 100644
--- a/libpqpp/pq-command.cpp
+++ b/libpqpp/pq-command.cpp
@@ -25,22 +25,26 @@ PQ::Command::~Command()
}
}
+AdHocFormatter(PQCommandParamName, "$%?");
void
-PQ::Command::prepareSql(std::string & psql, const std::string & sql)
+PQ::Command::prepareSql(std::stringstream & psql, const std::string & sql) const
{
- char buf[10];
+ if (values.empty()) {
+ psql << sql;
+ return;
+ }
int p = 1;
bool inquote = false;
- for(std::string::const_iterator i = sql.begin(); i != sql.end(); ++i) {
- if (*i == '?' && !inquote) {
- psql.append(buf, snprintf(buf, 10, "$%d", p++));
+ for (const auto & i : sql) {
+ if (i == '?' && !inquote) {
+ PQCommandParamName::write(psql, p++);
}
- else if (*i == '\'') {
+ else if (i == '\'') {
inquote = !inquote;
- psql += *i;
+ psql << i;
}
else {
- psql += *i;
+ psql << i;
}
}
}
diff --git a/libpqpp/pq-command.h b/libpqpp/pq-command.h
index 8af2d07..2c0bf14 100644
--- a/libpqpp/pq-command.h
+++ b/libpqpp/pq-command.h
@@ -31,7 +31,7 @@ namespace PQ {
void bindNull(unsigned int) override;
protected:
- static void prepareSql(std::string & psql, const std::string & sql);
+ void prepareSql(std::stringstream & psql, const std::string & sql) const;
const std::string stmntName;
Connection * const c;
diff --git a/libpqpp/pq-cursorselectcommand.cpp b/libpqpp/pq-cursorselectcommand.cpp
index 4ee6e80..ac4b825 100644
--- a/libpqpp/pq-cursorselectcommand.cpp
+++ b/libpqpp/pq-cursorselectcommand.cpp
@@ -3,7 +3,7 @@
#include "pq-error.h"
#include <compileTimeFormatter.h>
-AdHocFormatter(PQCursorSelectDeclare, "DECLARE %? CURSOR FOR %?");
+AdHocFormatter(PQCursorSelectDeclare, "DECLARE %? CURSOR FOR ");
AdHocFormatter(PQCursorSelectFetch, "FETCH %? IN %?");
AdHocFormatter(PQCursorSelectClose, "CLOSE %?");
@@ -14,7 +14,6 @@ PQ::CursorSelectCommand::CursorSelectCommand(Connection * conn, const std::strin
executed(false),
txOpened(false),
fTuples(35),
- s_declare(mkdeclare()),
s_fetch(PQCursorSelectFetch::get(fTuples, stmntName)),
s_close(PQCursorSelectClose::get(stmntName))
{
@@ -33,9 +32,10 @@ PQ::CursorSelectCommand::~CursorSelectCommand()
std::string
PQ::CursorSelectCommand::mkdeclare() const
{
- std::string psql;
+ std::stringstream psql;
+ PQCursorSelectDeclare::write(psql, stmntName);
prepareSql(psql, sql);
- return PQCursorSelectDeclare::get(stmntName, psql);
+ return psql.str();
}
void
@@ -46,6 +46,9 @@ PQ::CursorSelectCommand::execute()
c->beginTx();
txOpened = true;
}
+ if (s_declare.empty()) {
+ s_declare = mkdeclare();
+ }
c->checkResultFree(
PQexecParams(c->conn, s_declare.c_str(), values.size(), NULL, &values.front(), &lengths.front(), NULL, 0),
PGRES_COMMAND_OK);
diff --git a/libpqpp/pq-prepared.cpp b/libpqpp/pq-prepared.cpp
index bdf2a7d..8e6cea5 100644
--- a/libpqpp/pq-prepared.cpp
+++ b/libpqpp/pq-prepared.cpp
@@ -19,11 +19,10 @@ PQ::PreparedStatement::prepare() const
if (i != c->preparedStatements.end()) {
return (pstmt = i->second.c_str());
}
- std::string psql;
- psql.reserve(sql.length() + 20);
+ std::stringstream psql;
prepareSql(psql, sql);
c->checkResultFree(PQprepare(
- c->conn, stmntName.c_str(), psql.c_str(), values.size(), NULL), PGRES_COMMAND_OK);
+ c->conn, stmntName.c_str(), psql.str().c_str(), values.size(), NULL), PGRES_COMMAND_OK);
return (pstmt = c->preparedStatements.insert({hash, stmntName}).first->second.c_str());
}