Hi Folks,
I write a program in c++ using PostgreSQL 7.0 at the moment.
During this, I have
written some small classes for accessing the database. One of
this classes is QtResultSet. I use them to manage my statments.
To avoid memory leaks, I use the dtor to free the resultset with
PQclear(). Unfortunaly every call to PQclear causes a coredump.
What is my mistake?
=== QtResultSet.h ===
#include <string>
#include <map>
#include <vector>
#include <libpq-fe.h>
#include "../errors/QtExceptions.h"
#ifndef __QTRESULTSET__
#define __QTRESULTSET__
namespace qt { namespace database { using namespace std; using namespace qt::errors;
class QtResultSet { public:
virtual ~QtResultSet();
vector<string> fieldnames() throw(QtDbConnectionBadErr,
QtDbFatalErr, QtDbNonfatalErr, QtDbBadResponseErr); vector<string> fetch(int) throw(QtDbConnectionBadErr,
QtDbFatalErr, QtDbNonfatalErr, QtDbBadResponseErr); vector<string> fetch(void) throw(QtDbConnectionBadErr,
QtDbFatalErr, QtDbNonfatalErr, QtDbBadResponseErr);
string get_error();
int rows(); int fields();
void execute() throw(QtDbConnectionBadErr, QtDbFatalErr, QtDbNonfatalErr, QtDbBadResponseErr);
friend class QtConnection;
protected: QtResultSet(PGconn *, const string &);
private: void fetch_row(int, vector<string>*); bool binarydata_m; int rows_m; int fields_m; int
currentrow_m; string query_m; string error_m; PGresult *pgresult_mp; PGconn *pgconn_mp; };
} }
#endif
=== QtResultSet.cpp ===
#include <string>
#include <libpq-fe.h>
#include "QtResultSet.h"
#include "../errors/QtExceptions.h"
namespace qt { namespace database { using namespace std; using namespace qt::errors;
QtResultSet::~QtResultSet() {
PQclear(this->pgresult_mp);
}
QtResultSet::QtResultSet(PGconn *pgconn, const string &query)
{ pgconn_mp = pgconn; query_m = query; fields_m = 0; rows_m = 0; currentrow_m =
0; }
void QtResultSet::execute() throw(QtDbConnectionBadErr,
QtDbFatalErr, QtDbNonfatalErr, QtDbBadResponseErr)
try {pgresult_mp = PQexec(pgconn_mp, query_m.c_str());
ExecStatusType res = PQresultStatus(pgresult_mp);
if (res == (PGRES_COMMAND_OK || PGRES_TUPLES_OK)) { rows_m = PQntuples(pgresult_mp); fields_m =
PQnfields(pgresult_mp); binarydata_m = PQbinaryTuples(pgresult_mp); currentrow_m = -1;}else { error_m =
PQresultErrorMessage(pgresult_mp);
switch (res) { case PGRES_EMPTY_QUERY: break;
case PGRES_BAD_RESPONSE: throw QtDbBadResponseErr(); break;
case PGRES_NONFATAL_ERROR: throw QtDbNonfatalErr(); break;
case PGRES_FATAL_ERROR: throw QtDbFatalErr(); break; }
} } catch (...) {
#ifdef QTDEBUGcerr << "Exception catched and PQclear() called." << endl;
#endif QTDEBUG
PQclear(pgresult_mp);
#ifdef QTDEBUGcerr << "Exception rethrown." << endl;
#endif QTDEBUG
throw; } } int QtResultSet::fields() { return fields_m; } int QtResultSet::rows() { return rows_m;
}
vector<string> QtResultSet::fieldnames()
throw(QtDbConnectionBadErr, QtDbFatalErr, QtDbNonfatalErr, QtDbBadResponseErr) { vector<string> row;
for (int i = 0; i < rows_m; i++) {row.push_back(PQfname(pgresult_mp, i)); }
return row; } vector<string> QtResultSet::fetch(void)
throw(QtDbConnectionBadErr, QtDbFatalErr, QtDbNonfatalErr, QtDbBadResponseErr) { vector<string> row;
if (currentrow_m < (rows_m - 1)) {this->fetch_row(++currentrow_m, &row); } else { }
return row; } vector<string> QtResultSet::fetch(int id)
throw(QtDbConnectionBadErr, QtDbFatalErr, QtDbNonfatalErr, QtDbBadResponseErr) { vector<string> row;
if ((id > 0) && (id < rows_m)) {this->fetch_row(id, &row); } else { }
return row; } void QtResultSet::fetch_row(int rowid, vector<string>
*rowdata) {
for (int i = 0; i < fields_m; i++) {rowdata->push_back(string("Aber Hallo")); }
} string QtResultSet::get_error() { return this->error_m; } // QtResultSet::get_error
} // namespace database
} // namespace qt
BYe,
Oliver
--
Oliver Fischer
Level of Detail, Brunnenstr. 196, D-10119 Berlin
Tel. +49/30/280 491 43
--
Oliver Fischer
Level of Detail, Brunnenstr. 196, D-10119 Berlin
Tel. +49/30/280 491 43