From e804db8fcc2db928dff08555a1aa70af0afbb5fb Mon Sep 17 00:00:00 2001 From: Ansgar Becker Date: Fri, 5 Jul 2019 06:44:10 +0200 Subject: [PATCH] Issue #677: provide a new library combobox in MySQL mode, for selecting any of the libmysql/mariadb.dll files from the application directory --- out/locale/en/LC_MESSAGES/default.po | 6 +++- source/apphelpers.pas | 3 +- source/connections.dfm | 25 +++++++++++++--- source/connections.pas | 23 ++++++++++++++- source/dbconnection.pas | 43 +++++++++++----------------- 5 files changed, 67 insertions(+), 33 deletions(-) diff --git a/out/locale/en/LC_MESSAGES/default.po b/out/locale/en/LC_MESSAGES/default.po index 0122e04a..d7ebc1db 100644 --- a/out/locale/en/LC_MESSAGES/default.po +++ b/out/locale/en/LC_MESSAGES/default.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: HeidiSQL\n" "POT-Creation-Date: 2012-11-05 21:40\n" -"PO-Revision-Date: 2019-06-12 20:31+0200\n" +"PO-Revision-Date: 2019-07-05 06:42+0200\n" "Last-Translator: Ansgar Becker \n" "Language-Team: English (http://www.transifex.com/projects/p/heidisql/language/en/)\n" "MIME-Version: 1.0\n" @@ -4025,6 +4025,10 @@ msgstr "Trying to load library with full path: %s" msgid "Library error in %s: Could not find procedure address for \"%s\"" msgstr "Library error in %s: Could not find procedure address for \"%s\"" +#. DLL loading failed entirely +msgid "Library %s seems unusable. Please select a different one." +msgstr "Library %s seems unusable. Please select a different one." + #: dbconnection.pas:1392 msgid "Cannot find a usable %s. Please launch %s from the directory where you have installed it." msgstr "Cannot find a usable %s. Please launch %s from the directory where you have installed it." diff --git a/source/apphelpers.pas b/source/apphelpers.pas index bb6c91d6..a3bdcb33 100644 --- a/source/apphelpers.pas +++ b/source/apphelpers.pas @@ -141,7 +141,7 @@ type asWrapLongLines, asDisplayBLOBsAsText, asSingleQueries, asMemoEditorWidth, asMemoEditorHeight, asMemoEditorMaximized, asMemoEditorWrap, asDelimiter, asSQLHelpWindowLeft, asSQLHelpWindowTop, asSQLHelpWindowWidth, asSQLHelpWindowHeight, asSQLHelpPnlLeftWidth, asSQLHelpPnlRightTopHeight, asHost, - asUser, asPassword, asCleartextPluginEnabled, asWindowsAuth, asLoginPrompt, asPort, + asUser, asPassword, asCleartextPluginEnabled, asWindowsAuth, asLoginPrompt, asPort, asLibrary, asPlinkExecutable, asSSHtunnelHost, asSSHtunnelHostPort, asSSHtunnelPort, asSSHtunnelUser, asSSHtunnelPassword, asSSHtunnelTimeout, asSSHtunnelPrivateKey, asSSLActive, asSSLKey, asSSLCert, asSSLCA, asSSLCipher, asNetType, asCompressed, asLocalTimeZone, asQueryTimeout, asKeepAlive, @@ -3495,6 +3495,7 @@ begin InitSetting(asWindowsAuth, 'WindowsAuth', 0, False, '', True); InitSetting(asLoginPrompt, 'LoginPrompt', 0, False, '', True); InitSetting(asPort, 'Port', 0, False, '', True); + InitSetting(asLibrary, 'Library', 0, False, 'libmariadb.dll', True); InitSetting(asPlinkExecutable, 'PlinkExecutable', 0, False, ''); InitSetting(asSSHtunnelHost, 'SSHtunnelHost', 0, False, '', True); InitSetting(asSSHtunnelHostPort, 'SSHtunnelHostPort', 22, False, '', True); diff --git a/source/connections.dfm b/source/connections.dfm index dce2e6a7..f045703f 100644 --- a/source/connections.dfm +++ b/source/connections.dfm @@ -273,11 +273,18 @@ object connform: Tconnform end object lblComment: TLabel Left = 3 - Top = 241 + Top = 270 Width = 49 Height = 13 Caption = 'Comment:' end + object lblLibrary: TLabel + Left = 3 + Top = 243 + Width = 37 + Height = 13 + Caption = 'Library:' + end object chkCompressed: TCheckBox Left = 120 Top = 190 @@ -377,12 +384,12 @@ object connform: Tconnform end object memoComment: TMemo Left = 120 - Top = 238 + Top = 267 Width = 294 - Height = 119 + Height = 90 Anchors = [akLeft, akTop, akRight, akBottom] ScrollBars = ssVertical - TabOrder = 10 + TabOrder = 11 OnChange = Modification end object editDatabases: TButtonedEdit @@ -399,6 +406,16 @@ object connform: Tconnform OnChange = Modification OnRightButtonClick = editDatabasesRightButtonClick end + object comboLibrary: TComboBox + Left = 120 + Top = 240 + Width = 294 + Height = 21 + Style = csDropDownList + Anchors = [akLeft, akTop, akRight] + TabOrder = 10 + OnChange = Modification + end end end object tabSSHtunnel: TTabSheet diff --git a/source/connections.pas b/source/connections.pas index e4f3f0ff..80657f69 100644 --- a/source/connections.pas +++ b/source/connections.pas @@ -11,7 +11,7 @@ interface uses Windows, SysUtils, Classes, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, ComCtrls, VirtualTrees, Menus, Graphics, Generics.Collections, ActiveX, extra_controls, Messages, - dbconnection, gnugettext; + dbconnection, gnugettext, SynRegExpr, System.Types, System.IOUtils; type Tconnform = class(TFormWithSizeGrip) @@ -121,6 +121,8 @@ type TimerButtonAnimation: TTimer; lblBackgroundColor: TLabel; ColorBoxBackgroundColor: TColorBox; + comboLibrary: TComboBox; + lblLibrary: TLabel; procedure FormCreate(Sender: TObject); procedure btnOpenClick(Sender: TObject); procedure FormShow(Sender: TObject); @@ -230,6 +232,9 @@ var nt: TNetType; Node: PVirtualNode; Params: TConnectionParameters; + rx: TRegExpr; + Libs: TStringDynArray; + LibPath, LibFile: String; begin // Fix GUI stuff TranslateComponent(Self); @@ -265,6 +270,17 @@ begin end; Params.Free; + // Detect existing MySQL libraries + rx := TRegExpr.Create; + rx.Expression := '^lib(mysql|mariadb).*\.dll$'; + Libs := TDirectory.GetFiles(ExtractFilePath(ParamStr(0)), '*.dll'); + for LibPath in Libs do begin + LibFile := ExtractFileName(LibPath); + if rx.Exec(LibFile) then begin + comboLibrary.Items.Add(LibFile); + end; + end; + // Init sessions tree RefreshSessions(nil); @@ -388,6 +404,7 @@ begin Sess.LocalTimeZone := chkLocalTimeZone.Checked; Sess.FullTableStatus := chkFullTableStatus.Checked; Sess.SessionColor := ColorBoxBackgroundColor.Selected; + Sess.LibraryFile := comboLibrary.Text; Sess.AllDatabasesStr := editDatabases.Text; Sess.Comment := memoComment.Text; Sess.StartupScriptFilename := editStartupScript.Text; @@ -582,6 +599,7 @@ begin else Result.Port := 0; Result.AllDatabasesStr := editDatabases.Text; + Result.LibraryFile := comboLibrary.Text; Result.Comment := memoComment.Text; Result.SSHHost := editSSHHost.Text; Result.SSHPort := MakeInt(editSSHPort.Text); @@ -848,6 +866,7 @@ begin chkFullTableStatus.Checked := Sess.FullTableStatus; ColorBoxBackgroundColor.Selected := Sess.SessionColor; editDatabases.Text := Sess.AllDatabasesStr; + comboLibrary.ItemIndex := comboLibrary.Items.IndexOf(Sess.LibraryFile); memoComment.Text := Sess.Comment; editStartupScript.Text := Sess.StartupScriptFilename; editSSHPlinkExe.Text := Sess.SSHPlinkExe; @@ -1108,6 +1127,7 @@ begin or (Sess.SessionColor <> ColorBoxBackgroundColor.Selected) or (Sess.NetType <> TNetType(comboNetType.ItemIndex)) or (Sess.StartupScriptFilename <> editStartupScript.Text) + or (Sess.LibraryFile <> comboLibrary.Text) or (Sess.AllDatabasesStr <> editDatabases.Text) or (Sess.Comment <> memoComment.Text) or (Sess.SSHHost <> editSSHHost.Text) @@ -1187,6 +1207,7 @@ begin lblPort.Enabled := False; // Named instance without port editPort.Enabled := lblPort.Enabled; updownPort.Enabled := lblPort.Enabled; + comboLibrary.Enabled := Params.NetTypeGroup in [ngMySQL]; if Params.NetTypeGroup = ngPgSQL then lblDatabase.Caption := _('Database')+':' else diff --git a/source/dbconnection.pas b/source/dbconnection.pas index 6ca5534c..3c57f725 100644 --- a/source/dbconnection.pas +++ b/source/dbconnection.pas @@ -213,7 +213,7 @@ type TConnectionParameters = class(TObject) strict private FNetType: TNetType; - FHostname, FUsername, FPassword, FAllDatabases, FComment, FStartupScriptFilename, + FHostname, FUsername, FPassword, FAllDatabases, FLibraryFile, FComment, FStartupScriptFilename, FSessionPath, FSSLPrivateKey, FSSLCertificate, FSSLCACertificate, FSSLCipher, FServerVersion, FSSHHost, FSSHUser, FSSHPassword, FSSHPlinkExe, FSSHPrivateKey: String; FPort, FSSHPort, FSSHLocalPort, FSSHTimeout, FCounter, FQueryTimeout, FKeepAlive: Integer; @@ -263,6 +263,7 @@ type property WindowsAuth: Boolean read FWindowsAuth write FWindowsAuth; property CleartextPluginEnabled: Boolean read FCleartextPluginEnabled write FCleartextPluginEnabled; property AllDatabasesStr: String read FAllDatabases write FAllDatabases; + property LibraryFile: String read FLibraryFile write FLibraryFile; property Comment: String read FComment write FComment; property StartupScriptFilename: String read FStartupScriptFilename write FStartupScriptFilename; property QueryTimeout: Integer read FQueryTimeout write FQueryTimeout; @@ -1088,6 +1089,7 @@ begin FPort := DefaultPort; FCompressed := AppSettings.GetDefaultBool(asCompressed); FAllDatabases := AppSettings.GetDefaultString(asDatabases); + FLibraryFile := AppSettings.GetDefaultString(asLibrary); FComment := AppSettings.GetDefaultString(asComment); FSSHHost := AppSettings.GetDefaultString(asSSHtunnelHost); @@ -1154,6 +1156,7 @@ begin FPort := MakeInt(AppSettings.ReadString(asPort)); FCompressed := AppSettings.ReadBool(asCompressed); FAllDatabases := AppSettings.ReadString(asDatabases); + FLibraryFile := AppSettings.ReadString(asLibrary); FComment := AppSettings.ReadString(asComment); FSSHHost := AppSettings.ReadString(asSSHtunnelHost); @@ -1218,6 +1221,7 @@ begin AppSettings.WriteInt(asKeepAlive, FKeepAlive); AppSettings.WriteBool(asFullTableStatus, FFullTableStatus); AppSettings.WriteString(asDatabases, FAllDatabases); + AppSettings.WriteString(asLibrary, FLibraryFile); AppSettings.WriteString(asComment, FComment); AppSettings.WriteString(asStartupScriptFilename, FStartupScriptFilename); AppSettings.WriteInt(asTreeBackground, FSessionColor); @@ -2214,35 +2218,22 @@ end; procedure TMySQLConnection.DoBeforeConnect; var msg, - TryLibraryPath: String; - TryLibraryPaths: TStringList; + LibraryPath: String; begin // Init libmysql before actually connecting. - - - // Try newer libmariadb version at first, and fall back to libmysql, - // then fall back to dlls somewhere else on the users harddisk - // Win XP needs libmysql.dll - TryLibraryPaths := TStringList.Create; - TryLibraryPaths.Add(ExtractFilePath(Application.ExeName) + 'libmariadb.dll'); - TryLibraryPaths.Add(ExtractFilePath(Application.ExeName) + 'libmysql.dll'); - TryLibraryPaths.Add('libmariadb.dll'); - TryLibraryPaths.Add('libmysql.dll'); - - for TryLibraryPath in TryLibraryPaths do begin - Log(lcDebug, f_('Loading library file %s ...', [TryLibraryPath])); - try - FLib := TMySQLLib.Create(TryLibraryPath); - Log(lcDebug, FLib.DllFile + ' v' + DecodeApiString(FLib.mysql_get_client_info) + ' loaded.'); - Break; - except - on E:Exception do - Log(lcDebug, E.Message); - end + LibraryPath := ExtractFilePath(ParamStr(0)) + Parameters.LibraryFile; + Log(lcDebug, f_('Loading library file %s ...', [LibraryPath])); + try + FLib := TMySQLLib.Create(LibraryPath); + Log(lcDebug, FLib.DllFile + ' v' + DecodeApiString(FLib.mysql_get_client_info) + ' loaded.'); + except + on E:Exception do + Log(lcDebug, E.Message); end; + if not Assigned(FLib) then begin - msg := f_('Cannot find a usable %s. Please launch %s from the directory where you have installed it.', - [ExtractFileName(TryLibraryPaths[0]), ExtractFileName(ParamStr(0))] + msg := f_('Library %s seems unusable. Please select a different one.', + [ExtractFileName(LibraryPath)] ); if Windows.GetLastError <> 0 then msg := msg + CRLF + CRLF + f_('Internal error %d:', [Windows.GetLastError]) + ' ' + SysErrorMessage(Windows.GetLastError);