diff options
Diffstat (limited to 'libpqpp/selectcommand.cpp')
-rw-r--r-- | libpqpp/selectcommand.cpp | 58 |
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; } |