Date Dev Ver Change details
---------- --- ------ --------------
+2009-11-25 DP 1.12.0 Add code to the schema browser to allow the user to
+ reconnect to the server if the connection is lost.
2009-11-25 DP 1.10.1 Don't attempt to remove rows in the edit grid if the
user presses the delete key when the delete button is
disabled.
conn=0;
noticeArg=0;
connStatus = PGCONN_BAD;
- dbname = database;
#ifdef __WXMSW__
struct in_addr ipaddr;
wxLogInfo(wxT("Server name: %s (resolved to: %s)"), server.c_str(), hostip.c_str());
// Create the connection string
- wxString connstr;
if (!hostname.IsEmpty()) {
connstr.Append(wxT(" host="));
connstr.Append(qtConnString(hostname));
}
}
connstr.Trim(false);
-
+
+ dbHost = server;
+ dbHostName = hostname;
+ dbHostAddress = hostip;
+
// Open the connection
wxString cleanConnStr = connstr;
cleanConnStr.Replace(qtConnString(password), wxT("'XXXXXX'"));
wxLogInfo(wxT("Opening connection with connection string: %s"), cleanConnStr.c_str());
+
+ DoConnect();
+}
+
+
+pgConn::~pgConn()
+{
+ Close();
+}
+
+bool pgConn::DoConnect()
+{
wxCharBuffer cstrUTF=connstr.mb_str(wxConvUTF8);
conn = PQconnectdb(cstrUTF);
if (PQstatus(conn) == CONNECTION_OK)
}
}
- dbHost = server;
- dbHostName = hostname;
- dbHostAddress = hostip;
-
// Set client encoding to Unicode/Ascii
if (PQstatus(conn) == CONNECTION_OK)
{
wxString sql=wxT("SET DateStyle=ISO;SELECT oid, pg_encoding_to_char(encoding) AS encoding, datlastsysoid\n")
wxT(" FROM pg_database WHERE ");
- if (oid)
- sql += wxT("oid = ") + NumToStr(oid);
+ if (save_oid)
+ sql += wxT("oid = ") + NumToStr(save_oid);
else
{
// Note, can't use qtDbString here as we don't know the server version yet.
- wxString db = database;
+ wxString db = save_database;
db.Replace(wxT("\\"), wxT("\\\\"));
db.Replace(wxT("'"), wxT("''"));
- sql += wxT("datname=") + qtString(database);
+ sql += wxT("datname=") + qtString(save_database);
}
delete set;
}
}
-}
-
+ else
+ return false;
-pgConn::~pgConn()
-{
- Close();
+ return true;
}
+
void pgConn::Close()
{
if (conn)
connStatus=PGCONN_BAD;
}
+
+// Reconnect to the server
+bool pgConn::Reconnect()
+{
+ // Close the existing (possibly broken) connection
+ Close();
+
+ // Reset any vars that need to be in a defined state before connecting
+ needColQuoting = false;
+
+ // Attempt the reconnect
+ if (!DoConnect())
+ {
+ wxLogError(_("Failed to re-establish the connection to the server %s"), GetName());
+ return false;
+ }
+
+ return true;
+}
+
+
pgConn *pgConn::Duplicate()
{
return new pgConn(wxString(save_server), wxString(save_database), wxString(save_username), wxString(save_password), save_port, save_sslmode, save_oid);
}
+
// Return the SSL mode name
wxString pgConn::GetSslModeName()
{
{
wxString str;
if (dbHost.IsEmpty())
- str.Printf(_("%s on local socket"), dbname.c_str());
+ str.Printf(_("%s on local socket"), save_database.c_str());
else
- str.Printf(_("%s on %s@%s:%d"), dbname.c_str(), GetUser().c_str(), dbHost.c_str(), GetPort());
+ str.Printf(_("%s on %s@%s:%d"), save_database.c_str(), GetUser().c_str(), dbHost.c_str(), GetPort());
return str;
}
PQclear(qryRes);
}
}
- return 0;
+ return new pgSet();
}
//////////////////////////////////////////////////////////////////////////
bool pgConn::IsAlive()
{
if (GetStatus() != PGCONN_OK)
- {
- lastResultError.severity = wxString(wxT("FATAL"));
- lastResultError.msg_primary = wxString(PQerrorMessage(conn), *conv);
- lastResultError.formatted_msg = lastResultError.severity + wxT(": ") + lastResultError.msg_primary;
- wxLogError(wxT("%s"), lastResultError.msg_primary.c_str());
return false;
- }
PGresult *qryRes = PQexec(conn, "SELECT 1;");
lastResultStatus = PQresultStatus(qryRes);
#include "utils/sysLogger.h"
#include "utils/pgDefs.h"
+pgSet::pgSet()
+: conv(wxConvLibc)
+{
+ conn = 0;
+ res = 0;
+ nCols = 0;
+ nRows = 0;
+ pos = 0;
+}
+
pgSet::pgSet(PGresult *newRes, pgConn *newConn, wxMBConv &cnv, bool needColQt)
: conv(cnv)
{
conn->Close();
if (!userInformed)
{
- wxMessageDialog dlg(this, _("Close database browser? If you abort, the object browser will not show accurate data."),
+ wxMessageDialog dlg(this, _("Do you want to attempt to reconnect to the database?"),
wxString::Format(_("Connection to database %s lost."), db->GetName().c_str()),
wxICON_EXCLAMATION|wxYES_NO|wxYES_DEFAULT);
- closeIt = (dlg.ShowModal() == wxID_YES);
+ closeIt = (dlg.ShowModal() == wxID_NO);
userInformed = true;
}
if (closeIt)
browser->DeleteChildren(db->GetId());
db->UpdateIcon(browser);
}
+ else
+ {
+ // Create a server object and connect it.
+ wxBusyInfo waiting(wxString::Format(_("Reconnecting to database %s"),
+ db->GetName().c_str()), this);
+
+ // Give the UI a chance to redraw
+ wxSafeYield();
+ wxMilliSleep(100);
+ wxSafeYield();
+
+ if (!conn->Reconnect())
+ {
+ db->Disconnect();
+
+ browser->DeleteChildren(db->GetId());
+ db->UpdateIcon(browser);
+ }
+ else
+ // Indicate things are back to normal
+ userInformed = false;
+ }
+
}
}
}
server->connection()->Close();
if (!userInformed)
{
- wxMessageDialog dlg(this, _("Close server browser? If you abort, the object browser will not show accurate data."),
+ wxMessageDialog dlg(this, _("Do you want to attempt to reconnect to the server?"),
wxString::Format(_("Connection to server %s lost."), server->GetName().c_str()),
wxICON_EXCLAMATION|wxYES_NO|wxYES_DEFAULT);
- closeIt = (dlg.ShowModal() == wxID_YES);
+ closeIt = (dlg.ShowModal() == wxID_NO);
userInformed = true;
}
if (closeIt)
execSelChange(serverItem, true);
browser->DeleteChildren(serverItem);
}
+ else
+ {
+ // Create a server object and connect it.
+ wxBusyInfo waiting(wxString::Format(_("Reconnecting to server %s (%s:%d)"),
+ server->GetDescription().c_str(), server->GetName().c_str(), server->GetPort()), this);
+
+ // Give the UI a chance to redraw
+ wxSafeYield();
+ wxMilliSleep(100);
+ wxSafeYield();
+
+ if (!server->connection()->Reconnect())
+ {
+ server->Disconnect(this);
+ browser->SelectItem(serverItem);
+ execSelChange(serverItem, true);
+ browser->DeleteChildren(serverItem);
+ }
+ else
+ // Indicate things are back to normal
+ userInformed = false;
+ }
}
}
}
static void ExamineLibpqVersion();
static double GetLibpqVersion() { return libpqVersion; }
- static bool IsValidServerEncoding(int encid) { return pg_valid_server_encoding_id(encid); }
+ static bool IsValidServerEncoding(int encid) { return (bool)pg_valid_server_encoding_id(encid); }
void Close();
+ bool Reconnect();
bool ExecuteVoid(const wxString& sql, bool reportError = true);
wxString ExecuteScalar(const wxString& sql);
pgSet *ExecuteSet(const wxString& sql);
wxString GetHost() const { return dbHost; }
wxString GetHostName() const { return dbHostName; }
wxString GetHostAddress() const { return dbHostAddress; }
- wxString GetDbname() const { return dbname; }
+ wxString GetDbname() const { return save_database; }
wxString GetName() const;
bool GetNeedUtfConnectString() { return utfConnectString; }
int GetPort() const { return atoi(PQport(conn)); };
wxMBConv *conv;
bool needColQuoting, utfConnectString;
- wxString dbHost, dbHostName, dbHostAddress, dbname;
+ wxString dbHost, dbHostName, dbHostAddress;
OID lastSystemOID;
OID dbOid;
friend class pgQueryThread;
private:
+ bool DoConnect();
+
wxString qtString(const wxString& value);
bool features[32];
bool isGreenplum;
wxString reservedNamespaces;
-
+ wxString connstr;
+
wxString save_server, save_database, save_username, save_password;
int save_port, save_sslmode;
OID save_oid;
class pgSet
{
public:
+ pgSet();
pgSet(PGresult *newRes, pgConn *newConn, wxMBConv &cnv, bool needColQt);
~pgSet();
long NumRows() const { return nRows; }