Skip to content
Permalink
Browse files

Performance: Search libraries on system once per app instance and net…

… type group. Cache these in TConnectionParameters.FLibraries. OLE DB providers take some time to collect.
  • Loading branch information...
ansgarbecker committed Oct 20, 2019
1 parent f874c80 commit 3f0db16f5b590ef85b4b9b6a06e99cd2b37f11a3
Showing with 53 additions and 43 deletions.
  1. +2 −42 source/connections.pas
  2. +51 −1 source/dbconnection.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, SynRegExpr, System.Types, System.IOUtils, Vcl.GraphUtil, ADODB;
dbconnection, gnugettext, SynRegExpr, System.Types, Vcl.GraphUtil, ADODB;

type
Tconnform = class(TExtForm)
@@ -190,7 +190,6 @@ Tconnform = class(TExtForm)
procedure WMNCLBUTTONDOWN(var Msg: TWMNCLButtonDown) ; message WM_NCLBUTTONDOWN;
procedure WMNCLBUTTONUP(var Msg: TWMNCLButtonUp) ; message WM_NCLBUTTONUP;
procedure RefreshBackgroundColors;
procedure RefreshLibraries(Sess: TConnectionParameters);
public
{ Public declarations }
end;
@@ -855,7 +854,7 @@ procedure Tconnform.ListSessionsFocusChanged(Sender: TBaseVirtualTree;
RefreshBackgroundColors;
ColorBoxBackgroundColor.Selected := Sess.SessionColor;
editDatabases.Text := Sess.AllDatabasesStr;
RefreshLibraries(Sess^);
comboLibrary.Items := Sess.GetLibraries;
comboLibrary.ItemIndex := comboLibrary.Items.IndexOf(Sess.LibraryOrProvider);
if (comboLibrary.ItemIndex = -1) and (comboLibrary.Items.Count > 0) then begin
comboLibrary.ItemIndex := 0;
@@ -897,45 +896,6 @@ procedure Tconnform.RefreshBackgroundColors;
end;


procedure Tconnform.RefreshLibraries(Sess: TConnectionParameters);
var
rx: TRegExpr;
Libs: TStringDynArray;
LibPath, LibFile: String;
Providers: TStringList;
Provider: String;
begin
// Detect existing dll files in app folder
comboLibrary.Clear;

rx := TRegExpr.Create;
rx.ModifierI := True;
case Sess.NetTypeGroup of
ngMySQL: rx.Expression := '^lib(mysql|mariadb).*\.dll$';
ngMSSQL: rx.Expression := '^(MSOLEDBSQL|SQLOLEDB)$';
ngPgSQL: rx.Expression := '^libpq.*\.dll$';
end;

if Sess.NetTypeGroup in [ngMySQL, ngPgSQL] then begin
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;
end else begin
Providers := TStringList.Create;
GetProviderNames(Providers);
for Provider in Providers do begin
if rx.Exec(Provider) then begin
comboLibrary.Items.Add(Provider);
end;
end;
end;
end;


procedure Tconnform.TimerStatisticsTimer(Sender: TObject);
var
LastConnect, Created, DummyDate: TDateTime;
@@ -5,7 +5,7 @@ interface
uses
Classes, SysUtils, windows, dbstructures, SynRegExpr, Generics.Collections, Generics.Defaults,
DateUtils, Types, Math, Dialogs, ADODB, DB, DBCommon, ComObj, Graphics, ExtCtrls, StrUtils,
gnugettext, AnsiStrings, Controls, Forms;
gnugettext, AnsiStrings, Controls, Forms, System.IOUtils;


type
@@ -202,6 +202,7 @@ TPlink = class(TObject)
ntMSSQL_NamedPipe, ntMSSQL_TCPIP, ntMSSQL_SPX, ntMSSQL_VINES, ntMSSQL_RPC,
ntPgSQL_TCPIP, ntPgSQL_SSHtunnel);
TNetTypeGroup = (ngMySQL, ngMSSQL, ngPgSQL);
TNetGroupLibs = TDictionary<TNetTypeGroup, TStringList>;

TConnectionParameters = class(TObject)
strict private
@@ -214,6 +215,7 @@ TConnectionParameters = class(TObject)
FWindowsAuth, FWantSSL, FIsFolder, FCleartextPluginEnabled: Boolean;
FSessionColor: TColor;
FLastConnect: TDateTime;
class var FLibraries: TNetGroupLibs;
function GetImageIndex: Integer;
function GetSessionName: String;
public
@@ -236,6 +238,7 @@ TConnectionParameters = class(TObject)
function IsAzure: Boolean;
function IsMemSQL: Boolean;
property ImageIndex: Integer read GetImageIndex;
function GetLibraries: TStringList;
function DefaultLibrary: String;
function DefaultPort: Integer;
function DefaultUsername: String;
@@ -1458,6 +1461,53 @@ function TConnectionParameters.DefaultLibrary: String;
end;


function TConnectionParameters.GetLibraries: TStringList;
var
rx: TRegExpr;
Dlls: TStringDynArray;
DllPath, DllFile: String;
FoundLibs, Providers: TStringList;
Provider: String;
begin
if not Assigned(FLibraries) then begin
FLibraries := TNetGroupLibs.Create;
end;

if not FLibraries.ContainsKey(NetTypeGroup) then begin
FoundLibs := TStringList.Create;
rx := TRegExpr.Create;
rx.ModifierI := True;
case NetTypeGroup of
ngMySQL: rx.Expression := '^lib(mysql|mariadb).*\.dll$';
ngMSSQL: rx.Expression := '^(MSOLEDBSQL|SQLOLEDB)$';
ngPgSQL: rx.Expression := '^libpq.*\.dll$';
end;
if NetTypeGroup in [ngMySQL, ngPgSQL] then begin
Dlls := TDirectory.GetFiles(ExtractFilePath(ParamStr(0)), '*.dll');
for DllPath in Dlls do begin
DllFile := ExtractFileName(DllPath);
if rx.Exec(DllFile) then begin
FoundLibs.Add(DllFile);
end;
end;
SetLength(Dlls, 0);
end else begin
Providers := TStringList.Create;
GetProviderNames(Providers);
for Provider in Providers do begin
if rx.Exec(Provider) then begin
FoundLibs.Add(Provider);
end;
end;
Providers.Free;
end;
rx.Free;
FLibraries.Add(NetTypeGroup, FoundLibs);
end;
FLibraries.TryGetValue(NetTypeGroup, Result);
end;


function TConnectionParameters.GetSessionName: String;
var
LastBackSlash: Integer;

0 comments on commit 3f0db16

Please sign in to comment.
You can’t perform that action at this time.