From 74fcbf827294bac907fffe57382e34359893f20f Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Wed, 4 Jan 2017 02:00:04 +0000 Subject: C++ify the SQL preparer and skip it if no variables are being bound --- libpqpp/pq-command.cpp | 20 ++++++++++++-------- libpqpp/pq-command.h | 2 +- libpqpp/pq-cursorselectcommand.cpp | 11 +++++++---- libpqpp/pq-prepared.cpp | 5 ++--- 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 -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()); } -- cgit v1.2.3