- Recompilación en Delphi10 de todos los paquetes de RO para generar las DCU's en Lib\D10 - Recompilación en Delphi10 de todos los paquetes de DA para generar las DCU's en Lib\D10 git-svn-id: https://192.168.0.254/svn/Componentes.Terceros.RemObjects@9 b6239004-a887-0f4b-9937-50029ccdca16
426 lines
11 KiB
ObjectPascal
426 lines
11 KiB
ObjectPascal
unit uDACache;
|
|
|
|
{----------------------------------------------------------------------------}
|
|
{ Data Abstract Library - Core Library }
|
|
{ }
|
|
{ compiler: Delphi 6 and up, Kylix 3 and up }
|
|
{ platform: Win32, Linux }
|
|
{ }
|
|
{ (c)opyright RemObjects Software. all rights reserved. }
|
|
{ }
|
|
{ Using this code requires a valid license of the Data Abstract }
|
|
{ which can be obtained at http://www.remobjects.com. }
|
|
{----------------------------------------------------------------------------}
|
|
|
|
{$I DataAbstract.inc}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, SyncObjs,
|
|
uROClasses, uROTypes, uDAInterfaces;
|
|
|
|
type
|
|
{ TDACacheElement }
|
|
TDACacheElementOption = (ceoFlushOnUpdate);
|
|
TDACacheElementOptions = set of TDACacheElementOption;
|
|
|
|
TDACacheElement = class(TCollectionItem)
|
|
private
|
|
fEnabled: boolean;
|
|
fMaxReads: integer;
|
|
fReferencedDataset: string;
|
|
fOptions: TDACacheElementOptions;
|
|
fDuration: integer;
|
|
procedure SetDuration(const Value: integer);
|
|
procedure SetMaxReads(const Value: integer);
|
|
|
|
protected
|
|
function GetDisplayName: string; override;
|
|
|
|
public
|
|
constructor Create(aCollection : TCollection); override;
|
|
|
|
published
|
|
property ReferencedDataset : string read fReferencedDataset write fReferencedDataset;
|
|
property Enabled : boolean read fEnabled write fEnabled;
|
|
property Options : TDACacheElementOptions read fOptions write fOptions;
|
|
property MaxReads : integer read fMaxReads write SetMaxReads;
|
|
property Duration : integer read fDuration write SetDuration;
|
|
end;
|
|
|
|
{ TDACacheElementCollection }
|
|
TDACacheElementCollection = class(TCollection)
|
|
private
|
|
function GetItems(Index: integer): TDACacheElement;
|
|
protected
|
|
public
|
|
constructor Create;
|
|
destructor Destroy; override;
|
|
|
|
function Add : TDACacheElement;
|
|
function FindByDatasetName(aDatasetName : string) : TDACacheElement;
|
|
|
|
property Items[Index : integer] : TDACacheElement read GetItems; default;
|
|
end;
|
|
|
|
{ IDACacheEntry }
|
|
IDACacheEntry = interface
|
|
['{87F5AFF3-590C-4749-A3D7-BD4F8B2D5166}']
|
|
function GetInvalid: boolean;
|
|
function GetData: TStream;
|
|
function GetExpirationTime: TDateTime;
|
|
function GetMaxReads: integer;
|
|
function GetName: string;
|
|
function GetOwnsStream: boolean;
|
|
function GetReadCount: integer;
|
|
function GetRecordCount: integer;
|
|
procedure SetReadCount(const Value: integer);
|
|
|
|
property Name : string read GetName;
|
|
property Data : TStream read GetData;
|
|
property ReadCount : integer read GetReadCount write SetReadCount;
|
|
|
|
property RecordCount : integer read GetRecordCount;
|
|
|
|
property ExpirationTime : TDateTime read GetExpirationTime;
|
|
|
|
property MaxReads : integer read GetMaxReads;
|
|
property OwnsStream : boolean read GetOwnsStream;
|
|
property Invalid : boolean read GetInvalid;
|
|
end;
|
|
|
|
{ TDACacheEntry }
|
|
TDACacheEntry = class(TInterfacedObject, IDACacheEntry)
|
|
private
|
|
fOwnsStream : boolean;
|
|
fData: TStream;
|
|
fMaxReads: integer;
|
|
fReadCount: integer;
|
|
fName: string;
|
|
fExpirationTime: TDateTime;
|
|
fRecordCount: integer;
|
|
|
|
protected
|
|
{ IDACacheEntry }
|
|
function GetInvalid: boolean;
|
|
function GetData: TStream;
|
|
function GetExpirationTime: TDateTime;
|
|
function GetMaxReads: integer;
|
|
function GetName: string;
|
|
function GetOwnsStream: boolean;
|
|
function GetReadCount: integer;
|
|
function GetRecordCount: integer;
|
|
procedure SetReadCount(const Value: integer);
|
|
|
|
public
|
|
constructor Create(const aName : string; aData : TStream; aRecordCount : integer;
|
|
aOwnsStream : boolean; aMaxReads : integer = -1; aDuration : integer = -1);
|
|
destructor Destroy; override;
|
|
end;
|
|
|
|
{ TDACache }
|
|
TDACache = class(TComponent)
|
|
private
|
|
fTimer : TROThreadTimer;
|
|
fEntries : TInterfaceList;
|
|
fCritical : TCriticalSection;
|
|
|
|
function GetEntries(Index: integer): IDACacheEntry;
|
|
function GetEntryCount: integer;
|
|
|
|
protected
|
|
procedure OnTimerTick(CurrentTickCount : cardinal);
|
|
|
|
public
|
|
constructor Create(aOwner : TComponent); override;
|
|
destructor Destroy; override;
|
|
|
|
procedure Store(const anEntryName : string; Data : TStream;
|
|
CopyStream : boolean; RecordCount : integer = -1;
|
|
MaxReads : integer = -1; Duration : integer = -1);
|
|
function Get(const anEntryName : string) : IDACacheEntry;
|
|
procedure Flush(const anEntryName : string);
|
|
|
|
function Find(const anEntryName : string) : integer;
|
|
|
|
property Entries[Index : integer] : IDACacheEntry read GetEntries;
|
|
property EntryCount : integer read GetEntryCount;
|
|
|
|
end;
|
|
|
|
implementation
|
|
|
|
uses
|
|
DateUtils;
|
|
|
|
{ TDACacheElementCollection }
|
|
|
|
function TDACacheElementCollection.Add: TDACacheElement;
|
|
begin
|
|
result := TDACacheElement(inherited Add);
|
|
end;
|
|
|
|
constructor TDACacheElementCollection.Create;
|
|
begin
|
|
inherited Create(TDACacheElement);
|
|
end;
|
|
|
|
destructor TDACacheElementCollection.Destroy;
|
|
begin
|
|
|
|
inherited;
|
|
end;
|
|
|
|
function TDACacheElementCollection.FindByDatasetName(
|
|
aDatasetName: string): TDACacheElement;
|
|
var i : integer;
|
|
begin
|
|
result := NIL;
|
|
|
|
for i := 0 to (Count-1) do
|
|
if SameText(Items[i].ReferencedDataset, aDatasetName) then begin
|
|
result := Items[i];
|
|
Exit;
|
|
end;
|
|
end;
|
|
|
|
function TDACacheElementCollection.GetItems(
|
|
Index: integer): TDACacheElement;
|
|
begin
|
|
result := TDACacheElement(inherited Items[Index]);
|
|
end;
|
|
|
|
{ TDACacheElement }
|
|
|
|
constructor TDACacheElement.Create(aCollection: TCollection);
|
|
begin
|
|
inherited;
|
|
|
|
fEnabled := TRUE;
|
|
fMaxReads := -1;
|
|
fDuration := -1;
|
|
fOptions := [ceoFlushOnUpdate];
|
|
end;
|
|
|
|
function TDACacheElement.GetDisplayName: string;
|
|
begin
|
|
if fReferencedDataset<>''
|
|
then result := fReferencedDataset
|
|
else result := '<Unassigned>'
|
|
end;
|
|
|
|
procedure TDACacheElement.SetDuration(const Value: integer);
|
|
begin
|
|
if (Value=-1) or (Value>0)
|
|
then fDuration := Value;
|
|
end;
|
|
|
|
procedure TDACacheElement.SetMaxReads(const Value: integer);
|
|
begin
|
|
if (Value=-1) or (Value>0)
|
|
then fMaxReads := Value;
|
|
end;
|
|
|
|
{ TDACache }
|
|
|
|
constructor TDACache.Create(aOwner: TComponent);
|
|
begin
|
|
inherited;
|
|
|
|
fTimer := TROThreadTimer.Create(OnTimerTick, 60); // Checks every minute
|
|
|
|
fCritical := TCriticalSection.Create;
|
|
fEntries := TInterfaceList.Create;
|
|
end;
|
|
|
|
destructor TDACache.Destroy;
|
|
begin
|
|
fTimer.Terminate;
|
|
fTimer.Free;
|
|
|
|
fEntries.Free;
|
|
fCritical.Free;
|
|
|
|
inherited;
|
|
end;
|
|
|
|
function TDACache.Find(const anEntryName: string): integer;
|
|
var i : integer;
|
|
begin
|
|
result := -1;
|
|
for i := 0 to (fEntries.Count-1) do
|
|
if SameText(Entries[i].Name, anEntryName) then begin
|
|
result := i;
|
|
Exit;
|
|
end;
|
|
end;
|
|
|
|
procedure TDACache.Flush(const anEntryName: string);
|
|
var idx : integer;
|
|
begin
|
|
fCritical.Enter;
|
|
try
|
|
idx := Find(anEntryName);
|
|
if (idx>=0)
|
|
then fEntries.Delete(idx);
|
|
finally
|
|
fCritical.Leave;
|
|
end;
|
|
end;
|
|
|
|
function TDACache.Get(const anEntryName: string): IDACacheEntry;
|
|
var idx : integer;
|
|
begin
|
|
result := NIL;
|
|
fCritical.Enter;
|
|
try
|
|
idx := Find(anEntryName);
|
|
if (idx>=0) then begin
|
|
result := Entries[idx];
|
|
|
|
if result.Invalid then begin
|
|
result := NIL;
|
|
fEntries.Delete(idx);
|
|
Exit;
|
|
end
|
|
else begin
|
|
result.ReadCount := result.ReadCount+1;
|
|
end;
|
|
end;
|
|
finally
|
|
fCritical.Leave;
|
|
end;
|
|
end;
|
|
|
|
function TDACache.GetEntries(Index: integer): IDACacheEntry;
|
|
begin
|
|
result := fEntries[Index] as IDACacheEntry;
|
|
end;
|
|
|
|
function TDACache.GetEntryCount: integer;
|
|
begin
|
|
result := fEntries.Count;
|
|
end;
|
|
|
|
procedure TDACache.OnTimerTick(CurrentTickCount: cardinal);
|
|
var i : integer;
|
|
begin
|
|
fCritical.Enter;
|
|
try
|
|
for i := fEntries.Count-1 downto 0 do begin
|
|
if Entries[i].Invalid
|
|
then fEntries.Delete(i);
|
|
end;
|
|
finally
|
|
fCritical.Leave;
|
|
end;
|
|
end;
|
|
|
|
procedure TDACache.Store(const anEntryName: string; Data: TStream; CopyStream : boolean;
|
|
RecordCount, MaxReads, Duration: integer);
|
|
var entry : TDACacheEntry;
|
|
nme : string;
|
|
idx : integer;
|
|
newstream : Binary;
|
|
begin
|
|
nme := UpperCase(anEntryName);
|
|
|
|
fCritical.Enter;
|
|
try
|
|
idx := Find(nme);
|
|
|
|
if (idx<0) then begin
|
|
if CopyStream then begin
|
|
newstream := Binary.Create;
|
|
newstream.CopyFrom(Data, 0);
|
|
entry := TDACacheEntry.Create(nme, newstream, RecordCount, TRUE, MaxReads, Duration);
|
|
end
|
|
else entry := TDACacheEntry.Create(nme, Data, RecordCount, FALSE, MaxReads, Duration);
|
|
|
|
fEntries.Add(entry);
|
|
end
|
|
else raise Exception.Create('Duplicated name '+anEntryName);
|
|
finally
|
|
fCritical.Leave;
|
|
end;
|
|
end;
|
|
|
|
{ TDACacheEntry }
|
|
|
|
constructor TDACacheEntry.Create(const aName : string; aData : TStream; aRecordCount : integer;
|
|
aOwnsStream : boolean; aMaxReads : integer = -1; aDuration : integer = -1);
|
|
begin
|
|
inherited Create;
|
|
|
|
fName := aName;
|
|
fData := aData;
|
|
fRecordCount := aRecordCount;
|
|
|
|
if (aDuration>0)
|
|
then fExpirationTime := IncMinute(Now, aDuration)
|
|
else fExpirationTime := -1;
|
|
|
|
fReadCount := 0;
|
|
fMaxReads := aMaxReads;
|
|
end;
|
|
|
|
destructor TDACacheEntry.Destroy;
|
|
begin
|
|
if fOwnsStream
|
|
then fData.Free;
|
|
|
|
inherited;
|
|
end;
|
|
|
|
function TDACacheEntry.GetData: TStream;
|
|
begin
|
|
result := fData;
|
|
//Inc(fReadCount);
|
|
end;
|
|
|
|
function TDACacheEntry.GetExpirationTime: TDateTime;
|
|
begin
|
|
result := fExpirationTime
|
|
end;
|
|
|
|
function TDACacheEntry.GetInvalid: boolean;
|
|
begin
|
|
result := ((fMaxReads<>-1) and (fReadCount>=fMaxReads))
|
|
or
|
|
((fExpirationTime<>-1) and (fExpirationTime<=Now));
|
|
end;
|
|
|
|
function TDACacheEntry.GetMaxReads: integer;
|
|
begin
|
|
result := fMaxReads
|
|
end;
|
|
|
|
function TDACacheEntry.GetName: string;
|
|
begin
|
|
result := fName
|
|
end;
|
|
|
|
function TDACacheEntry.GetOwnsStream: boolean;
|
|
begin
|
|
result := fOwnsStream
|
|
end;
|
|
|
|
function TDACacheEntry.GetReadCount: integer;
|
|
begin
|
|
result := fReadCount
|
|
end;
|
|
|
|
function TDACacheEntry.GetRecordCount: integer;
|
|
begin
|
|
result := fRecordCount
|
|
end;
|
|
|
|
procedure TDACacheEntry.SetReadCount(const Value: integer);
|
|
begin
|
|
if (Value>=0)
|
|
then fReadCount := Value
|
|
end;
|
|
|
|
end.
|