Fix some AVs around ListTables by reintroducing recently deleted connection event OnDBObjectsCleared. Required in cases where cache is cleared or refreshed (!) elsewhere and ListTables get repainted later.

This commit is contained in:
Ansgar Becker
2010-04-04 23:30:37 +00:00
parent 45ba97b13f
commit ea8574bc1a
2 changed files with 39 additions and 24 deletions

View File

@@ -802,6 +802,7 @@ type
procedure SaveQueryMemo(Tab: TQueryTab; Filename: String; OnlySelection: Boolean);
procedure UpdateFilterPanel(Sender: TObject);
procedure DatabaseChanged(Database: String);
procedure DBObjectsCleared(Database: String);
function GetBlobContent(Results: TMySQLQuery; Column: Integer): String;
procedure DoSearchReplace;
procedure UpdateLineCharPanel;
@@ -2413,6 +2414,7 @@ begin
ConnectionAttempt := TMySQLConnection.Create(Self);
ConnectionAttempt.OnLog := LogSQL;
ConnectionAttempt.OnDatabaseChanged := DatabaseChanged;
ConnectionAttempt.OnDBObjectsCleared := DBObjectsCleared;
ConnectionAttempt.ObjectNamesInSelectedDB := SynSQLSyn1.TableNames;
ConnectionAttempt.Parameters := Params;
try
@@ -5079,6 +5081,8 @@ var
begin
// Find currently selected database node in database tree,
// or the parent if a table is currently selected.
if csDestroying in ComponentState then
Exit;
s := DBtree.FocusedNode;
if not Assigned(s) then Result := ''
else case DBtree.GetNodeLevel(s) of
@@ -6575,6 +6579,13 @@ begin
end;
procedure TMainForm.DBObjectsCleared(Database: String);
begin
if (Database='') or (ActiveDatabase=Database) then
InvalidateVT(ListTables, VTREE_NOTLOADED, False);
end;
procedure TMainForm.DBtreeDblClick(Sender: TObject);
var
Node: PVirtualNode;
@@ -6621,7 +6632,7 @@ begin
// ReInit tree population
if DoResetTableCache then begin
Connection.ClearDbObjects;
Connection.ClearAllDbObjects;
FreeAndNil(AllDatabases);
end;
DBtree.ResetNode(DBTree.GetFirst);

View File

@@ -102,6 +102,7 @@ type
FLogPrefix: String;
FOnLog: TMySQLLogEvent;
FOnDatabaseChanged: TMySQLDatabaseEvent;
FOnDBObjectsCleared: TMySQLDatabaseEvent;
FRowsFound: Int64;
FRowsAffected: Int64;
FServerVersionUntouched: String;
@@ -153,7 +154,8 @@ type
function GetDBObjects(db: String; Refresh: Boolean=False): TDBObjectList;
function GetDBSize(db: String): Int64;
function DbObjectsCached(db: String): Boolean;
procedure ClearDbObjects(db: String='');
procedure ClearDbObjects(db: String);
procedure ClearAllDbObjects;
property Parameters: TConnectionParameters read FParameters write FParameters;
property ThreadId: Cardinal read GetThreadId;
property ConnectionUptime: Integer read GetConnectionUptime;
@@ -183,6 +185,7 @@ type
// Events
property OnLog: TMySQLLogEvent read FOnLog write FOnLog;
property OnDatabaseChanged: TMySQLDatabaseEvent read FOnDatabaseChanged write FOnDatabaseChanged;
property OnDBObjectsCleared: TMySQLDatabaseEvent read FOnDBObjectsCleared write FOnDBObjectsCleared;
end;
@@ -268,6 +271,7 @@ begin
FLastQueryNetworkDuration := 0;
FLogPrefix := '';
FIsUnicode := False;
FDBObjectLists := TStringList.Create;
FDBSizes := TStringList.Create;
end;
@@ -967,40 +971,42 @@ begin
FreeAndNil(FCharsetTable);
FreeAndNil(FTableEngines);
FreeAndNil(FInformationSchemaObjects);
ClearDbObjects;
ClearAllDbObjects;
FTableEngineDefault := '';
end;
procedure TMySQLConnection.ClearDbObjects(db: String='');
procedure TMySQLConnection.ClearDbObjects(db: String);
var
i, idx: Integer;
begin
// Free all cached database object lists, or, if db is passed, only that one
if not Assigned(FDBObjectLists) then
// Free cached database object list
i := FDBObjectLists.IndexOf(db);
if i = -1 then
Exit;
if db <> '' then begin
i := FDBObjectLists.IndexOf(db);
if i = -1 then
Exit;
TDBObjectList(FDBObjectLists.Objects[i]).Free;
FDBObjectLists.Delete(i);
idx := FDBSizes.IndexOfName(db);
if idx > -1 then
FDBSizes.Delete(idx);
end else begin
for i:=0 to FDBObjectLists.Count-1 do
TDBObjectList(FDBObjectLists.Objects[i]).Free;
FreeAndNil(FDBObjectLists);
FDBSizes.Clear;
end;
TDBObjectList(FDBObjectLists.Objects[i]).Free;
FDBObjectLists.Delete(i);
idx := FDBSizes.IndexOfName(db);
if idx > -1 then
FDBSizes.Delete(idx);
if Assigned(FOnDBObjectsCleared) then
FOnDBObjectsCleared(db);
end;
procedure TMySQLConnection.ClearAllDbObjects;
var
i: Integer;
begin
for i:=FDBObjectLists.Count-1 downto 0 do
ClearDbObjects(FDBObjectLists[i]);
end;
function TMySQLConnection.DbObjectsCached(db: String): Boolean;
begin
// Check if a table list is stored in cache
Result := Assigned(FDBObjectLists) and (FDBObjectLists.IndexOf(db) > -1);
Result := FDBObjectLists.IndexOf(db) > -1;
end;
@@ -1210,8 +1216,6 @@ begin
Result.Sort;
// Add list of objects in this database to cached list of all databases
if not Assigned(FDBObjectLists) then
FDBObjectLists := TStringList.Create;
FDBObjectLists.AddObject(db, Result);
FDBSizes.Values[db] := IntToStr(DBSize);