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

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

View File

@ -323,9 +323,17 @@ begin
FServerStarted := FConnectionStarted - StrToIntDef(GetVar('SHOW STATUS LIKE ''Uptime''', 1), 1); FServerStarted := FConnectionStarted - StrToIntDef(GetVar('SHOW STATUS LIKE ''Uptime''', 1), 1);
FServerVersionUntouched := mysql_get_server_info(FHandle); FServerVersionUntouched := mysql_get_server_info(FHandle);
DetectCapabilities; DetectCapabilities;
tmpdb := FDatabase; if FDatabase <> '' then begin
FDatabase := ''; tmpdb := FDatabase;
SetDatabase(tmpdb); FDatabase := '';
try
Database := tmpdb;
except
// Trigger OnDatabaseChange event for <no db> if wanted db is not available
FDatabase := tmpdb;
Database := '';
end;
end;
end; end;
end end
@ -372,7 +380,7 @@ begin
raise Exception.Create(GetLastError); raise Exception.Create(GetLastError);
end else begin end else begin
// We must call mysql_store_result() + mysql_free_result() to unblock the connection // We must call mysql_store_result() + mysql_free_result() to unblock the connection
// See: http://dev.mysql.com/doc/refman/5.0/en/mysql-store-result.html // See: http://dev.mysql.com/doc/refman/5.0/en/mysql-store-result.html
FRowsAffected := mysql_affected_rows(FHandle); FRowsAffected := mysql_affected_rows(FHandle);
TimerStart := GetTickCount; TimerStart := GetTickCount;
Result := mysql_store_result(FHandle); Result := mysql_store_result(FHandle);
@ -404,9 +412,14 @@ end;
} }
procedure TMySQLConnection.SetDatabase(Value: WideString); procedure TMySQLConnection.SetDatabase(Value: WideString);
begin begin
if (Value = '') or (Value = FDatabase) then if Value <> FDatabase then begin
Exit; if Value = '' then begin
Query('USE '+QuoteIdent(Value), False); FDatabase := Value;
if Assigned(FOnDatabaseChanged) then
FOnDatabaseChanged(Value);
end else
Query('USE '+QuoteIdent(Value), False);
end;
end; end;