Extra Systems Database
unit table;
interface
uses
common, database, windows, classes, sysutils;
type
TEditMode = (emNone, emEdit, emAppend);
TESDBTable = class(TObject)
private
FActive : Boolean;
FHandle : HTABLE;
FParent : TESDBDatabase;
FRecordSize : Integer;
FRecordBuffer : Pointer;
FCurrentRecord : Integer;
FTotalRecordsCount : Integer;
FRealRecordsCount : Integer;
FLastGetRecord : Integer;
FEditMode : TEditMode;
function ReadCurrentRecord:Boolean;
public
FieldsList: TESDBFieldsList;
constructor Create(const Parent:TESDBDatabase);
destructor Destroy; override;
function Open(const TableName:String):Boolean;
procedure Close;
procedure Append;
procedure Edit;
function Pack:Boolean;
procedure Delete;
procedure Cancel;
function SetIntegerField(const FieldName:String; const Value:Integer):Boolean;
function SetStringField(const FieldName:String; const Value:String):Boolean;
function SetDateTimeField(const FieldName:String; const Value:TDateTime):Boolean;
function GetIntegerField(const FieldName:String):Integer;
function GetStringField(const FieldName:String):String;
function GetDateTimeField(const FieldName:String):TDateTime;
function Post:Boolean;
function TotalRecordsCount:Integer;
function RealRecordsCount:Integer;
procedure First;
procedure Last;
procedure Next;
procedure Prior;
function EOF:Boolean;
function BOF:Boolean;
property Active:Boolean read FActive;
end;
implementation
constructor TESDBTable.Create(const Parent:TESDBDatabase);
begin
inherited Create;
FParent:=Parent;
FActive:=False;
FieldsList:=TESDBFieldsList.Create;
FRecordBuffer:=nil;
FEditMode:=emNone;
end;
destructor TESDBTable.Destroy;
begin
Close;
FieldsList.Free;
inherited Destroy;
end;
function TESDBTable.Open(const TableName:String):Boolean;
var
i,j:Integer;
Field:TESDBField;
begin
Result:=False;
if FActive then Exit;
FHandle:=FParent.OpenTable(TableName);
FActive:=(FHandle > 0);
Result:=FActive;
if not Result then Exit;
FParent.GetTableStructure(FHandle, FieldsList);
FRecordSize:=0;
j:=0;
for i:=0 to FieldsList.Count - 1 do begin
FieldsList.GetItem(i, Field);
FRecordSize:=FRecordSize + Field.FieldLength;
Field.FieldPosition:=j;
j:=j + Field.FieldLength;
FieldsList.SetItem(i, Field);
end;
FTotalRecordsCount:=FParent.GetTotalRecordsCount(FHandle);
FRealRecordsCount:=FParent.GetRealRecordsCount(FHandle);
FLastGetRecord:=-1;
if (FRecordBuffer = nil) then begin
GetMem(FRecordBuffer, FRecordSize);
FillChar(FRecordBuffer^, FRecordSize, 0);
end;
First;
FEditMode:=emNone;
end;
procedure TESDBTable.Close;
begin
if not FActive then Exit;
FParent.CloseTable(FHandle);
if (FRecordBuffer <> nil) then begin
FreeMem(FRecordBuffer);
FRecordBuffer:=nil;
end;
FActive:=False;
end;
procedure TESDBTable.Append;
begin
if not FActive then Exit;
if (FEditMode <> emNone) then Exit;
FCurrentRecord:=0;
FillChar(FRecordBuffer^, FRecordSize, 0);
FEditMode:=emAppend;
end;
procedure TESDBTable.Edit;
begin
if not FActive then Exit;
if (FEditMode <> emNone) then Exit;
if (EOF or BOF) then Exit;
if (FLastGetRecord <> FCurrentRecord) then Exit;
FEditMode:=emEdit;
end;
procedure TESDBTable.Delete;
begin
if not FActive then Exit;
if (FEditMode <> emNone) then Exit;
if (EOF or BOF) then Exit;
if (FLastGetRecord <> FCurrentRecord) then Exit;
if FParent.DeleteTableRecord(FHandle, FCurrentRecord) then begin
Next;
end;
end;
procedure TESDBTable.Cancel;
begin
FEditMode:=emNone;
end;
function TESDBTable.SetIntegerField(const FieldName:String; const Value:Integer):Boolean;
begin
Result:=False;
if not FActive then Exit;
if (FEditMode = emNone) then Exit;
Result:=FParent.SetIntegerField(FieldName, Value, FieldsList, FRecordBuffer);
end;
function TESDBTable.GetStringField(const FieldName:String):String;
begin
Result:='';
if not FActive then Exit;
Result:=FParent.GetStringField(FieldName, FieldsList, FRecordBuffer);
end;
function TESDBTable.GetIntegerField(const FieldName:String):Integer;
begin
Result:=0;
if not FActive then Exit;
Result:=FParent.GetIntegerField(FieldName, FieldsList, FRecordBuffer);
end;
function TESDBTable.GetDateTimeField(const FieldName:String):TDateTime;
begin
Result:=0;
if not FActive then Exit;
Result:=FParent.GetDateTimeField(FieldName, FieldsList, FRecordBuffer);
end;
function TESDBTable.SetDateTimeField(const FieldName:String; const Value:TDateTime):Boolean;
begin
Result:=False;
if not FActive then Exit;
if (FEditMode = emNone) then Exit;
Result:=FParent.SetDateTimeField(FieldName, Value, FieldsList, FRecordBuffer);
end;
function TESDBTable.SetStringField(const FieldName:String; const Value:String):Boolean;
begin
Result:=False;
if not FActive then Exit;
if (FEditMode = emNone) then Exit;
Result:=FParent.SetStringField(FieldName, Value, FieldsList, FRecordBuffer);
end;
function TESDBTable.Post:Boolean;
begin
Result:=False;
if not FActive then Exit;
if (FEditMode = emNone) then Exit;
Result:=FParent.PostTableRecord(FHandle, FCurrentRecord, FRecordBuffer, FRecordSize);
if (Result and (FEditMode = emAppend)) then begin
FTotalRecordsCount:=FTotalRecordsCount + 1;
FRealRecordsCount:=FRealRecordsCount + 1;
FCurrentRecord:=FTotalRecordsCount;
end;
FEditMode:=emNone;
end;
function TESDBTable.TotalRecordsCount:Integer;
begin
if FActive then Result:=FTotalRecordsCount else Result:=0;
end;
function TESDBTable.RealRecordsCount:Integer;
begin
if FActive then Result:=FRealRecordsCount else Result:=0;
end;
procedure TESDBTable.First;
begin
if not FActive then Exit;
FCurrentRecord:=1;
while not EOF do begin
if ReadCurrentRecord then Break;
FCurrentRecord:=FCurrentRecord + 1;
end;
end;
procedure TESDBTable.Last;
begin
if not FActive then Exit;
FCurrentRecord:=FTotalRecordsCount;
while not BOF do begin
if ReadCurrentRecord then Break;
FCurrentRecord:=FCurrentRecord - 1;
end;
end;
procedure TESDBTable.Next;
begin
if not FActive then Exit;
while not EOF do begin
FCurrentRecord:=FCurrentRecord + 1;
if EOF then Break;
if ReadCurrentRecord then Break;
end;
end;
procedure TESDBTable.Prior;
begin
if not FActive then Exit;
while not BOF do begin
FCurrentRecord:=FCurrentRecord - 1;
if BOF then Break;
if ReadCurrentRecord then Break;
end;
end;
function TESDBTable.ReadCurrentRecord:Boolean;
begin
if (FRecordBuffer = nil) then begin
GetMem(FRecordBuffer, FRecordSize);
FillChar(FRecordBuffer^, FRecordSize, 0);
end;
Result:=(FParent.GetTableRecord(FHandle, FCurrentRecord, FRecordBuffer, FRecordSize) = grrOK);
if Result then FLastGetRecord:=FCurrentRecord;
end;
function TESDBTable.EOF:Boolean;
begin
if not FActive then begin
Result:=True;
end else begin
Result:=(FCurrentRecord > FTotalRecordsCount);
end;
end;
function TESDBTable.BOF:Boolean;
begin
if not FActive then begin
Result:=True;
end else begin
Result:=(FCurrentRecord < 1);
end;
end;
function TESDBTable.Pack:Boolean;
begin
if not FActive then begin
Result:=False;
end else begin
Result:=FParent.PackTable(FHandle);
if Result then begin
FTotalRecordsCount:=FParent.GetTotalRecordsCount(FHandle);
FRealRecordsCount:=FParent.GetRealRecordsCount(FHandle);
FLastGetRecord:=-1;
First;
FEditMode:=emNone;
end;
end;
end;
end.