2016-06-11 22:52:48 +00:00
|
|
|
{ Visual PlanIt datastore for a TBufDataset }
|
|
|
|
|
2016-06-22 07:59:17 +00:00
|
|
|
{$I vp.inc}
|
2016-06-11 22:52:48 +00:00
|
|
|
|
2021-10-27 18:22:19 +00:00
|
|
|
{ TBufDataset of FPC 3.2.0 and older has an abstract method, LoadBlobIntoBuffer,
|
|
|
|
which creates a compiler warning }
|
|
|
|
{$DEFINE FIX_BUFDATASET}
|
|
|
|
|
2016-06-11 22:52:48 +00:00
|
|
|
unit VpBufDS;
|
|
|
|
|
|
|
|
interface
|
|
|
|
|
|
|
|
uses
|
|
|
|
SysUtils, Classes, db, BufDataset,
|
|
|
|
VpDBDS;
|
|
|
|
|
2021-10-27 18:22:19 +00:00
|
|
|
{$IFDEF FIX_BUFDATASET}
|
|
|
|
type
|
|
|
|
TBufDataset = class(BufDataset.TBufDataset)
|
|
|
|
protected
|
|
|
|
procedure LoadBlobIntoBuffer({%H-}FieldDef: TFieldDef;{%H-}ABlobBuf: PBufBlobField); override;
|
|
|
|
end;
|
|
|
|
{$ENDIF}
|
|
|
|
|
2016-06-11 22:52:48 +00:00
|
|
|
type
|
|
|
|
TVpBufDSDataStore = class(TVpCustomDBDataStore)
|
|
|
|
private
|
|
|
|
FResourceTable: TBufDataset;
|
|
|
|
FEventsTable: TBufDataset;
|
|
|
|
FContactsTable: TBufDataset;
|
|
|
|
FTasksTable: TBufDataset;
|
|
|
|
FDirectory: String;
|
2016-07-03 22:56:59 +00:00
|
|
|
FUseAutoInc: Boolean;
|
2016-07-06 13:41:17 +00:00
|
|
|
FPersistent: Boolean;
|
2016-06-11 22:52:48 +00:00
|
|
|
procedure SetDirectory(AValue: String);
|
2016-07-06 13:41:17 +00:00
|
|
|
procedure SetPersistent(AValue: Boolean);
|
2016-07-03 22:56:59 +00:00
|
|
|
procedure SetUseAutoInc(AValue: Boolean);
|
2016-06-11 22:52:48 +00:00
|
|
|
|
|
|
|
protected
|
|
|
|
{ ancestor property getters }
|
|
|
|
function GetContactsTable: TDataset; override;
|
|
|
|
function GetEventsTable: TDataset; override;
|
|
|
|
function GetResourceTable: TDataset; override;
|
|
|
|
function GetTasksTable: TDataset; override;
|
|
|
|
|
|
|
|
{ ancestor methods }
|
|
|
|
procedure Loaded; override;
|
|
|
|
procedure SetConnected(const Value: boolean); override;
|
|
|
|
|
|
|
|
{ other methods }
|
|
|
|
procedure CloseTables;
|
|
|
|
procedure CreateTable(ATableName: String);
|
|
|
|
procedure OpenTables;
|
2016-07-03 22:56:59 +00:00
|
|
|
function UniqueID(AValue: Integer): Boolean;
|
2016-06-11 22:52:48 +00:00
|
|
|
|
|
|
|
public
|
|
|
|
constructor Create(AOwner: TComponent); override;
|
|
|
|
destructor Destroy; override;
|
|
|
|
procedure CreateTables;
|
2016-07-03 22:56:59 +00:00
|
|
|
function GetNextID(TableName: string): Integer; override;
|
2016-06-11 22:52:48 +00:00
|
|
|
|
|
|
|
property ResourceTable;
|
|
|
|
property EventsTable;
|
|
|
|
property ContactsTable;
|
|
|
|
property TasksTable;
|
|
|
|
|
|
|
|
published
|
|
|
|
property AutoConnect;
|
2016-06-19 11:44:35 +00:00
|
|
|
property AutoCreate;
|
2016-07-26 09:30:20 +00:00
|
|
|
property DayBuffer;
|
2016-07-06 13:41:17 +00:00
|
|
|
property Directory: String read FDirectory write SetDirectory;
|
|
|
|
property Persistent: Boolean read FPersistent write SetPersistent default true;
|
2016-07-03 22:56:59 +00:00
|
|
|
property UseAutoIncFields: Boolean read FUseAutoInc write SetUseAutoInc default true;
|
2016-06-11 22:52:48 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
implementation
|
|
|
|
|
|
|
|
uses
|
|
|
|
LazFileUtils,
|
2016-07-12 09:26:14 +00:00
|
|
|
VpConst, VpMisc, VpBaseDS, VpData;
|
2016-06-11 22:52:48 +00:00
|
|
|
|
|
|
|
const
|
|
|
|
TABLE_EXT = '.db';
|
2021-10-27 18:22:19 +00:00
|
|
|
|
|
|
|
|
|
|
|
{ TBufDataset }
|
|
|
|
|
|
|
|
procedure TBufDataset.LoadBlobIntoBuffer(FieldDef: TFieldDef; ABlobBuf: PBufBlobField);
|
|
|
|
begin
|
|
|
|
// We just want to avoid the compiler warning.
|
|
|
|
// TVpBufDSDataStore does not use BLOBs anyway.
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
{ TVpBufDSDatastore }
|
2016-06-11 22:52:48 +00:00
|
|
|
|
|
|
|
constructor TVpBufDSDatastore.Create(AOwner: TComponent);
|
|
|
|
begin
|
|
|
|
inherited Create(AOwner);
|
|
|
|
FResourceTable := TBufDataset.Create(nil);
|
|
|
|
FEventsTable := TBufDataset.Create(nil);
|
|
|
|
FContactsTable := TBufDataset.Create(nil);
|
|
|
|
FTasksTable := TBufDataset.Create(nil);
|
2016-07-06 13:41:17 +00:00
|
|
|
FPersistent := true;
|
2016-07-03 22:56:59 +00:00
|
|
|
FUseAutoInc := true;
|
2016-06-11 22:52:48 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
destructor TVpBufDSDatastore.Destroy;
|
|
|
|
begin
|
|
|
|
FreeAndNil(FResourceTable);
|
|
|
|
FreeAndNil(FEventsTable);
|
|
|
|
FreeAndNil(FContactsTable);
|
|
|
|
FreeAndNil(FTasksTable);
|
|
|
|
inherited;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpBufDSDatastore.CloseTables;
|
|
|
|
begin
|
|
|
|
FResourceTable.Close;
|
|
|
|
FEventsTable.Close;
|
|
|
|
FContactsTable.Close;
|
|
|
|
FTasksTable.Close;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpBufDSDatastore.CreateTable(ATableName: String);
|
|
|
|
var
|
|
|
|
dir: String;
|
|
|
|
table: TBufDataset;
|
|
|
|
begin
|
|
|
|
if FDirectory = '' then
|
|
|
|
dir := ExtractFilePath(ParamStr(0)) else
|
|
|
|
dir := IncludeTrailingPathDelimiter(FDirectory);
|
|
|
|
dir := ExpandFileName(dir);
|
|
|
|
if not DirectoryExistsUTF8(dir) then
|
2016-06-22 13:37:24 +00:00
|
|
|
begin
|
|
|
|
if AutoCreate then
|
|
|
|
CreateDir(dir)
|
|
|
|
else
|
|
|
|
raise Exception.CreateFmt('Directory "%s" for tables does not exist.', [dir]);
|
|
|
|
end;
|
2016-06-11 22:52:48 +00:00
|
|
|
|
|
|
|
if ATableName = ResourceTableName then
|
|
|
|
table := FResourceTable
|
|
|
|
else if ATableName = EventsTableName then
|
|
|
|
table := FEventsTable
|
|
|
|
else if ATableName = ContactsTablename then
|
|
|
|
table := FContactsTable
|
|
|
|
else if ATableName = TasksTableName then
|
|
|
|
table := FTasksTable
|
|
|
|
else
|
|
|
|
raise Exception.CreateFmt('TableName "%s" cannot be processed.', [ATableName]);
|
|
|
|
|
|
|
|
table.Close;
|
2016-07-06 13:41:17 +00:00
|
|
|
if FPersistent then
|
|
|
|
table.FileName := dir + ATableName + TABLE_EXT;
|
|
|
|
if ((not FPersistent) or (not FileExists(table.FileName))) and (table.FieldDefs.Count = 0) then
|
2016-06-11 22:52:48 +00:00
|
|
|
begin
|
|
|
|
CreateFieldDefs(ATableName, table.FieldDefs);
|
2016-07-03 22:56:59 +00:00
|
|
|
if FUseAutoInc then
|
|
|
|
table.FieldDefs[0].DataType := ftAutoInc;
|
2020-11-30 20:48:19 +00:00
|
|
|
table.IndexDefs.Clear;
|
|
|
|
table.IndexDefs.Update;
|
|
|
|
CreateIndexDefs(ATableName, table.IndexDefs);
|
2016-06-11 22:52:48 +00:00
|
|
|
table.CreateDataset;
|
2020-11-30 20:48:19 +00:00
|
|
|
end else
|
|
|
|
table.Open;
|
2016-06-11 22:52:48 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpBufDSDatastore.CreateTables;
|
|
|
|
begin
|
|
|
|
CreateTable(ResourceTablename);
|
|
|
|
CreateTable(EventsTableName);
|
|
|
|
CreateTable(ContactsTableName);
|
|
|
|
CreateTable(TasksTableName);
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TVpBufDSDatastore.GetResourceTable : TDataset;
|
|
|
|
begin
|
|
|
|
Result := FResourceTable;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TVpBufDSDatastore.GetEventsTable : TDataset;
|
|
|
|
begin
|
|
|
|
Result := FEventsTable;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TVpBufDSDatastore.GetContactsTable : TDataset;
|
|
|
|
begin
|
|
|
|
Result := FContactsTable;
|
|
|
|
end;
|
|
|
|
|
2016-07-03 22:56:59 +00:00
|
|
|
function TVpBufDSDatastore.GetNextID(TableName: string): Integer;
|
2016-06-11 22:52:48 +00:00
|
|
|
begin
|
2016-07-12 09:26:14 +00:00
|
|
|
Unused(TableName);
|
2016-07-03 22:56:59 +00:00
|
|
|
if FUseAutoInc then
|
|
|
|
{ This is not needed in the BufDataset datastore as these tables use
|
|
|
|
autoincrement fields. }
|
|
|
|
Result := -1
|
|
|
|
else
|
|
|
|
{ If autoincrement fields are not wanted the ID values are created from
|
|
|
|
random numbers. }
|
|
|
|
repeat
|
|
|
|
Result := Random(High(Integer));
|
|
|
|
until UniqueID(Result) and (Result <> -1);
|
2016-06-11 22:52:48 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
function TVpBufDSDatastore.GetTasksTable : TDataset;
|
|
|
|
begin
|
|
|
|
Result := FTasksTable;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpBufDSDatastore.Loaded;
|
|
|
|
begin
|
|
|
|
inherited;
|
|
|
|
Connected := AutoConnect;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpBufDSDatastore.OpenTables;
|
|
|
|
begin
|
|
|
|
FResourceTable.Open;
|
|
|
|
FEventsTable.Open;
|
|
|
|
FContactsTable.Open;
|
|
|
|
FTasksTable.Open;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpBufDSDatastore.SetConnected(const Value: boolean);
|
|
|
|
begin
|
|
|
|
{ Don't do anything with live data until run time. }
|
|
|
|
if (csDesigning in ComponentState) or (csLoading in ComponentState) then
|
|
|
|
Exit;
|
|
|
|
|
|
|
|
{ Connecting or disconnecting? }
|
|
|
|
if Value then begin
|
2016-06-19 11:44:35 +00:00
|
|
|
if AutoCreate then CreateTables;
|
2016-06-11 22:52:48 +00:00
|
|
|
OpenTables;
|
|
|
|
Load;
|
|
|
|
end;
|
|
|
|
|
|
|
|
inherited SetConnected(Value);
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpBufDSDatastore.SetDirectory(AValue: String);
|
|
|
|
begin
|
|
|
|
if AValue = FDirectory then
|
|
|
|
exit;
|
|
|
|
if Connected then
|
|
|
|
raise Exception.Create('Set directory before connecting.');
|
|
|
|
FDirectory := AValue;
|
|
|
|
end;
|
|
|
|
|
2016-07-06 13:41:17 +00:00
|
|
|
procedure TVpBufDSDatastore.SetPersistent(AValue: Boolean);
|
|
|
|
var
|
|
|
|
wasConn: Boolean;
|
|
|
|
begin
|
|
|
|
if AValue <> FPersistent then begin
|
|
|
|
wasConn := Connected;
|
|
|
|
Connected := false;
|
|
|
|
FPersistent := AValue;
|
|
|
|
if not FPersistent then begin
|
|
|
|
FResourceTable.FileName := '';
|
|
|
|
FEventsTable.FileName := '';
|
|
|
|
FContactsTable.FileName := '';
|
|
|
|
FTasksTable.FileName := '';
|
|
|
|
end;
|
|
|
|
Connected := wasConn;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2016-07-03 22:56:59 +00:00
|
|
|
procedure TVpBufDSDatastore.SetUseAutoInc(AValue: Boolean);
|
|
|
|
var
|
|
|
|
dir: String;
|
|
|
|
begin
|
|
|
|
if AValue = FUseAutoInc then
|
|
|
|
exit;
|
|
|
|
|
|
|
|
if ComponentState = [] then begin
|
|
|
|
if FDirectory = '' then
|
|
|
|
dir := ExtractFilePath(ParamStr(0)) else
|
|
|
|
dir := IncludeTrailingPathDelimiter(FDirectory);
|
|
|
|
dir := ExpandFileName(dir);
|
|
|
|
if DirectoryExistsUTF8(dir) then
|
|
|
|
begin
|
|
|
|
if FileExists(dir + ResourceTableName + TABLE_EXT) or
|
|
|
|
FileExists(dir + EventsTableName + TABLE_EXT) or
|
|
|
|
FileExists(dir + ContactsTableName + TABLE_EXT) or
|
|
|
|
FileExists(dir + TasksTableName + TABLE_EXT)
|
|
|
|
then
|
|
|
|
raise Exception.Create('You cannot change the property "UseAutoIncFields" after creation of the tables.');
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
FUseAutoInc := AValue;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TVpBufDSDatastore.UniqueID(AValue: Integer): Boolean;
|
|
|
|
var
|
|
|
|
i, j: Integer;
|
|
|
|
res: TVpResource;
|
|
|
|
begin
|
|
|
|
Result := false;
|
|
|
|
for i:=0 to Resources.Count-1 do begin
|
|
|
|
res := Resources.Items[i];
|
|
|
|
if res.ResourceID = AValue then
|
|
|
|
exit;
|
|
|
|
for j:=0 to res.Contacts.Count-1 do
|
|
|
|
if res.Contacts.GetContact(j).RecordID = AValue then
|
|
|
|
exit;
|
|
|
|
for j:=0 to res.Tasks.Count-1 do
|
|
|
|
if res.Tasks.GetTask(j).RecordID = AValue then
|
|
|
|
exit;
|
|
|
|
for j:=0 to res.Schedule.EventCount-1 do
|
|
|
|
if res.Schedule.GetEvent(j).RecordID = AValue then
|
|
|
|
exit;
|
|
|
|
end;
|
|
|
|
Result := true;
|
|
|
|
end;
|
2016-06-11 22:52:48 +00:00
|
|
|
|
|
|
|
end.
|