Files
lazarus-ccr/components/flashfiler/sourcelaz/explorer/uentity.pas

1178 lines
31 KiB
ObjectPascal
Raw Normal View History

{*********************************************************}
{* Classes for server, database, and table lists *}
{*********************************************************}
(* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is TurboPower FlashFiler
*
* The Initial Developer of the Original Code is
* TurboPower Software
*
* Portions created by the Initial Developer are Copyright (C) 1996-2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** *)
{$I ffdefine.inc}
unit uentity;
interface
uses
Classes,
Controls,
Consts,
DB,
Dialogs,
Forms,
SysUtils,
Windows,
ffclbase,
ffllbase,
fflldict,
ffllprot,
ffclreng,
ffdb,
fflllgcy,
fflllog,
fflogdlg,
ffsrbde;
type
TffexpSession = class(TffSession)
protected
procedure FFELogin(aSource : TObject;
var aUserName : TffName;
var aPassword : TffName;
var aResult : Boolean);
public
ffePassword : string;
ffeUserName : string;
public
constructor Create(AOwner : TComponent); override;
end;
TffexpDatabase = class(TffDatabase);
TffexpTable = class(TffTable);
type
TffeEntityType = (etServer, etDatabase, etTable);
TffeServerList = class;
TffeDatabaseList = class;
TffeDatabaseItem = class;
TffeTableList = class;
TffeTableItem = class;
TffeEntityItem = class(TffListItem)
protected { private}
FEntityType: TffeEntityType;
FEntityName: TffNetAddress;
FEntitySerialKey: DWORD;
public
constructor Create(aEntityType: TffeEntityType; aEntityName: TffShStr);
function Compare(aKey : Pointer): Integer; override;
{-compare Self's key to aKey: return <0 if aKey < Self's, 0 if
equal, >0 otherwise}
function Key: Pointer; override;
{-return a pointer to this item's key: it'll be a pointer to a
shortstring}
property EntityType: TffeEntityType
read FEntityType;
property EntityName: TffNetAddress
read FEntityName;
property EntitySerialKey: DWORD
read FEntitySerialKey;
end;
TffeEntityList = class(TffList)
protected
function GetItem(aIndex: LongInt): TffeEntityItem;
public
function IndexOfName(const aName: TffShStr): LongInt;
{-return the index of the entry whose name is given}
function IndexOfSerialKey(aSerialKey: DWORD): LongInt;
{-return the list index for a given entity identified by its
serial key (the outline control keeps track of entities
by the serial key) }
property Items[aIndex: LongInt]: TffeEntityItem
read GetItem;
end;
TffeServerNotifyEvent = procedure(aServerIndex: LongInt) of object;
TffeServerItem = class(TffeEntityItem)
protected
FClient : TffClient;
FDatabaseList: TffeDatabaseList;
FProtocol : TffProtocolType;
FServerEngine : TffRemoteServerEngine;
FSession : TffexpSession;
FTransport : TffLegacyTransport;
procedure siCheckAttached;
function siGetDatabaseCount : longInt;
function siGetDatabase(const anIndex : longInt) : TffeDatabaseItem;
public
ServerID: LongInt;
Attached: Boolean;
constructor Create(aServerName: TffNetAddress;
aProtocol : TffProtocolType);
destructor Destroy; override;
procedure AddAlias(aAlias : TffName;
aPath : TffPath;
aCheckSpace : Boolean); {!!.11}
function AddDatabase(aAlias : TffName) : TffeDatabaseItem;
function Attach(aLog : TffBaseLog): TffResult;
procedure Detach;
procedure DropDatabase(aDatabaseName : TffName);
procedure GetAliases(aList : TStrings);
function GetAutoInc(aTable : TffTable) : TffWord32;
procedure LoadDatabases;
property DatabaseCount : longInt read siGetDatabaseCount;
property Databases[const anIndex : longInt] : TffeDatabaseItem
read siGetDatabase;
property ServerName: TffNetAddress read FEntityName;
property Session : TffexpSession read FSession;
property Protocol : TffProtocolType read FProtocol; {!!.10}
property Client : TffClient read FClient; {!!.11}
end;
TffeServerList = class(TffeEntityList)
protected {private}
FClient : TffClient;
FOnAttach: TffeServerNotifyEvent;
FOnDetach: TffeServerNotifyEvent;
FServerEngine : TffRemoteServerEngine;
FTransport : TffLegacyTransport;
function GetItem(aIndex: LongInt): TffeServerItem;
public
constructor Create(aLog : TffBaseLog);
destructor Destroy; override;
procedure DetachAll;
function Insert(aItem: TffeServerItem): Boolean;
procedure Load;
procedure LoadRegisteredServers;
property Items[aIndex: LongInt]: TffeServerItem
read GetItem;
property OnAttach: TffeServerNotifyEvent
read FOnAttach write FOnAttach;
property OnDetach: TffeServerNotifyEvent
read FOnDetach write FOnDetach;
end;
TffeDatabaseItem = class(TffeEntityItem)
protected
FDatabase : TffexpDatabase;
FServer : TffeServerItem;
FTableList : TffeTableList;
diParentList: TffeDatabaseList;
function diGetIsOpen: Boolean;
function diGetServer: TffeServerItem;
function diGetTable(const anIndex : longInt) : TffeTableItem;
function diGetTableCount : longInt;
public
DatabaseID: LongInt; { FF internal DB Identifier }
constructor Create(aServer : TffeServerItem; aAliasName: TffName);
destructor Destroy; override;
procedure Close;
function AddTable(const aTableName : TffTableName) : longInt;
procedure CreateTable(const aTableName: TffTableName; aDict: TffDataDictionary);
procedure DropTable(const anIndex : longInt);
{ Drop the specified table from the list of tables. }
procedure GetTableNames(Tables: TStrings);
function IndexOf(aTable : TffeTableItem) : longInt;
procedure LoadTables;
procedure Open;
procedure Rename(aNewName: TffNetAddress);
property Database : TffexpDatabase read FDatabase;
property DatabaseName: TffNetAddress read FEntityName;
property IsOpen: Boolean read diGetIsOpen;
property Server: TffeServerItem read diGetServer;
property TableCount : longInt read diGetTableCount;
property Tables[const anIndex : longInt] : TffeTableItem
read diGetTable;
end;
TffeDatabaseList = class(TffeEntityList)
protected
FServer : TffeServerItem;
function GetItem(aIndex: LongInt): TffeDatabaseItem;
public
constructor Create(aServer : TffeServerItem);
destructor Destroy; override;
function Add(const aDatabaseName: TffName): TffeDatabaseItem;
procedure DropDatabase(aIndex: LongInt);
function Insert(aItem: TffeDatabaseItem): Boolean;
procedure Load;
{ Load the aliases for the server. }
property Items[aIndex: LongInt]: TffeDatabaseItem
read GetItem;
end;
TffeTableItem = class(TffeEntityItem)
protected {private}
FParent : TffeDatabaseItem;
protected
tiParentList: TffeTableList;
procedure AfterOpenEvent(aDataset: TDataset);
function GetDatabase: TffeDatabaseItem;
function GetDictionary: TffDataDictionary;
function GetRebuilding: Boolean;
function GetRecordCount: TffWord32;
function GetServer: TffeServerItem;
public
Table: TffexpTable;
DatabaseIndex: LongInt;
CursorID: LongInt;
TaskID: LongInt;
constructor Create(aDatabase : TffeDatabaseItem; aTableName: TffName);
destructor Destroy; override;
procedure CheckRebuildStatus(var aCompleted: Boolean;
var aStatus: TffRebuildStatus);
function GetAutoInc : TffWord32;
procedure Pack;
procedure Reindex(aIndexNum: Integer);
procedure Rename(aNewTableName: TffName);
procedure Restructure(aDictionary: TffDataDictionary; aFieldMap: TStrings);
procedure SetAutoIncSeed(aValue : LongInt);
procedure Truncate;
procedure CopyRecords(aSrcTable : TffDataSet; aCopyBLOBs : Boolean); {!!.10}
property Database: TffeDatabaseItem
read GetDatabase;
property Dictionary: TffDataDictionary
read GetDictionary;
property Rebuilding: Boolean
read GetRebuilding;
property RecordCount: TffWord32
read GetRecordCount;
property Server: TffeServerItem
read GetServer;
property TableName: TffNetAddress
read FEntityName;
end;
TffeTableList = class(TffeEntityList)
protected
FDatabase : TffeDatabaseItem;
function GetItem(aIndex: LongInt): TffeTableItem;
public
constructor Create(aDatabase : TffeDatabaseItem);
destructor Destroy; override;
function Add(const aTableName: TffName): longInt;
procedure DropTable(aIndex: LongInt);
function Insert(aItem: TffeTableItem): Boolean;
procedure Load;
property Items[aIndex: LongInt]: TffeTableItem
read GetItem;
end;
const
ffcConnectTimeout : longInt = 2000;
{-Number of milliseconds we will wait for servers to respond to our
broadcast. }
implementation
uses
ffclcfg,
ffdbbase,
ffllcomm,
ffllcomp,
fflleng,
ubase,
uconsts,
{$IFDEF DCC6ORLATER} {!!.03}
RTLConsts, {!!.03}
{$ENDIF} {!!.03}
uconfig;
const
ffcLogName = 'ffe.log';
ffcDatabaseClosed = 'Cannot perform this operation on a closed database';
var
NextEntitySerialKey: DWORD;
{=====TffeEntityItem methods=====}
constructor TffeEntityItem.Create(aEntityType: TffeEntityType; aEntityName: TffShStr);
begin
inherited Create;
FEntityType := aEntityType;
FEntityName := aEntityName;
FEntitySerialKey := NextEntitySerialKey;
Inc(NextEntitySerialKey);
end;
function TffeEntityItem.Compare(aKey: Pointer): Integer;
begin
Result := FFCmpShStr(PffShStr(aKey)^, EntityName, 255);
end;
function TffeEntityItem.Key: Pointer;
begin
Result := @FEntityName;
end;
{=====TffeEntityList methods=====}
function TffeEntityList.GetItem(aIndex: LongInt): TffeEntityItem;
begin
if (aIndex < 0) or (aIndex >= Count) then
raise EListError.Create(SListIndexError);
Result := TffeEntityItem(inherited Items[aIndex]);
end;
function TffeEntityList.IndexOfName(const aName: TffShStr): LongInt;
begin
for Result := 0 to Count - 1 do
if Items[Result].EntityName = aName then Exit;
Result := -1;
end;
function TffeEntityList.IndexOfSerialKey(aSerialKey: DWORD): LongInt;
begin
for Result := 0 to Count - 1 do
if Items[Result].EntitySerialKey = aSerialKey then Exit;
Result := -1;
end;
{===TffeServerItem===================================================}
constructor TffeServerItem.Create(aServerName: TffNetAddress;
aProtocol : TffProtocolType);
begin
inherited Create(etServer, FFShStrTrim(aServerName));
FDatabaseList := TffeDatabaseList.Create(Self);
FProtocol := aProtocol;
Attached := False;
end;
{--------}
destructor TffeServerItem.Destroy;
begin
Detach;
FDatabaseList.Free;
inherited Destroy;
end;
{--------}
procedure TffeServerItem.AddAlias(aAlias : TffName;
aPath : TffPath;
aCheckSpace : Boolean); {!!.11}
begin
FSession.AddAlias(aAlias, aPath, aCheckSpace); {!!.11}
end;
{--------}
function TffeServerItem.AddDatabase(aAlias : TffName) : TffeDatabaseItem;
begin
Result := FDatabaseList.Add(aAlias);
end;
{--------}
function TffeServerItem.Attach(aLog : TffBaseLog): TffResult;
var
OldCursor: TCursor;
begin
Result := DBIERR_NONE;
{ If we're already attached, then we don't need to do anything }
if Attached then Exit;
OldCursor := Screen.Cursor;
Screen.Cursor := crHourglass;
try
if not assigned(FTransport) then
FTransport := TffLegacyTransport.Create(nil);
with FTransport do begin
Mode := fftmSend;
Enabled := True;
Protocol := FProtocol;
EventLog := aLog;
EventLogEnabled := True;
EventLogOptions := [fftpLogErrors];
ServerName := FEntityName;
end;
if not assigned(FServerEngine) then
FServerEngine := TffRemoteServerEngine.Create(nil);
with FServerEngine do begin
Transport := FTransport;
end;
if not assigned(FClient) then
FClient := TffClient.Create(nil);
with FClient do begin
TimeOut := Config.DefaultTimeout; {!!.11}
ServerEngine := FServerEngine;
AutoClientName := True;
Active := True;
end;
if not assigned(FSession) then
FSession := TffexpSession.Create(nil);
with FSession do begin
ClientName := FClient.ClientName;
AutoSessionName := True;
Active := True;
end;
Attached := FSession.Active;
if Attached then begin
{ Automatically load up all the databases for this server }
if not assigned(FDatabaseList) then
FDatabaseList := TffeDatabaseList.Create(Self);
FDatabaseList.Load;
{ Run the event-handler if any }
with ServerList do
if Assigned(FOnAttach) then
FOnAttach(Index(FEntityName));
end;
finally;
Screen.Cursor := OldCursor;
end;
end;
{--------}
procedure TffeServerItem.Detach;
var
S: TffNetAddress;
begin
if assigned(FDatabaseList) then begin
FDatabaseList.Free;
FDatabaseList := nil;
end;
if assigned(FSession) then begin
FSession.Active := False;
FSession.Free;
FSession := nil;
end;
if assigned(FClient) then begin
FClient.Active := False;
FClient.Free;
FClient := nil;
end;
if assigned(FTransport) then begin
FTransport.State := ffesInactive;
FTransport.Free;
FTransport := nil;
end;
if assigned(FServerEngine) then begin
FServerEngine.Free;
FServerEngine := nil;
end;
Attached := False;
S := ServerName;
with ServerList do
if Assigned(FOnDetach) then
FOnDetach(Index(S));
end;
{--------}
procedure TffeServerItem.DropDatabase(aDatabaseName : TffName);
begin
siCheckAttached;
FDatabaseList.DropDatabase(FDatabaseList.IndexOfName(aDatabaseName));
end;
{--------}
procedure TffeServerItem.GetAliases(aList : TStrings);
begin
siCheckAttached;
FSession.GetAliasNames(aList);
end;
{--------}
function TffeServerItem.GetAutoInc(aTable : TffTable) : TffWord32;
begin
Result := 1;
FServerEngine.TableGetAutoInc(aTable.CursorID, Result);
end;
{--------}
procedure TffeServerItem.LoadDatabases;
begin
siCheckAttached;
FDatabaseList.Load;
end;
{--------}
procedure TffeServerItem.siCheckAttached;
begin
if not Attached then
Attach(nil);
end;
{--------}
function TffeServerItem.siGetDatabaseCount : longInt;
begin
Result := FDatabaseList.Count;
end;
{--------}
function TffeServerItem.siGetDatabase(const anIndex : Longint)
: TffeDatabaseItem;
begin
Result := TffeDatabaseItem(FDatabaseList[anIndex]);
end;
{====================================================================}
{===TffeServerList===================================================}
constructor TffeServerList.Create(aLog : TffBaseLog);
begin
inherited Create;
Sorted := True;
{ The transport will be left inactive. Its sole purpose is to
broadcast for servers using the protocol identified in the registry. }
FTransport := TffLegacyTransport.Create(nil);
with FTransport do begin
Mode := fftmSend;
Enabled := True;
Protocol := ptRegistry;
EventLog := aLog;
EventLogEnabled := True;
EventLogOptions := [fftpLogErrors];
Name := 'ffeTransport';
end;
FServerEngine := TffRemoteServerEngine.Create(nil);
with FServerEngine do begin
Transport := FTransport;
Name := 'ffeServerEngine';
end;
FClient := TffClient.Create(nil);
with FClient do begin
ServerEngine := FServerEngine;
Name := 'ffeClient';
ClientName := Name;
Timeout := ffcConnectTimeout;
Active := True;
end;
end;
{--------}
destructor TffeServerList.Destroy;
begin
Empty;
FClient.Active := False;
FClient.Free;
FServerEngine.Free;
FTransport.State := ffesInactive;
FTransport.Free;
inherited Destroy;
end;
{--------}
procedure TffeServerList.DetachAll;
var
I: Integer;
begin
for I := 0 to Count - 1 do
with Items[I] do
if Attached then Detach;
end;
{--------}
function TffeServerList.Insert(aItem: TffeServerItem): Boolean;
begin
Result := inherited Insert(aItem);
end;
{--------}
function TffeServerList.GetItem(aIndex: LongInt): TffeServerItem;
begin
Result := TffeServerItem(inherited Items[aIndex]);
end;
{--------}
procedure TffeServerList.Load;
var
Servers: TStringList;
I: Integer;
tryProt: TffProtocolType; {!!.10}
function ServerRegistered(const ServerName : string) : Boolean; {begin !!.06}
var
Idx : Integer;
begin
Result := False;
with Config do
for Idx := 0 to Pred(RegisteredServers.Count) do
if FFAnsiCompareText(ServerName, RegisteredServers[Idx]) = 0 then begin {!!.10}
Result := True;
Exit;
end;
end; {end !!.06}
begin
Empty;
// if not (Config.Protocol = TffSingleUserProtocol) then {!!.06}
LoadRegisteredServers;
{Begin !!.07}
{ added loop to try all protocols. we no longer let the user
select protocol, but instead list all servers on all protocols. }
{ Broadcast for currently active servers }
Servers := TStringList.Create;
try
for tryProt := ptSingleUser to ptIPXSPX do begin
try
FTransport.Enabled := False;
FTransport.Protocol := tryProt;
FClient.GetServerNames(Servers);
for I := 0 to Servers.Count - 1 do
if not ServerRegistered(Servers[I]) then {!!.06}
Insert(TffeServerItem.Create(Servers[I], tryProt));
except
{ swallow all errors. assume that the particular protocol failed. }
end;
end;
{End !!.07}
finally
Servers.Free;
end;
end;
{--------}
procedure TffeServerList.LoadRegisteredServers;
var
I: Integer;
begin
with Config.RegisteredServers do
for I := 0 to Count - 1 do
Self.Insert(TffeServerItem.Create(Strings[I], ptTCPIP)); {!!.10} {changed protocol type}
end;
{=====================================================================}
{== TffeDatabaseItem =================================================}
constructor TffeDatabaseItem.Create(aServer : TffeServerItem;
aAliasName : TffName);
begin
inherited Create(etDatabase, aAliasName);
FServer := aServer;
DatabaseID := -1;
diParentList := nil;
FDatabase := TffexpDatabase.Create(nil);
FTableList := TffeTableList.Create(Self);
with FDatabase do begin
DatabaseName := 'exp' + aAliasName;
SessionName := aServer.Session.SessionName;
AliasName := aAliasName;
end;
end;
{--------}
destructor TffeDatabaseItem.Destroy;
begin
if IsOpen then Close;
FTableList.Free;
FDatabase.Free;
inherited Destroy;
end;
{--------}
procedure TffeDatabaseItem.Close;
begin
FDatabase.Connected := False;
end;
{--------}
function TffeDatabaseItem.AddTable(const aTableName : TffTableName)
: Longint;
begin
Result := FTableList.Add(aTableName);
end;
{--------}
procedure TffeDatabaseItem.CreateTable(const aTableName : TffTableName;
aDict : TffDataDictionary);
begin
if not IsOpen then
Open;
Check(FDatabase.CreateTable(False, aTableName, aDict));
end;
{--------}
procedure TffeDatabaseItem.DropTable(const anIndex : longInt);
begin
FTableList.DropTable(anIndex);
end;
{--------}
function TffeDatabaseItem.diGetIsOpen: Boolean;
begin
Result := FDatabase.Connected;
end;
{--------}
function TffeDatabaseItem.diGetServer: TffeServerItem;
begin
Result := FServer;
end;
{--------}
function TffeDatabaseItem.diGetTable(const anIndex : longInt) : TffeTableItem;
begin
Result := TffeTableItem(FTableList[anIndex]);
end;
{--------}
function TffeDatabaseItem.diGetTableCount : longInt;
begin
Result := FTableList.Count;
end;
{--------}
procedure TffeDatabaseItem.GetTableNames(Tables: TStrings);
begin
if Tables is TStringList then
TStringList(Tables).Sorted := True;
FDatabase.GetTableNames(Tables);
end;
{--------}
function TffeDatabaseItem.IndexOf(aTable : TffeTableItem) : longInt;
begin
Result := FTableList.IndexOfName(aTable.TableName);
end;
{--------}
procedure TffeDatabaseItem.LoadTables;
{ Find all the tables in the database and add to the table list. }
var
Tables: TStringList;
I: Integer;
begin
Tables := TStringList.Create;
try
FTableList.Empty;
// try
FDatabase.GetTableNames(Tables);
for I := 0 to Tables.Count - 1 do
FTableList.Add(Tables[I]);
{ except
on EffDatabaseError do
{do nothing}
{ else
raise;
end;}
finally
Tables.Free;
end;
end;
{--------}
procedure TffeDatabaseItem.Open;
begin
FDatabase.Connected := True;
end;
{--------}
procedure TffeDatabaseItem.Rename(aNewName: TffNetAddress);
begin
FDatabase.Close;
Check(FServer.Session.ModifyAlias(FEntityName, aNewName, '', False)); {!!.11}
FEntityName := aNewName;
end;
{=====================================================================}
{== TffeDatabaseList =================================================}
constructor TffeDatabaseList.Create(aServer : TffeServerItem);
begin
inherited Create;
FServer := aServer;
Sorted := False;
end;
{--------}
destructor TffeDatabaseList.Destroy;
begin
{ Close all databases. }
Empty;
inherited Destroy;
end;
{--------}
function TffeDatabaseList.Add(const aDatabaseName : TffName)
: TffeDatabaseItem;
begin
Result := TffeDatabaseItem.Create(FServer, aDatabaseName);
Insert(Result);
end;
{--------}
procedure TffeDatabaseList.DropDatabase(aIndex: LongInt);
begin
with Items[aIndex] do begin
FDatabase.Connected := False;
FServer.Session.DeleteAlias(DatabaseName);
end;
DeleteAt(aIndex);
end;
{--------}
function TffeDatabaseList.GetItem(aIndex: LongInt): TffeDatabaseItem;
begin
Result := TffeDatabaseItem(inherited Items[aIndex]);
end;
{--------}
function TffeDatabaseList.Insert(aItem: TffeDatabaseItem): Boolean;
begin
aItem.diParentList := Self;
Result := inherited Insert(AItem);
end;
{--------}
procedure TffeDatabaseList.Load;
var
Aliases : TStringList;
Index : longInt;
OldCursor: TCursor;
begin
OldCursor := Screen.Cursor;
Aliases := TStringList.Create;
Screen.Cursor := crHourglass;
try
Empty;
FServer.GetAliases(Aliases);
for Index := 0 to pred(Aliases.Count) do begin
Add(Aliases[Index]);
end;
finally
Aliases.Free;
Screen.Cursor := OldCursor;
end;
end;
{=====================================================================}
{== TffeTableItem ====================================================}
constructor TffeTableItem.Create(aDatabase : TffeDatabaseItem;
aTableName : TffName);
begin
inherited Create(etTable, aTableName);
FParent := aDatabase;
CursorID := -1;
TaskID := -1;
tiParentList := nil;
Table := TffexpTable.Create(nil);
with Table do begin
SessionName := aDatabase.Server.Session.SessionName;
DatabaseName := aDatabase.Database.DatabaseName;
TableName := aTableName;
ReadOnly := False;
AfterOpen := AfterOpenEvent;
end;
end;
{--------}
destructor TffeTableItem.Destroy;
begin
Table.Free;
inherited Destroy;
end;
{--------}
procedure TffeTableItem.CheckRebuildStatus(var aCompleted: Boolean;
var aStatus: TffRebuildStatus);
var
WasOpen : Boolean;
begin
WasOpen := Database.IsOpen;
if not Database.IsOpen then
Database.Open;
try
Check(FParent.Server.Session.GetTaskStatus(TaskID, aCompleted, aStatus));
if aCompleted then
TaskID := -1;
except
TaskID := -1;
end;
if not WasOpen then
Database.Close;
end;
{--------}
function TffeTableItem.GetAutoInc : TffWord32;
var
WasOpen : Boolean;
begin
WasOpen := Table.Active;
if not Table.Active then
Table.Open;
Result := FParent.Server.GetAutoInc(Table);
if not WasOpen then
Table.Close;
end;
{--------}
procedure TffeTableItem.AfterOpenEvent(aDataset: TDataset);
var
I: Integer;
begin
with aDataset do
for I := 0 to FieldCount - 1 do
case Fields[I].DataType of
ftString: TStringField(Fields[I]).Transliterate := False;
ftMemo: TMemoField(Fields[I]).Transliterate := False;
end;
end;
{--------}
function TffeTableItem.GetDatabase: TffeDatabaseItem;
begin
Result := FParent;
end;
{--------}
function TffeTableItem.GetDictionary: TffDataDictionary;
var
WasOpen : Boolean;
begin
WasOpen := Table.Active;
if not Table.Active then
Table.Open;
Result := Table.Dictionary;
if not WasOpen then
Table.Close;
end;
{--------}
function TffeTableItem.GetRebuilding: Boolean;
begin
Result := TaskID <> -1;
end;
{--------}
function TffeTableItem.GetRecordCount: TffWord32;
var {!!.06}
WasOpen : Boolean; {!!.06}
begin {!!.06}
WasOpen := Table.Active;
if not Table.Active then
Table.Open;
Result := Table.RecordCount;
if WasOpen then {!!.06}
Table.Close; {!!.06}
end;
{--------}
function TffeTableItem.GetServer: TffeServerItem;
begin
Result := FParent.Server;
end;
{--------}
procedure TffeTableItem.Pack;
var
WasOpen : Boolean;
begin
WasOpen := Database.IsOpen;
if not Database.IsOpen then
Database.Open;
Check(Database.FDatabase.PackTable(Table.TableName, TaskID));
if not WasOpen then
Database.Close;
end;
{--------}
procedure TffeTableItem.Reindex(aIndexNum: Integer);
var
WasOpen: Boolean;
begin
WasOpen := Database.IsOpen;
if not Database.IsOpen then
Database.Open;
if Table.Active then Table.Close;
Check(Database.FDatabase.ReindexTable(Table.TableName, aIndexNum, TaskID));
if not WasOpen then
Database.Close;
end;
{--------}
procedure TffeTableItem.Rename(aNewTableName: TffName);
begin
with Table do begin
if Active then Close;
RenameTable(aNewTableName);
FEntityName := aNewTableName;
end;
end;
{--------}
procedure TffeTableItem.Restructure(aDictionary: TffDataDictionary; aFieldMap: TStrings);
var
Result: TffResult;
WasOpen: Boolean;
begin
WasOpen := Database.IsOpen;
if not Database.IsOpen then
Database.Open;
Table.Close;
Result := Database.FDatabase.RestructureTable
(Tablename, aDictionary, aFieldMap, TaskID);
if Result = DBIERR_INVALIDRESTROP then
raise Exception.Create('Cannot preserve data if user-defined indexes have been added or changed')
else Check(Result);
if not WasOpen then
Database.Close;
end;
{--------}
procedure TffeTableItem.SetAutoIncSeed(aValue: Integer);
var
WasOpen : Boolean;
begin
WasOpen := Table.Active;
if not Table.Active then
Table.Open;
Check(Table.SetTableAutoIncValue(aValue));
if not WasOpen then
Table.Close;
end;
{--------}
procedure TffeTableItem.Truncate;
begin
{ Make sure we suck in the dictionary before the table gets deleted }
GetDictionary;
with Table do begin
Close;
DeleteTable;
end;
Database.CreateTable(TableName, Dictionary);
end;
{--------}
procedure TffeTableItem.CopyRecords(aSrcTable: TffDataSet;
aCopyBLOBs: Boolean);
var
WasOpen : Boolean;
begin
WasOpen := Table.Active;
if not Table.Active then
Table.Open;
Table.CopyRecords(aSrcTable, aCopyBLOBs);
if not WasOpen then
Table.Close;
end;
{=====================================================================}
{== TffeTableList ====================================================}
constructor TffeTableList.Create(aDatabase : TffeDatabaseItem);
begin
inherited Create;
FDatabase := aDatabase;
Sorted := False;
end;
{--------}
destructor TffeTableList.Destroy;
begin
Empty;
inherited Destroy;
end;
{--------}
function TffeTableList.Add(const aTableName: TffName): longInt;
var
aTable : TffeTableItem;
begin
aTable := TffeTableItem.Create(FDatabase, aTableName);
Insert(aTable);
Result := pred(Count);
end;
{--------}
procedure TffeTableList.DropTable(aIndex: LongInt);
begin
with Items[aIndex].Table do begin
if Active then
Close;
DeleteTable;
end;
DeleteAt(aIndex);
end;
{--------}
function TffeTableList.GetItem(aIndex: LongInt): TffeTableItem;
begin
Result := TffeTableItem(inherited Items[aIndex]);
end;
{--------}
function TffeTableList.Insert(aItem: TffeTableItem): Boolean;
begin
aItem.tiParentList := Self;
Result := inherited Insert(aItem);
end;
{--------}
procedure TffeTableList.Load;
var
I: Integer;
OldCursor: TCursor;
Tables: TStringList;
begin
Tables := TStringList.Create;
OldCursor := Screen.Cursor;
Screen.Cursor := crHourglass;
try
{ Remove any existing tables for this database }
Empty;
FDatabase.GetTableNames(Tables);
for I := 0 to Tables.Count - 1 do
Add(Tables[I]);
finally
Screen.Cursor := OldCursor;
Tables.Free;
end;
end;
{=====================================================================}
{ TffexpSession }
constructor TffexpSession.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
OnLogin := FFELogin;
ffePassword := '';
ffeUserName := '';
end;
procedure TffexpSession.FFELogin(aSource: TObject; var aUserName,
aPassword: TffName; var aResult: Boolean);
var
FFLoginDialog : TffLoginDialog;
begin
FFLoginDialog := TFFLoginDialog.Create(nil);
try
with FFLoginDialog do begin
UserName := aUserName;
Password := aPassword;
ShowModal;
aResult := ModalResult = mrOK;
if aResult then begin
aUserName := UserName;
ffeUserName := UserName;
aPassword := Password;
ffePassword := Password;
aResult := True;
end;
end;
finally
FFLoginDialog.Free;
end;
end;
initialization
NextEntitySerialKey := 0;
end.