Page 1 of 1

GetTableNames refresh error

Posted: 27.06.2006, 14:02
by Cirunz
I've a problem with the GetTableNames function of the ZConnection.

I'm using firebird 1.5: after I've created some tables, if I use the GetTableNames function without disconnect and reconnect the ZConnection object, the newly created tables doesn't appears in the list.

On BDE I'm used to resolve a similar problem with the FlushSchemaCache method of the TDataBase object, did someone know what I've to do with ZeosLibs?

Posted: 28.06.2006, 13:01
by Terence
Its quite easy, but not implemented with out reconnecting.
If i get svn write rights i can commit ;)

Anyway, that is my unoptimized solution:

ZDbcMetaData is the object keeping meta cache which is filled on demand by using methods such GetTableNames.
ZDbcMetaData keeps for saving meta a hashmap. If value already exists (key for taklenames) cache is used, else sql live queried from db and cached. There is no listener to updates on shema changes , so if changed cache is oudated!
There is a virtual method "TZAbstractDatabaseMetadata.ClearCache()" which shall be implemented by inherting db specific classes and this method clear cache completly (e.g. also the sps or index metainf cache). Then if any meta inf getter method is called, eg. "GetTablesNames()" the cache is empty and the data is get live from db.

code (untested):

Connection.Connect;
Connection.GetTablesNames();
....change shema...
Connection.DbcConnection.ClearCache();
Connection.GetTablesNames();
Connection.DisConnect;

Better would be only to requery specific cache item (in your case tablespaces),
but that would require code change.

Hope it helps, i just coded that in mind,
no idea if it works.

Posted: 29.06.2006, 09:42
by mdaems
Terence,

I can't give you SVN commit rights, but can commit your changes to testing branch if you send them as a SVN patch file to testing branch. I know it's a workaround. I would say : give us a little proof that 'you're worth' the commit right and I'll try to convince Firmos to give it.
Can you do the changes and test them? My proposal : Change Clearcache() to accept an optional key. If the key is filled out you just clear the corresponding part of the cache. If adding a new method is easier you can add for instance ClearCachePartial. The keys are plain strings, so it could be implemented that all keys starting with XXX are removed. I think it can be changed for all databases at once by changing TZAbstractDatabaseMetadata, but I'm not sure.

Mark

Posted: 03.07.2006, 09:45
by Cirunz
Ok thanks for the answer Terence, I'll try it for the moment and hope to see the specialized clearcache in the future :)

Posted: 04.07.2006, 14:24
by Terence
You are also free to implement this feature and send us your modifications ;)

Posted: 08.07.2006, 17:49
by Terence
http://cforce.dnsalias.org/files/spec_clearcache.patch

Patch done.
You can do specific cache clear, like see below.
Code untested, please reply if it works.

uses ZDbcMetadata;

List :=TStringList.Create;
ZConnection.Connect;
ZConnection.GetTableNames('',List);

ZConnection.DbcConnection.GetMetadata.ClearCache(GetTablesMetaDataCacheKey( '','','',nil));
List.Clear;
ZConnection.GetTableNames('',List);
ZConnection.DisConnect;


-----------------------
method used to build cache key name for table spaces,
std is like used above, some dbs need extended context, catalog,shema or eg if u use pattern.
-----------------------
function GetTablesMetaDataCacheKey(Const Catalog:String;
Const SchemaPattern:String; Const TableNamePattern:String;const Types: TStringDynArray):String;

Posted: 10.07.2006, 21:17
by mdaems
This has been added to SVN testing branch. Go for it!!!

Posted: 13.07.2006, 11:54
by Cirunz
Uhm, I've tried this (On C++Builder 6), but the compiler sai it's not a member of IZConnection.

I see that DbcConnection is a _di_IZConnection, that is the Delphi interface for IZConnection. How it's correlated to ZDbcMetaData?

Posted: 13.07.2006, 17:02
by Cirunz
Ok I've tried to use the Metadata directly in this way:

Code: Select all

_di_IZDatabaseMetadata MD;

MD = zconmain->DbcConnection->GetMetadata();
MD->ClearCache();
And it worked :)