From 83dad7b0c51a86827f6ecaf27a02b4582812732a Mon Sep 17 00:00:00 2001
From: John Obaterspok <john.obaterspok@gmail.com>
Date: Mon, 15 Jun 2015 21:22:30 +0200
Subject: [PATCH] [PATCH] Add ElapsedTimeToString to format execution time in a
 more readable manner (instead of showing everything as msec)

Signed-off-by: John Obaterspok <john.obaterspok@gmail.com>
---
 pgadmin/dlg/dlgClasses.cpp   |  2 +-
 pgadmin/frm/frmMain.cpp      |  6 ++----
 pgadmin/frm/frmQuery.cpp     | 49 ++++++++++++++++++++++++++++----------------
 pgadmin/include/utils/misc.h |  1 +
 pgadmin/utils/misc.cpp       | 22 ++++++++++++++++++++
 5 files changed, 57 insertions(+), 23 deletions(-)

diff --git a/pgadmin/dlg/dlgClasses.cpp b/pgadmin/dlg/dlgClasses.cpp
index 9a3e473..e6fa488 100644
--- a/pgadmin/dlg/dlgClasses.cpp
+++ b/pgadmin/dlg/dlgClasses.cpp
@@ -562,7 +562,7 @@ void ExecutionDialog::OnOK(wxCommandEvent &ev)
 			{
 				if (txtMessages)
 					txtMessages->AppendText(_("Total query runtime: ")
-					                        + (wxGetLocalTimeMillis() - startTime).ToString() + wxT(" ms."));
+					                        + ElapsedTimeToString(wxGetLocalTimeMillis() - startTime));
 
 				btnOK->SetLabel(_("Done"));
 				btnCancel->Disable();
diff --git a/pgadmin/frm/frmMain.cpp b/pgadmin/frm/frmMain.cpp
index 8629dda..94528e8 100644
--- a/pgadmin/frm/frmMain.cpp
+++ b/pgadmin/frm/frmMain.cpp
@@ -1352,9 +1352,7 @@ void frmMain::EndMsg(bool done)
 	{
 		// Get the execution time & display it
 		float timeval = stopwatch.Time();
-		wxString time;
-		time.Printf(_("%.2f secs"), (timeval / 1000));
-		statusBar->SetStatusText(time, 2);
+		statusBar->SetStatusText(ElapsedTimeToString(timeval), 2);
 
 		// Display the 'Done' message
 		if (done)
@@ -1362,7 +1360,7 @@ void frmMain::EndMsg(bool done)
 		else
 			statusBar->SetStatusText(timermsg + _(" Failed."), 1);
 
-		wxLogStatus(wxT("%s (%s)"), timermsg.c_str(), time.c_str());
+		wxLogStatus(wxT("%s (%s)"), timermsg.c_str(), ElapsedTimeToString(timeval).c_str());
 		wxEndBusyCursor();
 	}
 }
diff --git a/pgadmin/frm/frmQuery.cpp b/pgadmin/frm/frmQuery.cpp
index b5a2f56..5be7acc 100644
--- a/pgadmin/frm/frmQuery.cpp
+++ b/pgadmin/frm/frmQuery.cpp
@@ -55,6 +55,7 @@
 #include "utils/sysLogger.h"
 #include "utils/sysSettings.h"
 #include "utils/utffile.h"
+#include "utils/misc.h"
 #include "pgscript/pgsApplication.h"
 
 // Icons
@@ -2522,7 +2523,7 @@ bool frmQuery::isBeginNotRequired(wxString query)
 	/*
 	 * Check word length (since "beginx" is not "begin").
 	 */
-	while(wxIsalpha(query.GetChar(wordlen)))
+	while(wordlen < query.Length() && wxIsalpha(query.GetChar(wordlen)))
 		wordlen++;
 
 	/*
@@ -2711,7 +2712,7 @@ void frmQuery::OnQueryComplete(pgQueryResultEvent &ev)
 	msgHistory->AppendText(str);
 
 	elapsedQuery = wxGetLocalTimeMillis() - startTimeQuery;
-	SetStatusText(elapsedQuery.ToString() + wxT(" ms"), STATUSPOS_SECS);
+	SetStatusText(ElapsedTimeToString(elapsedQuery), STATUSPOS_SECS);
 
 	if (sqlResult->RunStatus() != PGRES_TUPLES_OK)
 	{
@@ -2724,28 +2725,28 @@ void frmQuery::OnQueryComplete(pgQueryResultEvent &ev)
 			OID insertedOid = sqlResult->InsertedOid();
 			if (insertedCount < 0)
 			{
-				showMessage(wxString::Format(_("Query returned successfully with no result in %s ms."),
-				                             elapsedQuery.ToString().c_str()), _("OK."));
+				showMessage(wxString::Format(_("Query returned successfully with no result in %s."),
+				                             ElapsedTimeToString(elapsedQuery).c_str()), _("OK."));
 			}
 			else if (insertedCount == 1)
 			{
 				if (insertedOid)
 				{
-					showMessage(wxString::Format(_("Query returned successfully: one row with OID %ld inserted, %s ms execution time."),
-					                             (long)insertedOid, elapsedQuery.ToString().c_str()),
+					showMessage(wxString::Format(_("Query returned successfully: one row with OID %ld inserted, %s execution time."),
+					                             (long)insertedOid, ElapsedTimeToString(elapsedQuery).c_str()),
 					            wxString::Format(_("One row with OID %ld inserted."), (long)insertedOid));
 				}
 				else
 				{
-					showMessage(wxString::Format(_("Query returned successfully: one row affected, %s ms execution time."),
-					                             elapsedQuery.ToString().c_str()),
+					showMessage(wxString::Format(_("Query returned successfully: one row affected, %s execution time."),
+					                             ElapsedTimeToString(elapsedQuery).c_str()),
 					            wxString::Format(_("One row affected.")));
 				}
 			}
 			else
 			{
-				showMessage(wxString::Format(_("Query returned successfully: %d rows affected, %s ms execution time."),
-				                             insertedCount, elapsedQuery.ToString().c_str()),
+				showMessage(wxString::Format(_("Query returned successfully: %d rows affected, %s execution time."),
+				                             insertedCount, ElapsedTimeToString(elapsedQuery).c_str()),
 				            wxString::Format(_("%d rows affected."), insertedCount));
 			}
 		}
@@ -2865,9 +2866,9 @@ void frmQuery::OnQueryComplete(pgQueryResultEvent &ev)
 
 				sqlResult->DisplayData();
 
-				SetStatusText(elapsedQuery.ToString() + wxT(" ms"), STATUSPOS_SECS);
+				SetStatusText(ElapsedTimeToString(elapsedQuery), STATUSPOS_SECS);
 
-				str = _("Total query runtime: ") + elapsedQuery.ToString() + wxT(" ms.\n") ;
+				str = _("Total query runtime: ") + ElapsedTimeToString(elapsedQuery) + "\n";
 				msgResult->AppendText(str);
 				msgHistory->AppendText(str);
 
@@ -2952,9 +2953,10 @@ void frmQuery::OnScriptComplete(wxCommandEvent &ev)
 
 	// Manage timer
 	elapsedQuery = wxGetLocalTimeMillis() - startTimeQuery;
-	SetStatusText(elapsedQuery.ToString() + wxT(" ms"), STATUSPOS_SECS);
+	wxString fmtExecTime = ElapsedTimeToString(elapsedQuery);
+	SetStatusText(fmtExecTime, STATUSPOS_SECS);
 	SetStatusText(_("pgScript completed."), STATUSPOS_MSGS);
-	wxString str = _("Total pgScript runtime: ") + elapsedQuery.ToString() + wxT(" ms.\n\n");
+	wxString str = _("Total pgScript runtime: ") + fmtExecTime + "\n\n";
 	msgHistory->AppendText(str);
 
 	// Check whether there was an error/exception
@@ -3078,7 +3080,7 @@ void frmQuery::completeQuery(bool done, bool explain, bool verbose)
 void frmQuery::OnTimer(wxTimerEvent &event)
 {
 	elapsedQuery = wxGetLocalTimeMillis() - startTimeQuery;
-	SetStatusText(elapsedQuery.ToString() + wxT(" ms"), STATUSPOS_SECS);
+	SetStatusText(ElapsedTimeToString(elapsedQuery), STATUSPOS_SECS);
 
 	wxString str = sqlResult->GetMessagesAndClear();
 	if (!str.IsEmpty())
@@ -3088,13 +3090,24 @@ void frmQuery::OnTimer(wxTimerEvent &event)
 	}
 
 	// Increase the granularity for longer running queries
-	if (elapsedQuery > 200 && timer.GetInterval() == 10 && timer.IsRunning())
+	if (timer.IsRunning())
 	{
-		timer.Stop();
-		timer.Start(100);
+		// Set timer to fire every 100 ms if >200 ms elapsed
+		if (elapsedQuery > 200 && timer.GetInterval() < 100)
+		{
+			timer.Stop();
+			timer.Start(100);
+		}
+		// Set timer to fire every 1000 ms if >60 seconds elapsed
+		else if (elapsedQuery > 60 * 1000 && timer.GetInterval() < 1000)
+		{
+			timer.Stop();
+			timer.Start(1000);
+		}
 	}
 }
 
+
 // Adjust sizes of GQB components, Located here because need to
 // avoid some issues when implementing inside controller/view Classes
 void frmQuery::adjustGQBSizes()
diff --git a/pgadmin/include/utils/misc.h b/pgadmin/include/utils/misc.h
index abef297..07713ae 100644
--- a/pgadmin/include/utils/misc.h
+++ b/pgadmin/include/utils/misc.h
@@ -117,6 +117,7 @@ wxString NumToStr(double value);
 wxString NumToStr(OID value);
 wxString NumToStr(wxLongLong value);
 wxString DateToStr(const wxDateTime &datetime);
+wxString ElapsedTimeToString(wxLongLong msec);
 
 
 // Quoting
diff --git a/pgadmin/utils/misc.cpp b/pgadmin/utils/misc.cpp
index b7d8afe..9a134fb 100644
--- a/pgadmin/utils/misc.cpp
+++ b/pgadmin/utils/misc.cpp
@@ -219,6 +219,28 @@ wxString DateToStr(const wxDateTime &datetime)
 }
 
 
+wxString ElapsedTimeToString(wxLongLong msec)
+{
+	wxTimeSpan tsMsec(0, 0, 0, msec);
+
+	int days = tsMsec.GetDays();
+	int hours = (wxTimeSpan(tsMsec.GetHours(), 0, 0, 0) - wxTimeSpan(days * 24)).GetHours();
+	int minutes = (wxTimeSpan(0, tsMsec.GetMinutes(), 0, 0) - wxTimeSpan(hours)).GetMinutes();
+	long seconds = (wxTimeSpan(0, 0, tsMsec.GetSeconds(), 0) - wxTimeSpan(0, minutes)).GetSeconds().ToLong();
+	long milliseconds = (wxTimeSpan(0, 0, 0, tsMsec.GetMilliseconds()) - wxTimeSpan(0, 0, seconds)).GetMilliseconds().ToLong();
+
+	if (days > 0)
+		return wxString::Format("%d %s, %02d:%02d:%02ld hours", days, wxT("days"), hours, minutes, seconds);
+	else if (hours > 0)
+		return wxString::Format("%02d:%02d:%02ld hours", hours, minutes, seconds);
+	else if (msec >= 1000 * 60)
+		return wxString::Format("%02d:%02ld minutes", minutes, seconds);
+	else if (msec >= 1000)
+		return wxString::Format("%ld.%ld secs", seconds, milliseconds / 100);
+	else
+		return msec.ToString() + wxT(" msec");
+}
+
 wxDateTime StrToDateTime(const wxString &value)
 {
 	wxDateTime dt;
-- 
1.9.5.msysgit.1

