Zitat von
Nuclear-Ping:
Wie schon gesagt wird deine ganze Anwendung der Prozess sein, der den Zugriff verhindert. Vielleicht ist ZEOS oder dein SQlite Server auch nur so eingerichtet, dass sie die Datei so öffnen, dass kein geteilter Zugriff ermöglicht wird?
Daher der Vorschlag:
- Anwendung erzeugt Batch, startet Batch und beendet sich selber
- Batch:
--- Warten, bis Anwendung wirklich zu ist
--- REN[list=1] <newdb>
--- Anwendung.exe
- Anwendung löscht Batch
Danke für den Vorschlag, aber das ist mir zu umständlich für diese "einfache" Funktionalität. Dann laß ich lieber kein Umbenennen zu
Was ZEOS oder SQLite angeht: Mir ist dort keine Einstellung bekannt, die dieses Verhalten ändert.
...
Ich hab' jetzt mal ein Testprojekt aufgesetzt und siehe da es funktioniert (Ich war mir auch sicher das es vorher schonmal funktioniert hat). Stellt sich nun also die Frage warum funktioniert es nicht im eigentlichen Projekt???
Hier mal ein wenig Code und Hintergrund:
Ich öffne die Datenbank so:
Delphi-Quellcode:
function TMasterDB.OpenCatalog(AOwner: TComponent; ACatalogName: Widestring): TCatalog;
begin
Result := TCatalog.Create(AOwner, ACatalogName, '
', False);
if Assigned (Result)
then
FListedCatalogs.Add(Result);
// TObjectlist (zur Verwaltung der Datenbankknoten im VST
//(Anzeigeelemnent für DB und Datensätze)
end;
Definition TCatalog:
Delphi-Quellcode:
type
TCatalog =
class(TDataModule)
ConDB: TZConnection;
private
fCatID : Cardinal;
// MasterDB-ID
fCatName : WideString;
// Name (VST OnGetText)
fCatDescr : Widestring;
// Beschreibung (VST OnHint)
procedure SetCatalogID(
const Value: Cardinal);
procedure SetCatalogName(
const Value: Widestring);
procedure SetCatalogDescr(
const Value: Widestring);
function CreateCatalog: Boolean;
public
property CatalogID: Cardinal
read fCatID
write SetCatalogID;
property CatalogName: Widestring
read fCatName
write SetCatalogName;
property CatalogDescr: Widestring
read fCatDescr
write SetCatalogDescr;
constructor Create(AOwner: TComponent; AName: WideString; ADesc: WideString;
New: Boolean = True);
overload;
destructor Destroy;
override;
function Open: Boolean;
function Close: Boolean;
end;
{==============================================================================
Datenbankverbindung herstellen (Vorhandene DB)
===============================================================================}
function TCatalog.Open: Boolean;
begin
Result := False;
// Katalog öffnen (verbinden)
with conDB
do
try
Database := pyPathes.DBPath + fCatName + pyCatDBExt;
Connect;
Result := Connected;
finally
//
end;
end;
{==============================================================================
Datenbankverbindung schliessen
===============================================================================}
function TCatalog.Close: Boolean;
begin
ConDB.Disconnect;
Result :=
not ConDB.Connected;
end;
{==============================================================================
Anlegen Neue DB
===============================================================================}
function TCatalog.CreateCatalog: Boolean;
var
OK: Boolean;
begin
Result := false;
OK := False;
// Katalog anlegen
with conDB
do
try
Database := pyPathes.DBPath + fCatName + pyCatDBExt;
Connect;
with TZQuery.Create(
nil)
do
try
Connection := conDB;
// Tabelle Prog internas
SQL.Add('
CREATE TABLE [tblInternal] (');
SQL.Add('
[IntType] INTEGER NOT NULL DEFAULT 1,');
// MasterDB(0) oder Katalog(1) oder ReferenzDB(2)
SQL.Add('
[IntProgVersion] TEXT NOT NULL,');
// Erstellt mit Pythia Version
SQL.Add('
[IntDBVersion] TEXT NOT NULL,');
// Datenbankversion
SQL.Add('
[IntSQLVersion] TEXT NOT NULL,');
// Erstellt mit SQLite Version
SQL.Add('
[IntMagic] TEXT NOT NULL,');
// Magicnr der MasterDB (wird bei jedem ERZEUGEN der MasterDB neu angelegt)
SQL.Add('
[IntCatCreation] DATE NOT NULL,');
// Katalog erstellt am/um
SQL.Add('
[IntCatLastChange] DATE NOT NULL,');
// Letzte Änderungen im Katalog am/um
SQL.Add('
[IntCatDescr] TEXT NULL');
// Beschreibung des Katalogs
SQL.Add('
);');
//
// Erzeugung weiterer Tabellen
//
// Zeitpunkt der Erstellung und Versionsnr. eintragen
SQL.Add('
INSERT INTO tblInternal');
SQL.Add('
(IntProgVersion, IntDBVersion, IntSQLVersion, IntMagic, IntCatCreation, IntCatLastChange)');
SQL.Add('
VALUES (:AVersion, :ADBVersion, :ASQLVersion, :AMNr, DATETIME(''
now''
), DATETIME(''
now''
));');
ParamByName('
AVersion').Value := pyVersion.ProgVersion;
ParamByName('
ADBVersion').Value := pyVersion.DBVersion;
ParamByName('
ASQLVersion').Value := pyVersion.SQLiteVersion;
ParamByName('
AMNr').Value := pyVersion.MagicNo;
ExecSQL;
OK := True;
finally
Free;
end;
finally // ConDB
Disconnect;
end;
Result := OK;
// Alles gut gelaufen
end;
{==============================================================================
Erzeugen des Objektes und Anlegen des Katalogs
===============================================================================}
constructor TCatalog.Create(AOwner: TComponent; AName: WideString;
ADesc: WideString; New: Boolean);
begin
inherited Create(AOwner);
fCatName := AName;
fCatDescr := ADesc;
if not New
then
Open
else begin
CreateCatalog;
end;
end;
destructor TCatalog.Destroy;
begin
inherited Destroy;
end;
Hier die Routine zum Umbenennen:
Delphi-Quellcode:
function TMasterDB.RenameCatalog(ACatalog: TCatalog;
ANewCatName: Widestring): Boolean;
var
ACatID: Cardinal;
fo, fn: WideString;
begin
Result := False;
fo := pyPathes.DBPath + ACatalog.CatalogName + pyCatDBExt;
fn := pyPathes.DBPath + ANewCatName + pyCatDBExt;
// Umbenennen nur möglich wenn Verbindung getrennt
// (Öffnen erst wieder bei einer Aktion am Katalog)
if ACatalog.Close then begin
if WideRenameFile(fo, fn) then begin
// Datei erfolgreich umbenannt => auch in MasterDB umbenennen?
if RenameCatalogEntry(ACatalog.CatalogID, ANewCatName) then begin
ACatalog.CatalogName := ANewCatName;
end
else
WideRenameFile(fn, fo); // Umbenennen in MasterDB fehlgeschlagen -> zurück zum ursprünglichen Namen
end;
end;
end;
Die Datenbanken (Typ TCatalog) werden über eine Objektliste verwaltet. D.h. jedesmal wenn ein TCatalogObject erzeugt wird, wird es der Objektliste FlistedCatalogs hinzugefügt. Wie oben zu sehen ist, hat jedes TCatalog auch eine Eigenschaft CatalogName, die im VST zur Anzeige benutzt wird.
Vor der Umstellung gab es keine TObjectlist, sondern nur eine StringList mit den Namen der vorhandenen
DB's. Die Daten für das VST, die nun aus dem Object TCatalog kommen, kamen vorher aus Record's.
Liegt vielleicht hier der Hase im Pfeffer begraben??? Klappt es wegen der Objectlist nicht??? Müsste nur 'ne Kleinigkeit am Code / Design umgestellt werden ???
Ach ja, es gibt noch eine MasterDB, in der die Namen und eine ID pro
DB verwaltet werden. Aus diesem Modul kommt auch der Aufruf
Delphi-Quellcode:
RenameCatalog(ACatalog: TCatalog;
ANewCatName: Widestring)