summaryrefslogtreecommitdiff
path: root/libpqpp/selectcommand.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libpqpp/selectcommand.cpp')
-rw-r--r--libpqpp/selectcommand.cpp58
1 files changed, 46 insertions, 12 deletions
diff --git a/libpqpp/selectcommand.cpp b/libpqpp/selectcommand.cpp
index 6ed0d5a..9d3f356 100644
--- a/libpqpp/selectcommand.cpp
+++ b/libpqpp/selectcommand.cpp
@@ -12,11 +12,14 @@ PQ::SelectCommand::SelectCommand(const Connection * conn, const std::string & sq
tuple(0),
execRes(NULL)
{
+ c->beginTx();
}
PQ::SelectCommand::~SelectCommand()
{
- if (execRes) {
+ c->commitTx();
+ if (executed) {
+ PQclear(PQexec(c->conn, ("CLOSE " + stmntName).c_str()));
PQclear(execRes);
}
for (unsigned int f = 0; f < fields.size(); f += 1) {
@@ -28,18 +31,30 @@ void
PQ::SelectCommand::execute()
{
if (!executed) {
- prepare();
- execRes = PQexecPrepared(c->conn, stmntName.c_str(), values.size(), &values.front(), &lengths.front(), &formats.front(), 0);
- c->checkResult(execRes, PGRES_TUPLES_OK);
- unsigned int nFields = PQnfields(execRes);
- fields.resize(nFields);
- for (unsigned int f = 0; f < nFields; f += 1) {
- Column * c = new Column(this, f);
- fields[f] = c;
- fieldsName[c->name] = c;
+ std::string psql;
+ psql.reserve(sql.length() + 40);
+ char buf[4];
+ int p = 1;
+ bool inquote = false;
+ psql += "DECLARE ";
+ psql += stmntName;
+ psql += " CURSOR FOR ";
+ for(std::string::const_iterator i = sql.begin(); i != sql.end(); i++) {
+ if (*i == '?' && !inquote) {
+ snprintf(buf, 4, "$%d", p++);
+ psql += buf;
+ }
+ else if (*i == '\'') {
+ inquote = !inquote;
+ psql += *i;
+ }
+ else {
+ psql += *i;
+ }
}
- nTuples = PQntuples(execRes);
- tuple = -1;
+ c->checkResultFree(
+ PQexecParams(c->conn, psql.c_str(), values.size(), NULL, &values.front(), &lengths.front(), &formats.front(), 0),
+ PGRES_COMMAND_OK);
executed = true;
}
}
@@ -48,10 +63,29 @@ bool
PQ::SelectCommand::fetch()
{
execute();
+ if (tuple >= (nTuples - 1)) {
+ if (execRes) {
+ PQclear(execRes);
+ }
+ execRes = c->checkResult(PQexec(c->conn, ("FETCH 35 IN " + stmntName).c_str()), PGRES_TUPLES_OK);
+ nTuples = PQntuples(execRes);
+ tuple = -1;
+ }
+ if (fields.empty()) {
+ unsigned int nFields = PQnfields(execRes);
+ fields.resize(nFields);
+ for (unsigned int f = 0; f < nFields; f += 1) {
+ Column * c = new Column(this, f);
+ fields[f] = c;
+ fieldsName[c->name] = c;
+ }
+ }
if (tuple++ < (nTuples - 1)) {
return true;
}
else {
+ PQclear(PQexec(c->conn, ("CLOSE " + stmntName).c_str()));
+ PQclear(execRes);
executed = false;
return false;
}