abstractdata.pas

 Back to Parent Page

unit abstractdata; 
{ Implementation of item data manipulation classes. 
  Two conditional defines are used: 
  ACTIVE_X - turn on in item business logic module 
  LOG_ON - can be used for debug purposes. Allow to log 
  benchmarking information of apply procedures. 
 
  Developed by Alex Feigin. } 
 
interface 
 
uses 
 Windows, Classes, DBTables, Db, SysUtils, StrUtils, Databkr, ComObj, itemdm, Dialogs; 
 
type 
{ Class TItemSlice supports manipulation with item data slice } 
TItemSlice = class(TPersistent) 
 private 
{ Physical name of data field } 
  FFieldName:String; 
{ Field value} 
  FValue:Variant; 
 public 
  constructor Create(EFieldName:string;EValue:Variant); virtual; 
  destructor  Destroy; override; 
  property    FieldName : string read FFieldName write FFieldName; 
  property    Value : Variant read FValue write FValue; 
 end; 
 
{ Class TItemData supports manipulations with item slices list } 
TItemData = class(TPersistent) 
 private 
{ Current index value} 
  currentIndex:integer; 
{ TStringList, which includes references to item data slices } 
  ItemData:TStringList; 
{ Reference to item logic RDM } 
  DMItemLog:TRemoteDataModule; 
{ Function returns item slice, correspondend to the index value  } 
  function    GetItemSlice(I:Integer):TItemSlice; 
{ Function process changes used to apply item slice to the appropriated 
  table. Available in item business logic module only. } 
{$IFDEF ACTIVE_X} 
  function    ProcessChanges(DataSet:TTable;ItemSlice:TItemSlice;var ParentKeySlice:TItemSlice):HResult; 
{$ENDIF} 
 public 
{$IFDEF LOG_ON} 
  ItemApplyTime:TDateTime; 
  DefaultApplyTime:TDateTime; 
  ProcessRecordTime:TDateTime; 
  checkIndexTime:TDateTime; 
  indexForFieldTime:TDateTime; 
  ProtocolApplyTime:TDateTime; 
{$ENDIF} 
  constructor Create(DMItemLog:TRemoteDataModule;isSorted:Boolean=true); 
  destructor  Destroy; override; 
{ Function ApplyToDataSet used to apply item slices to the item database. 
  Available in item business logic module only. } 
{$IFDEF ACTIVE_X} 
  function    ApplyToDataSet(useDefaultLabel:Boolean;useDefaultCompItem:Boolean):HResult; 
{$ENDIF} 
{ Function, which adds new data slice to item data buffer} 
  function    AddDataSlice(fieldName:string;Value:Variant):HResult; 
{ Function, which reads first data slice from the item data buffer} 
  function    ReadFirstDataSlice(var fieldName:string;var Value:Variant):HResult; 
{ Function, which reads next data slice from the item data buffer} 
  function    ReadNextDataSlice(var fieldName:string;var Value:Variant):HResult; 
{ Function, InitFormDataSet was designed for retriving of item data buffer from the 
  item database. Not implemented in the current implementation, because there is no 
  users.} 
  function    InitFromDataSet(Moniker:string):HResult; 
{ Function makes search for item slice by field name } 
  function    FindItemSlice(fieldName:String):TItemSlice; 
{ Function reads item slice from item data buffer by field name } 
  function    ReadSliceByName(fieldName:String):OleVariant; 
{ Function returns field value, correspondend to the index value  } 
  function    GetItemValue(I:Integer) : Variant; 
{ Procedure, which clears item data buffer } 
  procedure   ClearItemData; 
end; 
 
 
implementation 
{$IFDEF ACTIVE_X} 
uses 
 dmLogItem; 
{$ENDIF}  
 
{ TItemSlice object constructor } 
constructor TItemSlice.Create(EFieldName:string;EValue:Variant); 
begin 
 inherited Create; 
 FieldName:=EFieldName; 
 Value:=EValue; 
end; 
 
{ TItemSlice object destructor } 
destructor  TItemSlice.Destroy; 
begin 
 inherited Destroy; 
end; 
 
{ TItemData object constructor } 
constructor TItemData.Create(DMItemLog:TRemoteDataModule;isSorted:Boolean); 
begin 
 inherited Create;  
{ Creation of string list, which will store references to item slices } 
 ItemData:=TStringList.Create; 
 ItemData.Sorted:=isSorted; 
 currentIndex:=0; 
 self.DMItemLog:=DMItemLog; 
{$IFDEF LOG_ON} 
 ItemApplyTime:=0; 
 DefaultApplyTime:=0; 
 ProtocolApplyTime:=0; 
 ProcessRecordTime:=0; 
 checkIndexTime:=0; 
 indexForFieldTime:=0; 
{$ENDIF} 
end; 
 
{ Function, which retrives item value by index from item data buffer 
  Input value  : index 
  Returns : field value in case of success, otherwise returns varEmpty 
} 
function  TItemData.GetItemValue(I:Integer) : Variant; 
var 
 ItemSlice:TItemSlice; 
begin 
 ItemSlice:=GetItemSlice(I); 
 if(ItemSlice<>nil) then 
  Result:=ItemSlice.Value; 
end; 
 
{ TItemData class destructor } 
destructor TItemData.Destroy; 
var 
 I:Integer; 
begin 
{ Destroing of item slice objects } 
 for I:=0 to ItemData.Count-1 do 
   ItemData.Objects[I].Destroy; 
{ Destroying of item data buffer } 
 ItemData.Free; 
 inherited Destroy; 
end; 
 
{ Procedure to add new data slice to item data buffer. 
  Attention attempt to add value equal to varEmpty or varNull produce 
  an error. 
  Input values: 
  fieldName - physical field name 
  Value     - field value 
  Returns NOERROR, if operation is successful. E_INVALIDARG in case of error. } 
function TItemData.AddDataSlice(fieldName:string;Value:Variant):HResult; 
begin 
 if(VarIsNull(Value) OR 
    VarIsEmpty(Value)) then 
  Result:=E_INVALIDARG 
 else 
  begin 
   ItemData.AddObject(fieldName,TItemSlice.Create(fieldName,Value)); 
   Result:=NOERROR; 
  end; 
end; 
 
{ Function, which retrieves first data slice from item data buffer 
  Output values: 
  fieldName - physical field name 
  Value     - field value 
  Returns NOERROR, if operation is successful, E_OUTOFMEMORY if item data 
  buffer is empty } 
function  TItemData.ReadFirstDataSlice(var fieldName:string;var Value:Variant):HResult; 
var 
 ItemSlice:TItemSlice; 
begin 
 currentIndex:=0; 
 if(currentIndexthen 
  begin 
   ItemSlice:=(ItemData.Objects[currentIndex] as TItemSlice); 
   fieldName:=ItemSlice.fieldName; 
   Value:=ItemSlice.Value; 
   Result:=NOERROR; 
  end 
 else 
  Result:=E_OUTOFMEMORY; 
end; 
 
{ Function, which retrieves next data slice from item data buffer 
  Output values: 
  fieldName - physical field name 
  Value     - field value 
  Returns NOERROR, if operation is successful, E_OUTOFMEMORY if end of item data 
  buffer is reached } 
function  TItemData.ReadNextDataSlice(var fieldName:string;var Value:Variant):HResult; 
var 
 ItemSlice:TItemSlice; 
begin 
 Inc(currentIndex); 
 if(currentIndexthen 
  begin 
   ItemSlice:=(ItemData.Objects[currentIndex] as TItemSlice); 
   fieldName:=ItemSlice.fieldName; 
   Value:=ItemSlice.Value; 
   Result:=NOERROR; 
  end 
 else 
  Result:=E_OUTOFMEMORY; 
end; 
 
{ Function return item slice by index value. 
  Input value : I - index in item data buffer 
  Result : item slice object with index I, nil if appropriated 
  item slice is absent in item data buffer }  
function  TItemData.GetItemSlice(I:Integer):TItemSlice; 
begin 
 if (I>=0) and (Ithen 
   Result:=TItemSlice(ItemData.Objects[I]) 
 else 
   Result:=nil; 
end; 
 
{ Procedure, which clears item data buffer } 
procedure   TItemData.ClearItemData; 
var 
 I:Integer; 
begin 
 for I:=0 to ItemData.Count-1 do 
   ItemData.Objects[I].Destroy; 
 ItemData.Clear; 
 currentIndex:=0; 
end; 
 
{ Making search of slice from item data buffer by field name. 
  Input values :  field name 
  Ouput values :  item slice in case of success, nil if field 
  is not found } 
function   TItemData.FindItemSlice(fieldName:String):TItemSlice; 
var 
  I:Integer; 
  isFound:Boolean; 
begin 
  if(ItemData.Sorted) then 
   isFound:=ItemData.Find(fieldName,I) 
  else 
   begin 
    I:=ItemData.IndexOf(fieldName); 
    isFound:=(I<>-1); 
   end; 
  if(isFound) then 
   Result:=GetItemSlice(I) 
  else 
   Result:=nil; 
e