Einzelnen Beitrag anzeigen

OG Karotte
(Gast)

n/a Beiträge
 
#9

Re: Datenbank per Code umbenennen

  Alt 12. Mai 2008, 11:20
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)
  Mit Zitat antworten Zitat