Index: pgConn.cpp =================================================================== RCS file: /projects/pgadmin3/src/db/pgConn.cpp,v retrieving revision 1.45 retrieving revision 1.46 diff -Lsrc/db/pgConn.cpp -Lsrc/db/pgConn.cpp -u -w -r1.45 -r1.46 --- src/db/pgConn.cpp +++ src/db/pgConn.cpp @@ -191,7 +191,7 @@ bool pgConn::IsSSLconnected() { - return (PQstatus(conn) == CONNECTION_OK && PQgetssl(conn) != NULL); + return (conn && PQstatus(conn) == CONNECTION_OK && PQgetssl(conn) != NULL); } #endif @@ -225,6 +225,9 @@ bool pgConn::ExecuteVoid(const wxString& sql) { + if (GetStatus() != PGCONN_OK) + return false; + // Execute the query and get the status. PGresult *qryRes; @@ -236,7 +239,7 @@ if (res != PGRES_TUPLES_OK && res != PGRES_COMMAND_OK) { - wxLogError(wxT("%s"), wxString(PQerrorMessage(conn), *conv).c_str()); + LogError(); } // Cleanup & exit @@ -258,6 +261,10 @@ wxString pgConn::ExecuteScalar(const wxString& sql) { + wxString result; + + if (GetStatus() == PGCONN_OK) + { // Execute the query and get the status. PGresult *qryRes; wxLogSql(wxT("Scalar query (%s:%d): %s"), this->GetHost().c_str(), this->GetPort(), sql.c_str()); @@ -266,7 +273,7 @@ // Check for errors if (PQresultStatus(qryRes) != PGRES_TUPLES_OK) { - wxLogError(wxT("%s"), wxString(PQerrorMessage(conn), *conv).c_str()); + LogError(); PQclear(qryRes); return wxEmptyString; } @@ -280,19 +287,22 @@ } // Retrieve the query result and return it. - wxString result; result=wxString(PQgetvalue(qryRes, 0, 0), *conv); wxLogSql(wxT("Query result: %s"), result.c_str()); // Cleanup & exit PQclear(qryRes); + } + return result; } pgSet *pgConn::ExecuteSet(const wxString& sql) { // Execute the query and get the status. + if (GetStatus() == PGCONN_OK) + { PGresult *qryRes; wxLogSql(wxT("Set query (%s:%d): %s"), this->GetHost().c_str(), this->GetPort(), sql.c_str()); qryRes = PQexec(conn, sql.mb_str(*conv)); @@ -301,7 +311,7 @@ if (status == PGRES_TUPLES_OK || status == PGRES_COMMAND_OK) { - pgSet *set = new pgSet(qryRes, conn, *conv, needColQuoting); + pgSet *set = new pgSet(qryRes, this, *conv, needColQuoting); if (!set) { wxLogError(__("Couldn't create a pgSet object!")); @@ -311,10 +321,10 @@ } else { - wxLogError(wxT("%s"), wxString(PQerrorMessage(conn), *conv).c_str()); + LogError(); PQclear(qryRes); } - + } return 0; } @@ -322,13 +332,32 @@ // Info ////////////////////////////////////////////////////////////////////////// + +void pgConn::LogError() +{ + if (conn) + { + wxLogError(wxT("%s"), wxString(PQerrorMessage(conn), *conv).c_str()); + + ConnStatusType status = PQstatus(conn); + if (status == CONNECTION_BAD) + { + PQfinish(conn); + conn=0; + } + } +} + + int pgConn::GetStatus() const { - if(resolvedIP) { - return PQstatus(conn); - } else { + if(!resolvedIP) return PGCONN_DNSERR; - } + + if (!conn) + return PGCONN_BAD; + else + return PQstatus(conn); } Index: pgConn.h =================================================================== RCS file: /projects/pgadmin3/src/include/pgConn.h,v retrieving revision 1.22 retrieving revision 1.23 diff -Lsrc/include/pgConn.h -Lsrc/include/pgConn.h -u -w -r1.22 -r1.23 --- src/include/pgConn.h +++ src/include/pgConn.h @@ -69,6 +69,9 @@ bool BackendMinimumVersion(int major, int minor); void RegisterNoticeProcessor(PQnoticeProcessor proc, void *arg); wxString SystemNamespaceRestriction(const wxString &nsp); + + void LogError(); + #ifdef SSL bool IsSSLconnected(); #endif Index: pgDatabase.h =================================================================== RCS file: /projects/pgadmin3/src/include/pgDatabase.h,v retrieving revision 1.31 retrieving revision 1.32 diff -Lsrc/include/pgDatabase.h -Lsrc/include/pgDatabase.h -u -w -r1.31 -r1.32 --- src/include/pgDatabase.h +++ src/include/pgDatabase.h @@ -36,9 +36,9 @@ static pgObject *ReadObjects(pgCollection *collection, wxTreeCtrl *browser, const wxString &restriction=wxT("")); static void ShowStatistics(pgCollection *collection, ctlListView *statistics); - pgSet *ExecuteSet(const wxString& sql) { return conn->ExecuteSet(sql); } - wxString ExecuteScalar(const wxString& sql) { return conn->ExecuteScalar(sql); } - bool ExecuteVoid(const wxString& sql) { return conn->ExecuteVoid(sql); } + pgSet *ExecuteSet(const wxString& sql); + wxString ExecuteScalar(const wxString& sql); + bool ExecuteVoid(const wxString& sql); wxString GetPrettyOption() const { return prettyOption; } @@ -55,7 +55,7 @@ wxString GetSearchPath() const { return searchPath; } wxString GetSchemaPrefix(const wxString &schemaname) const; wxString GetQuotedSchemaPrefix(const wxString &schemaname) const; - bool GetConnected() const { return connected; } + bool GetConnected() const { return conn != 0; } bool GetSystemObject() const; long GetMissingFKs() const { return missingFKs; } @@ -64,6 +64,7 @@ bool RequireDropConfirm() { return true; } pgConn *connection() { return conn; } int Connect(); + void Disconnect(); void AppendSchemaChange(const wxString &sql); wxString GetSchemaChanges() { return schemaChanges; } void ClearSchemaChanges() { schemaChanges=wxEmptyString; } @@ -76,7 +77,7 @@ pgConn *conn; wxString searchPath, path, encoding, variables; wxString prettyOption; - bool allowConnections, connected, createPrivilege; + bool allowConnections, createPrivilege; long missingFKs; wxString schemaChanges; Index: pgDatabase.cpp =================================================================== RCS file: /projects/pgadmin3/src/schema/pgDatabase.cpp,v retrieving revision 1.51 retrieving revision 1.52 diff -Lsrc/schema/pgDatabase.cpp -Lsrc/schema/pgDatabase.cpp -u -w -r1.51 -r1.52 --- src/schema/pgDatabase.cpp +++ src/schema/pgDatabase.cpp @@ -28,7 +28,6 @@ wxLogInfo(wxT("Creating a pgDatabase object")); allowConnections = TRUE; - connected = FALSE; conn = NULL; } @@ -60,7 +59,7 @@ if (!allowConnections) return PGCONN_REFUSED; - if (connected) + if (conn) return conn->GetStatus(); else { @@ -68,7 +67,6 @@ if (conn->GetStatus() == PGCONN_OK) { // Now we're connected. - connected = TRUE; iSetComment(conn->ExecuteScalar(wxT("SELECT description FROM pg_description WHERE objoid=") + GetOidStr())); // check for extended ruleutils with pretty-print option @@ -82,6 +80,8 @@ } else { + delete conn; + conn=0; wxLogError(wxT("%s"), conn->GetLastError().c_str()); return PGCONN_BAD; } @@ -89,6 +89,55 @@ } +void pgDatabase::Disconnect() +{ +#if 0 + if (conn) + delete conn; + conn=0; +#endif +} + + +pgSet *pgDatabase::ExecuteSet(const wxString& sql) +{ + pgSet *set=0; + if (conn) + { + set=conn->ExecuteSet(sql); + if (!set && conn->GetStatus() == PGCONN_BAD) + Disconnect(); + } + return set; +} + + +wxString pgDatabase::ExecuteScalar(const wxString& sql) +{ + wxString str; + if (conn) + { + str = conn->ExecuteScalar(sql); + if (str.IsEmpty() && conn->GetStatus() == PGCONN_BAD) + Disconnect(); + } + return str; +} + + +bool pgDatabase::ExecuteVoid(const wxString& sql) +{ + bool rc; + if (conn) + { + rc = conn->ExecuteVoid(sql); + if (!rc && conn->GetStatus() == PGCONN_BAD) + Disconnect(); + } + return rc; +} + + wxString pgDatabase::GetSchemaPrefix(const wxString &name) const { if (name.IsEmpty()) @@ -144,12 +193,8 @@ bool pgDatabase::DropObject(wxFrame *frame, wxTreeCtrl *browser) { - if (conn) - { - delete conn; - conn=0; - connected = FALSE; - } + Disconnect(); + bool done=server->ExecuteVoid(wxT("DROP DATABASE ") + GetQuotedIdentifier() + wxT(";")); if (!done) Connect();