Wrap Connection.Database in try..except blocks, so they don't throw access violations when the selected db was deleted from outside. Fixes issue #1445

This commit is contained in:
Ansgar Becker
2009-12-21 09:07:21 +00:00
parent 424ff3c8ab
commit 4501f070a9
2 changed files with 49 additions and 17 deletions

View File

@ -728,6 +728,7 @@ type
// Filter text per tab for filter panel
FilterTextVariables, FilterTextStatus, FilterTextProcessList, FilterTextCommandStats,
FilterTextDatabase, FilterTextData: WideString;
PreviousFocusedNode: PVirtualNode;
function GetParamValue(const paramChar: Char; const paramName:
string; var curIdx: Byte; out paramValue: string): Boolean;
procedure SetDelimiter(Value: String);
@ -4799,11 +4800,13 @@ procedure TMainForm.SetSelectedDatabase(db: WideString);
var
n: PVirtualNode;
begin
if db = '' then
n := DBtree.GetFirst
else
n := FindDBNode(db);
if Assigned(n) then begin
DBtree.Selected[n] := true;
DBtree.FocusedNode := n;
end else
if Assigned(n) then
SelectNode(DBtree, n)
else
raise Exception.Create('Database node ' + db + ' not found in tree.');
end;
@ -5976,12 +5979,27 @@ begin
0: ShowHost;
1: begin
newDb := Databases[Node.Index];
// Selecting a database can cause an SQL error if the db was deleted from outside. Select previous node in that case.
try
Connection.Database := newDb;
ShowDatabase( newDb );
except on E:Exception do begin
MessageDlg(E.Message, mtError, [mbOK], 0);
SelectNode(DBtree, PreviousFocusedNode);
Exit;
end;
end;
ShowDatabase(newDb);
end;
2: begin
newDb := Databases[Node.Parent.Index];
try
Connection.Database := newDb;
except on E:Exception do begin
MessageDlg(E.Message, mtError, [mbOK], 0);
SelectNode(DBtree, PreviousFocusedNode);
Exit;
end;
end;
newDbObject := SelectedTable.Text;
tabEditor.TabVisible := True;
tabData.TabVisible := SelectedTable.NodeType in [lntTable, lntView];
@ -6016,6 +6034,7 @@ begin
end;
end;
end;
PreviousFocusedNode := DBTree.FocusedNode;
if newDb <> '' then
LoadDatabaseProperties(newDb);
FixQueryTabCloseButtons;
@ -6025,7 +6044,7 @@ end;
procedure TMainForm.DatabaseChanged(Database: WideString);
begin
if (Database <> ActiveDatabase) and (Databases.IndexOf(Database) > -1) then
if (Database='') or (Databases.IndexOf(Database) > -1) then
ActiveDatabase := Database;
end;

View File

@ -323,9 +323,17 @@ begin
FServerStarted := FConnectionStarted - StrToIntDef(GetVar('SHOW STATUS LIKE ''Uptime''', 1), 1);
FServerVersionUntouched := mysql_get_server_info(FHandle);
DetectCapabilities;
if FDatabase <> '' then begin
tmpdb := FDatabase;
FDatabase := '';
SetDatabase(tmpdb);
try
Database := tmpdb;
except
// Trigger OnDatabaseChange event for <no db> if wanted db is not available
FDatabase := tmpdb;
Database := '';
end;
end;
end;
end
@ -404,9 +412,14 @@ end;
}
procedure TMySQLConnection.SetDatabase(Value: WideString);
begin
if (Value = '') or (Value = FDatabase) then
Exit;
if Value <> FDatabase then begin
if Value = '' then begin
FDatabase := Value;
if Assigned(FOnDatabaseChanged) then
FOnDatabaseChanged(Value);
end else
Query('USE '+QuoteIdent(Value), False);
end;
end;