mirror of
https://github.com/HeidiSQL/HeidiSQL.git
synced 2025-08-06 18:24:26 +08:00
Introduce caching of collation table and table engines list in connection layer. Remove that stuff from main unit and automatically clear cached stuff on disconnection.
This commit is contained in:
@ -15,7 +15,6 @@ object CreateDatabaseForm: TCreateDatabaseForm
|
||||
Position = poOwnerFormCenter
|
||||
OnClose = FormClose
|
||||
OnCreate = FormCreate
|
||||
OnDestroy = FormDestroy
|
||||
OnShow = FormShow
|
||||
DesignSize = (
|
||||
317
|
||||
|
@ -18,7 +18,6 @@ type
|
||||
comboCollation: TComboBox;
|
||||
lblPreview: TLabel;
|
||||
SynMemoPreview: TSynMemo;
|
||||
procedure FormDestroy(Sender: TObject);
|
||||
procedure btnOKClick(Sender: TObject);
|
||||
procedure comboCharsetChange(Sender: TObject);
|
||||
procedure Modified(Sender: TObject);
|
||||
@ -29,7 +28,7 @@ type
|
||||
function GetCreateStatement: WideString;
|
||||
private
|
||||
{ Private declarations }
|
||||
dsCollations : TMySQLQuery;
|
||||
CollationTable: TMySQLQuery;
|
||||
defaultCharset : String;
|
||||
currentCollation : String;
|
||||
public
|
||||
@ -53,45 +52,11 @@ var
|
||||
charset: String;
|
||||
begin
|
||||
InheritFont(Font);
|
||||
|
||||
try
|
||||
dsCollations := Mainform.Connection.GetResults('SHOW COLLATION');
|
||||
// Detect servers default charset
|
||||
defaultCharset := Mainform.Connection.GetVar( 'SHOW VARIABLES LIKE '+esc('character_set_server'), 1 );
|
||||
except
|
||||
// Ignore it when the above statements don't work on pre 4.1 servers.
|
||||
// If the list(s) are nil, disable the combobox(es), so we create the db without charset.
|
||||
end;
|
||||
|
||||
// Create a list with charsets from collations dataset
|
||||
comboCharset.Enabled := dsCollations <> nil;
|
||||
lblCharset.Enabled := comboCharset.Enabled;
|
||||
if comboCharset.Enabled then
|
||||
begin
|
||||
comboCharset.Items.BeginUpdate;
|
||||
dsCollations.First;
|
||||
while not dsCollations.Eof do begin
|
||||
charset := dsCollations.Col('Charset');
|
||||
if comboCharset.Items.IndexOf(charset) = -1 then
|
||||
comboCharset.Items.Add(charset);
|
||||
dsCollations.Next;
|
||||
end;
|
||||
comboCharset.Items.EndUpdate;
|
||||
end;
|
||||
|
||||
comboCollation.Enabled := dsCollations <> nil;
|
||||
lblCollation.Enabled := comboCollation.Enabled;
|
||||
|
||||
// Setup SynMemoPreview
|
||||
SynMemoPreview.Highlighter := Mainform.SynSQLSyn1;
|
||||
end;
|
||||
|
||||
|
||||
procedure TCreateDatabaseForm.FormDestroy(Sender: TObject);
|
||||
begin
|
||||
FreeAndNil(dsCollations);
|
||||
end;
|
||||
|
||||
{**
|
||||
Form gets displayed: Set default values.
|
||||
}
|
||||
@ -100,8 +65,28 @@ var
|
||||
selectCharset,
|
||||
currentCharset,
|
||||
sql_create : WideString;
|
||||
Charset: String;
|
||||
colpos: Integer;
|
||||
begin
|
||||
CollationTable := Mainform.Connection.CollationTable;
|
||||
// Detect servers default charset
|
||||
defaultCharset := Mainform.Connection.GetVar( 'SHOW VARIABLES LIKE '+esc('character_set_server'), 1 );
|
||||
comboCharset.Enabled := Assigned(CollationTable);
|
||||
lblCharset.Enabled := comboCharset.Enabled;
|
||||
comboCollation.Enabled := comboCharset.Enabled;
|
||||
lblCollation.Enabled := comboCharset.Enabled;
|
||||
if comboCharset.Enabled then begin
|
||||
// Create a list with charsets from collations dataset
|
||||
comboCharset.Items.BeginUpdate;
|
||||
while not CollationTable.Eof do begin
|
||||
Charset := CollationTable.Col('Charset');
|
||||
if comboCharset.Items.IndexOf(Charset) = -1 then
|
||||
comboCharset.Items.Add(Charset);
|
||||
CollationTable.Next;
|
||||
end;
|
||||
comboCharset.Items.EndUpdate;
|
||||
end;
|
||||
|
||||
if modifyDB = '' then
|
||||
begin
|
||||
Caption := 'Create database ...';
|
||||
@ -157,21 +142,21 @@ var
|
||||
defaultCollation : String;
|
||||
begin
|
||||
// Abort if collations were not fetched successfully
|
||||
if dsCollations = nil then
|
||||
if not Assigned(CollationTable) then
|
||||
Exit;
|
||||
|
||||
// Fill pulldown with fitting collations
|
||||
comboCollation.Items.BeginUpdate;
|
||||
comboCollation.Items.Clear;
|
||||
dsCollations.First;
|
||||
while not dsCollations.Eof do begin
|
||||
if dsCollations.Col('Charset') = comboCharset.Text then
|
||||
CollationTable.First;
|
||||
while not CollationTable.Eof do begin
|
||||
if CollationTable.Col('Charset') = comboCharset.Text then
|
||||
begin
|
||||
comboCollation.Items.Add( dsCollations.Col('Collation'));
|
||||
if dsCollations.Col('Default') = 'Yes' then
|
||||
defaultCollation := dsCollations.Col('Collation');
|
||||
comboCollation.Items.Add(CollationTable.Col('Collation'));
|
||||
if CollationTable.Col('Default') = 'Yes' then
|
||||
defaultCollation := CollationTable.Col('Collation');
|
||||
end;
|
||||
dsCollations.Next;
|
||||
CollationTable.Next;
|
||||
end;
|
||||
|
||||
// Preselect default or current collation
|
||||
|
109
source/main.pas
109
source/main.pas
@ -708,9 +708,6 @@ type
|
||||
EditVariableForm : TfrmEditVariable;
|
||||
FileNameSessionLog : String;
|
||||
FileHandleSessionLog : Textfile;
|
||||
dsShowEngines,
|
||||
dsHaveEngines,
|
||||
dsCollations,
|
||||
FSelectedTableColumns,
|
||||
FSelectedTableKeys : TMySQLQuery;
|
||||
FilterPanelManuallyOpened : Boolean;
|
||||
@ -824,7 +821,6 @@ type
|
||||
procedure ActivateFileLogging;
|
||||
procedure DeactivateFileLogging;
|
||||
procedure TrimSQLLog;
|
||||
procedure TableEnginesCombo(var Combobox: TCombobox);
|
||||
function GetTreeNodeType(Tree: TBaseVirtualTree; Node: PVirtualNode): TListNodeType;
|
||||
function GetFocusedTreeNodeType: TListNodeType;
|
||||
procedure RefreshTree(DoResetTableCache: Boolean; SelectDatabase: WideString = '');
|
||||
@ -850,7 +846,6 @@ type
|
||||
function GetRegKeyTable: String;
|
||||
procedure SaveListSetup( List: TVirtualStringTree );
|
||||
procedure RestoreListSetup( List: TVirtualStringTree );
|
||||
function GetCollations(Items: TWideStrings = nil): TMySQLQuery;
|
||||
procedure SetEditorTabCaption(Editor: TFrame; ObjName: WideString);
|
||||
procedure ResetSelectedTableStuff;
|
||||
procedure SetWindowCaption;
|
||||
@ -1662,18 +1657,11 @@ begin
|
||||
ClearAllTableLists;
|
||||
FreeAndNil(AllDatabases);
|
||||
FreeAndNil(InformationSchemaTables);
|
||||
FreeAndNil(dsShowEngines);
|
||||
FreeAndNil(dsHaveEngines);
|
||||
FreeAndNil(dsCollations);
|
||||
FreeAndNil(FDataGridSelect);
|
||||
ResetSelectedTableStuff;
|
||||
SynMemoFilter.Clear;
|
||||
SetLength(FDataGridSort, 0);
|
||||
|
||||
// Free forms which use session based datasets, fx dsShowEngines
|
||||
FreeAndNil(TableEditor);
|
||||
FreeAndNil(CreateDatabaseForm);
|
||||
|
||||
// Closing connection
|
||||
if Assigned(Connection) then
|
||||
FreeAndNil(Connection);
|
||||
@ -5783,81 +5771,6 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
{**
|
||||
Fetch table engines from server
|
||||
Currently used in tbl_properties and createtable
|
||||
}
|
||||
procedure TMainForm.TableEnginesCombo(var Combobox: TCombobox);
|
||||
var
|
||||
engineName, defaultEngine, engineSupport : String;
|
||||
HaveEngineList : TStrings;
|
||||
begin
|
||||
Combobox.Items.BeginUpdate;
|
||||
Combobox.Items.Clear;
|
||||
|
||||
// Cache datasets
|
||||
if dsShowEngines = nil then begin
|
||||
FreeAndNil(dsShowEngines);
|
||||
try
|
||||
dsShowEngines := Connection.GetResults('SHOW ENGINES');
|
||||
except
|
||||
// Ignore errors on old servers
|
||||
end;
|
||||
end;
|
||||
if dsHaveEngines = nil then begin
|
||||
FreeAndNil(dsHaveEngines);
|
||||
dsHaveEngines := Connection.GetResults('SHOW VARIABLES LIKE ''have%''');
|
||||
end;
|
||||
|
||||
if Assigned(dsShowEngines) then begin
|
||||
dsShowEngines.First;
|
||||
while not dsShowEngines.Eof do begin
|
||||
engineName := dsShowEngines.Col('Engine');
|
||||
engineSupport := LowerCase(dsShowEngines.Col('Support'));
|
||||
// Add to dropdown if supported
|
||||
if engineSupport <> 'no' then
|
||||
Combobox.Items.Add(engineName);
|
||||
// Check if this is the default engine
|
||||
if engineSupport = 'default' then
|
||||
defaultEngine := engineName;
|
||||
dsShowEngines.Next;
|
||||
end;
|
||||
end
|
||||
else begin
|
||||
// Manually fetch available engine types by analysing have_* options
|
||||
// This is for servers below 4.1 or when the SHOW ENGINES statement has
|
||||
// failed for some other reason
|
||||
|
||||
// Add default engines which will not show in a have_* variable:
|
||||
Combobox.Items.CommaText := 'MyISAM,MRG_MyISAM,HEAP';
|
||||
defaultEngine := 'MyISAM';
|
||||
// Possible other engines:
|
||||
HaveEngineList := TStringList.Create;
|
||||
HaveEngineList.CommaText := 'ARCHIVE,BDB,BLACKHOLE,CSV,EXAMPLE,FEDERATED,INNODB,ISAM';
|
||||
dsHaveEngines.First;
|
||||
while not dsHaveEngines.Eof do begin
|
||||
engineName := copy(dsHaveEngines.Col(0), 6, Length(dsHaveEngines.Col(0)) );
|
||||
// Strip additional "_engine" suffix, fx from "have_blackhole_engine"
|
||||
if Pos('_', engineName) > 0 then
|
||||
engineName := copy(engineName, 0, Pos('_', engineName)-1);
|
||||
engineName := UpperCase(engineName);
|
||||
// Add engine to dropdown if it's a) in HaveEngineList and b) activated
|
||||
if (HaveEngineList.IndexOf(engineName) > -1)
|
||||
and (LowerCase(dsHaveEngines.Col(1)) = 'yes') then
|
||||
Combobox.Items.Add(engineName);
|
||||
dsHaveEngines.Next;
|
||||
end;
|
||||
end;
|
||||
|
||||
Combobox.Sorted := True;
|
||||
|
||||
// Select default
|
||||
Combobox.ItemIndex := Combobox.Items.IndexOf(defaultEngine);
|
||||
|
||||
Combobox.Items.EndUpdate;
|
||||
end;
|
||||
|
||||
|
||||
{**
|
||||
A row in the process list was selected. Fill SynMemoProcessView with
|
||||
the SQL of that row.
|
||||
@ -8215,28 +8128,6 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
function TMainform.GetCollations(Items: TWideStrings = nil): TMySQLQuery;
|
||||
begin
|
||||
// Return cached collation list, used in several places, e.g. table editor
|
||||
if dsCollations = nil then try
|
||||
dsCollations := Connection.GetResults('SHOW COLLATION');
|
||||
except
|
||||
// Ignore errors on old servers
|
||||
end;
|
||||
if Assigned(dsCollations) then begin
|
||||
dsCollations.First;
|
||||
if Assigned(Items) then begin
|
||||
while not dsCollations.Eof do begin
|
||||
Items.Add(dsCollations.Col('Collation'));
|
||||
dsCollations.Next;
|
||||
end;
|
||||
dsCollations.First;
|
||||
end;
|
||||
end;
|
||||
Result := dsCollations;
|
||||
end;
|
||||
|
||||
|
||||
procedure TMainForm.PlaceObjectEditor(Which: TListNodeType);
|
||||
var
|
||||
frm: TFrame;
|
||||
|
@ -83,6 +83,10 @@ type
|
||||
FServerVersionUntouched: String;
|
||||
FLastQueryStart, FLastQueryEnd: Cardinal;
|
||||
FIsUnicode: Boolean;
|
||||
FTableEngines: TStringList;
|
||||
FTableEngineDefault: String;
|
||||
FCollationTable: TMySQLQuery;
|
||||
FCollationsUnavailable: Boolean;
|
||||
function GetActive: Boolean;
|
||||
procedure SetActive(Value: Boolean);
|
||||
procedure SetDatabase(Value: WideString);
|
||||
@ -93,8 +97,12 @@ type
|
||||
function GetServerVersionStr: String;
|
||||
function GetServerVersionInt: Integer;
|
||||
function GetLastQueryDuration: Cardinal;
|
||||
function GetTableEngines: TStringList;
|
||||
function GetCollationTable: TMySQLQuery;
|
||||
function GetCollationList: TStringList;
|
||||
procedure Log(Category: TMySQLLogCategory; Msg: WideString);
|
||||
procedure DetectCapabilities;
|
||||
procedure ClearCache;
|
||||
public
|
||||
constructor Create(AOwner: TComponent); override;
|
||||
destructor Destroy; override;
|
||||
@ -119,6 +127,10 @@ type
|
||||
property RowsAffected: Int64 read FRowsAffected;
|
||||
property LastQueryDuration: Cardinal read GetLastQueryDuration;
|
||||
property IsUnicode: Boolean read FIsUnicode;
|
||||
property TableEngines: TStringList read GetTableEngines;
|
||||
property TableEngineDefault: String read FTableEngineDefault;
|
||||
property CollationTable: TMySQLQuery read GetCollationTable;
|
||||
property CollationList: TStringList read GetCollationList;
|
||||
published
|
||||
property Active: Boolean read GetActive write SetActive default False;
|
||||
property Hostname: String read FHostname write FHostname;
|
||||
@ -196,6 +208,7 @@ end;
|
||||
destructor TMySQLConnection.Destroy;
|
||||
begin
|
||||
if Active then Active := False;
|
||||
ClearCache;
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
@ -290,8 +303,10 @@ end;
|
||||
|
||||
function TMySQLConnection.GetActive: Boolean;
|
||||
begin
|
||||
if FActive and (mysql_ping(FHandle) <> 0) then
|
||||
if FActive and (mysql_ping(FHandle) <> 0) then begin
|
||||
Active := False;
|
||||
ClearCache;
|
||||
end;
|
||||
Result := FActive;
|
||||
end;
|
||||
|
||||
@ -616,6 +631,93 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
function TMySQLConnection.GetTableEngines: TStringList;
|
||||
var
|
||||
ShowEngines, HaveEngines: TMySQLQuery;
|
||||
engineName, engineSupport: String;
|
||||
PossibleEngines: TStringList;
|
||||
begin
|
||||
if not Assigned(FTableEngines) then begin
|
||||
FTableEngines := TStringList.Create;
|
||||
try
|
||||
ShowEngines := GetResults('SHOW ENGINES');
|
||||
while not ShowEngines.Eof do begin
|
||||
engineName := ShowEngines.Col('Engine');
|
||||
engineSupport := LowerCase(ShowEngines.Col('Support'));
|
||||
// Add to dropdown if supported
|
||||
if engineSupport <> 'no' then
|
||||
FTableEngines.Add(engineName);
|
||||
// Check if this is the default engine
|
||||
if engineSupport = 'default' then
|
||||
FTableEngineDefault := engineName;
|
||||
ShowEngines.Next;
|
||||
end;
|
||||
except
|
||||
// Ignore errors on old servers and try a fallback:
|
||||
// Manually fetch available engine types by analysing have_* options
|
||||
// This is for servers below 4.1 or when the SHOW ENGINES statement has
|
||||
// failed for some other reason
|
||||
HaveEngines := GetResults('SHOW VARIABLES LIKE ''have%''');
|
||||
// Add default engines which will not show in a have_* variable:
|
||||
FTableEngines.CommaText := 'MyISAM,MRG_MyISAM,HEAP';
|
||||
FTableEngineDefault := 'MyISAM';
|
||||
// Possible other engines:
|
||||
PossibleEngines := TStringList.Create;
|
||||
PossibleEngines.CommaText := 'ARCHIVE,BDB,BLACKHOLE,CSV,EXAMPLE,FEDERATED,INNODB,ISAM';
|
||||
while not HaveEngines.Eof do begin
|
||||
engineName := copy(HaveEngines.Col(0), 6, Length(HaveEngines.Col(0)));
|
||||
// Strip additional "_engine" suffix, fx from "have_blackhole_engine"
|
||||
if Pos('_', engineName) > 0 then
|
||||
engineName := copy(engineName, 0, Pos('_', engineName)-1);
|
||||
engineName := UpperCase(engineName);
|
||||
// Add engine to list if it's a) in HaveEngineList and b) activated
|
||||
if (PossibleEngines.IndexOf(engineName) > -1)
|
||||
and (LowerCase(HaveEngines.Col(1)) = 'yes') then
|
||||
FTableEngines.Add(engineName);
|
||||
HaveEngines.Next;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
Result := FTableEngines;
|
||||
end;
|
||||
|
||||
|
||||
function TMySQLConnection.GetCollationTable: TMySQLQuery;
|
||||
begin
|
||||
if (not Assigned(FCollationTable)) and (not FCollationsUnavailable) then try
|
||||
FCollationTable := GetResults('SHOW COLLATION');
|
||||
except
|
||||
// Ignore errors on old servers
|
||||
FCollationsUnavailable := True;
|
||||
end;
|
||||
if Assigned(FCollationTable) then
|
||||
FCollationTable.First;
|
||||
Result := FCollationTable;
|
||||
end;
|
||||
|
||||
|
||||
function TMySQLConnection.GetCollationList: TStringList;
|
||||
var
|
||||
c: TMySQLQuery;
|
||||
begin
|
||||
c := CollationTable;
|
||||
Result := TStringList.Create;
|
||||
if not FCollationsUnavailable then while not c.Eof do begin
|
||||
Result.Add(c.Col('Collation'));
|
||||
c.Next;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure TMySQLConnection.ClearCache;
|
||||
begin
|
||||
// Free cached lists and results. Called when the connection was closed and/or destroyed
|
||||
FreeAndNil(FCollationTable);
|
||||
FCollationsUnavailable := False;
|
||||
FreeAndNil(FTableEngines);
|
||||
FTableEngineDefault := '';
|
||||
end;
|
||||
|
||||
|
||||
|
||||
{ TMySQLQuery }
|
||||
|
@ -343,7 +343,7 @@ object frmTableEditor: TfrmTableEditor
|
||||
TabOrder = 0
|
||||
OnChange = editNumEditChange
|
||||
end
|
||||
object comboCollation: TTntComboBox
|
||||
object comboCollation: TComboBox
|
||||
Left = 354
|
||||
Top = 3
|
||||
Width = 119
|
||||
|
@ -36,7 +36,7 @@ type
|
||||
memoUnionTables: TTntMemo;
|
||||
comboInsertMethod: TComboBox;
|
||||
lblCollation: TLabel;
|
||||
comboCollation: TTNTComboBox;
|
||||
comboCollation: TComboBox;
|
||||
lblEngine: TLabel;
|
||||
comboEngine: TComboBox;
|
||||
treeIndexes: TVirtualStringTree;
|
||||
@ -302,9 +302,9 @@ begin
|
||||
// Start with "basic" tab activated when just called
|
||||
if FAlterTableName <> AlterTableName then
|
||||
PageControlMain.ActivePage := tabBasic;
|
||||
Mainform.TableEnginesCombo(comboEngine);
|
||||
comboCollation.Items.Clear;
|
||||
Mainform.GetCollations(comboCollation.Items);
|
||||
comboEngine.Items := Mainform.Connection.TableEngines;
|
||||
comboEngine.ItemIndex := comboEngine.Items.IndexOf(Mainform.Connection.TableEngineDefault);
|
||||
comboCollation.Items := Mainform.Connection.CollationList;
|
||||
FAlterTableName := AlterTableName;
|
||||
listColumns.BeginUpdate;
|
||||
FColumns.Clear;
|
||||
@ -688,8 +688,8 @@ begin
|
||||
if comboInsertMethod.Enabled and (comboInsertMethod.Tag = ModifiedFlag) and (comboInsertMethod.Text <> '') then
|
||||
Specs.Add('INSERT_METHOD='+comboInsertMethod.Text);
|
||||
if chkCharsetConvert.Checked then begin
|
||||
Results := Mainform.GetCollations;
|
||||
while not Results.Eof do begin
|
||||
Results := Mainform.Connection.CollationTable;
|
||||
if Assigned(Results) then while not Results.Eof do begin
|
||||
if Results.Col('Collation') = comboCollation.Text then begin
|
||||
Specs.Add('CONVERT TO CHARSET '+Results.Col('Charset'));
|
||||
break;
|
||||
@ -1409,7 +1409,7 @@ begin
|
||||
8: begin // Collation pulldown
|
||||
EnumEditor := TEnumEditorLink.Create(VT);
|
||||
EnumEditor.ValueList := TWideStringList.Create;
|
||||
Mainform.GetCollations(EnumEditor.ValueList);
|
||||
EnumEditor.ValueList.Text := Mainform.Connection.CollationList.Text;
|
||||
EnumEditor.ValueList.Insert(0, '');
|
||||
EditLink := EnumEditor;
|
||||
end;
|
||||
|
Reference in New Issue
Block a user