From 2af4d3cc18f63febcadb93753ce212a2a397f44e Mon Sep 17 00:00:00 2001 From: Ansgar Becker Date: Sun, 4 May 2014 05:01:25 +0000 Subject: [PATCH] Support query timeout on MSSQL and PostgreSQL. Make customizable per up/down scroller in "Advanced" tab of session manager. Fixes issue #3507. --- source/connections.dfm | 35 +++++++++++++++++++++++++++++++---- source/connections.pas | 10 ++++++++++ source/dbconnection.pas | 7 ++++++- source/helpers.pas | 3 ++- 4 files changed, 49 insertions(+), 6 deletions(-) diff --git a/source/connections.dfm b/source/connections.dfm index da0ac3f6..5d30afa4 100644 --- a/source/connections.dfm +++ b/source/connections.dfm @@ -617,6 +617,13 @@ object connform: Tconnform Caption = 'Startup script:' FocusControl = editStartupScript end + object lblQueryTimeout: TLabel + Left = 3 + Top = 183 + Width = 73 + Height = 13 + Caption = 'Query timeout:' + end object editSSLPrivateKey: TButtonedEdit Left = 120 Top = 36 @@ -671,7 +678,7 @@ object connform: Tconnform end object chkLocalTimeZone: TCheckBox Left = 120 - Top = 180 + Top = 212 Width = 172 Height = 17 Hint = @@ -679,7 +686,7 @@ object connform: Tconnform ', for MySQL 4.1.3+' Anchors = [akLeft, akTop, akRight] Caption = 'Use own client time zone' - TabOrder = 5 + TabOrder = 7 OnClick = Modification end object editStartupScript: TButtonedEdit @@ -698,7 +705,7 @@ object connform: Tconnform end object chkFullTableStatus: TCheckBox Left = 120 - Top = 203 + Top = 235 Width = 172 Height = 17 Hint = @@ -706,9 +713,29 @@ object connform: Tconnform 'DB tables' Anchors = [akLeft, akTop, akRight] Caption = 'Get full table status' - TabOrder = 6 + TabOrder = 8 OnClick = Modification end + object editQueryTimeout: TEdit + Left = 120 + Top = 180 + Width = 90 + Height = 21 + NumbersOnly = True + TabOrder = 5 + Text = '0' + OnChange = Modification + end + object updownQueryTimeout: TUpDown + Left = 210 + Top = 180 + Width = 16 + Height = 21 + Associate = editQueryTimeout + Max = 2147483646 + TabOrder = 6 + Wrap = True + end end object tabStatistics: TTabSheet Caption = 'Statistics' diff --git a/source/connections.pas b/source/connections.pas index 38e35c44..c85aad7a 100644 --- a/source/connections.pas +++ b/source/connections.pas @@ -102,6 +102,9 @@ type Importsettingsfile1: TMenuItem; lblComment: TLabel; memoComment: TMemo; + lblQueryTimeout: TLabel; + editQueryTimeout: TEdit; + updownQueryTimeout: TUpDown; procedure FormCreate(Sender: TObject); procedure btnOpenClick(Sender: TObject); procedure FormShow(Sender: TObject); @@ -317,6 +320,7 @@ begin Sess.Port := updownPort.Position; Sess.NetType := TNetType(comboNetType.ItemIndex); Sess.Compressed := chkCompressed.Checked; + Sess.QueryTimeout := updownQueryTimeout.Position; Sess.LocalTimeZone := chkLocalTimeZone.Checked; Sess.FullTableStatus := chkFullTableStatus.Checked; Sess.AllDatabasesStr := editDatabases.Text; @@ -526,6 +530,7 @@ begin Result.SSLCACertificate := editSSLCACertificate.Text; Result.StartupScriptFilename := editStartupScript.Text; Result.Compressed := chkCompressed.Checked; + Result.QueryTimeout := updownQueryTimeout.Position; Result.LocalTimeZone := chkLocalTimeZone.Checked; Result.FullTableStatus := chkFullTableStatus.Checked; end; @@ -765,6 +770,7 @@ begin chkWindowsAuth.Checked := Sess.WindowsAuth; updownPort.Position := Sess.Port; chkCompressed.Checked := Sess.Compressed; + updownQueryTimeout.Position := Sess.QueryTimeout; chkLocalTimeZone.Checked := Sess.LocalTimeZone; chkFullTableStatus.Checked := Sess.FullTableStatus; editDatabases.Text := Sess.AllDatabasesStr; @@ -1010,6 +1016,7 @@ begin or (Sess.WindowsAuth <> chkWindowsAuth.Checked) or (Sess.Port <> updownPort.Position) or (Sess.Compressed <> chkCompressed.Checked) + or (Sess.QueryTimeout <> updownQueryTimeout.Position) or (Sess.LocalTimeZone <> chkLocalTimeZone.Checked) or (Sess.FullTableStatus <> chkFullTableStatus.Checked) or (Sess.NetType <> TNetType(comboNetType.ItemIndex)) @@ -1098,6 +1105,9 @@ begin lblSSLCertificate.Enabled := Params.WantSSL; editSSLCertificate.Enabled := Params.WantSSL; tabSSHtunnel.TabVisible := Params.NetType = ntMySQL_SSHtunnel; + lblQueryTimeout.Enabled := Params.NetTypeGroup in [ngMSSQL, ngPgSQL]; + editQueryTimeout.Enabled := lblQueryTimeout.Enabled; + updownQueryTimeout.Enabled := lblQueryTimeout.Enabled; Params.Free; end; end; diff --git a/source/dbconnection.pas b/source/dbconnection.pas index 6a208015..911b4a06 100644 --- a/source/dbconnection.pas +++ b/source/dbconnection.pas @@ -205,7 +205,7 @@ type FHostname, FUsername, FPassword, FAllDatabases, FComment, FStartupScriptFilename, FSessionPath, FSSLPrivateKey, FSSLCertificate, FSSLCACertificate, FServerVersion, FSSHHost, FSSHUser, FSSHPassword, FSSHPlinkExe, FSSHPrivateKey: String; - FPort, FSSHPort, FSSHLocalPort, FSSHTimeout, FCounter: Integer; + FPort, FSSHPort, FSSHLocalPort, FSSHTimeout, FCounter, FQueryTimeout: Integer; FLoginPrompt, FCompressed, FLocalTimeZone, FFullTableStatus, FWindowsAuth, FWantSSL, FIsFolder: Boolean; FSessionColor: TColor; FLastConnect: TDateTime; @@ -246,6 +246,7 @@ type property AllDatabasesStr: String read FAllDatabases write FAllDatabases; property Comment: String read FComment write FComment; property StartupScriptFilename: String read FStartupScriptFilename write FStartupScriptFilename; + property QueryTimeout: Integer read FQueryTimeout write FQueryTimeout; property Compressed: Boolean read FCompressed write FCompressed; property LocalTimeZone: Boolean read FLocalTimeZone write FLocalTimeZone; property FullTableStatus: Boolean read FFullTableStatus write FFullTableStatus; @@ -1099,6 +1100,7 @@ begin FSSLCACertificate := AppSettings.ReadString(asSSLCA); FStartupScriptFilename := AppSettings.ReadString(asStartupScriptFilename); FCompressed := AppSettings.ReadBool(asCompressed); + FQueryTimeout := AppSettings.ReadInt(asQueryTimeout); FLocalTimeZone := AppSettings.ReadBool(asLocalTimeZone); FFullTableStatus := AppSettings.ReadBool(asFullTableStatus); FServerVersion := AppSettings.ReadString(asServerVersionFull); @@ -1132,6 +1134,7 @@ begin AppSettings.WriteInt(asNetType, Integer(FNetType)); AppSettings.WriteBool(asCompressed, FCompressed); AppSettings.WriteBool(asLocalTimeZone, FLocalTimeZone); + AppSettings.WriteInt(asQueryTimeout, FQueryTimeout); AppSettings.WriteBool(asFullTableStatus, FFullTableStatus); AppSettings.WriteString(asDatabases, FAllDatabases); AppSettings.WriteString(asComment, FComment); @@ -1710,6 +1713,7 @@ begin // CurCharset := CharacterSet; // Log(lcDebug, 'Characterset: '+CurCharset); FIsUnicode := True; + FAdoHandle.CommandTimeout := Parameters.QueryTimeout; try // Gracefully accept failure on MS Azure (SQL Server 11), which does not have a sysprocesses table FServerUptime := StrToIntDef(GetVar('SELECT DATEDIFF(SECOND, '+QuoteIdent('login_time')+', CURRENT_TIMESTAMP) FROM '+QuoteIdent('master')+'.'+QuoteIdent('dbo')+'.'+QuoteIdent('sysprocesses')+' WHERE '+QuoteIdent('spid')+'=1'), -1); @@ -1802,6 +1806,7 @@ begin FConnectionStarted := GetTickCount div 1000; Log(lcInfo, f_('Connected. Thread-ID: %d', [ThreadId])); FIsUnicode := True; + Query('SET statement_timeout TO '+IntToStr(Parameters.QueryTimeout)); try FServerUptime := StrToIntDef(GetVar('SELECT EXTRACT(EPOCH FROM CURRENT_TIMESTAMP - pg_postmaster_start_time())::INTEGER'), -1); except diff --git a/source/helpers.pas b/source/helpers.pas index a8b69ca5..2a591f2f 100644 --- a/source/helpers.pas +++ b/source/helpers.pas @@ -140,7 +140,7 @@ type asUser, asPassword, asWindowsAuth, asLoginPrompt, asPort, asPlinkExecutable, asSSHtunnelHost, asSSHtunnelHostPort, asSSHtunnelPort, asSSHtunnelUser, asSSHtunnelPassword, asSSHtunnelTimeout, asSSHtunnelPrivateKey, asSSLActive, asSSLKey, - asSSLCert, asSSLCA, asNetType, asCompressed, asLocalTimeZone, + asSSLCert, asSSLCA, asNetType, asCompressed, asLocalTimeZone, asQueryTimeout, asStartupScriptFilename, asDatabases, asComment, asDatabaseFilter, asTableFilter, asExportSQLCreateDatabases, asExportSQLCreateTables, asExportSQLDataHow, asExportSQLFilenames, asExportZIPFilenames, asExportSQLDirectories, asExportSQLDatabase, asExportSQLServerDatabase, asExportSQLOutput, asGridExportOutputCopy, asGridExportOutputFile, @@ -3123,6 +3123,7 @@ begin InitSetting(asNetType, 'NetType', Integer(ntMySQL_TCPIP), False, '', True); InitSetting(asCompressed, 'Compressed', 0, False, '', True); InitSetting(asLocalTimeZone, 'LocalTimeZone', 0, False, '', True); + InitSetting(asQueryTimeout, 'QueryTimeout', 30, False, '', True); InitSetting(asStartupScriptFilename, 'StartupScriptFilename', 0, False, '', True); InitSetting(asDatabases, 'Databases', 0, False, '', True); InitSetting(asComment, 'Comment', 0, False, '', True);