home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / Pascal / BPASCAL.700 / D12 / PXWIN.ZIP / PXACCESS.PAS next >
Encoding:
Pascal/Delphi Source File  |  1992-10-01  |  6.4 KB  |  279 lines

  1. {************************************************}
  2. {                                                }
  3. {   Paradox Engine demo access unit              }
  4. {   Copyright (c) 1991 by Borland International  }
  5. {                                                }
  6. {************************************************}
  7.  
  8. unit PXAccess;
  9.  
  10. interface
  11.  
  12. {$N+}
  13.  
  14. uses Objects, PXEngine;
  15.  
  16. type
  17.   PFieldArray = ^TFieldArray;
  18.   TFieldArray = array[1..256] of PChar;
  19.  
  20. type
  21.   PPXTable = ^TPXTable;
  22.   TPXTable = object(TObject)
  23.     Status: Integer;
  24.     constructor Init(TableName: PChar);
  25.     destructor Done; virtual;
  26.     procedure ClearError;
  27.     function FieldName(Field: Integer): PChar;
  28.     function FieldType(Field: Integer): PChar;
  29.     function FieldWidth(Field: Integer): Integer;
  30.     function GetField(Rec, Fld: Integer): PChar;
  31.     function NumRecords: LongInt;
  32.     function NumFields: Integer;
  33.     procedure PXError(Error: Integer); virtual;
  34.   private
  35.     CurRecord: Integer;
  36.     TblHandle: TableHandle;
  37.     RecHandle: RecordHandle;
  38.     NumFlds: Integer;
  39.     NumRecs: LongInt;
  40.     FieldNames: PFieldArray;
  41.     FieldTypes: PFieldArray;
  42.     Cache: Pointer;
  43.     function CheckError(Code: Integer): Boolean;
  44.   end;
  45.  
  46. implementation
  47.  
  48. uses WinTypes, WinProcs, Strings;
  49.  
  50. type
  51.   PCache = ^TCache;
  52.   TCache = object(TCollection)
  53.     constructor Init(CacheSize: Integer);
  54.     procedure Add(Index: LongInt; P: PChar);
  55.     function Get(Index: LongInt): PChar;
  56.     procedure FreeItem(P: Pointer); virtual;
  57.   end;
  58.  
  59. type
  60.   PCacheElement = ^TCacheElement;
  61.   TCacheElement = record
  62.     Index: LongInt;
  63.     Item: PChar;
  64.   end;
  65.  
  66. constructor TCache.Init(CacheSize: Integer);
  67. begin
  68.   TCollection.Init(CacheSize, 0);
  69. end;
  70.  
  71. procedure TCache.Add(Index: LongInt; P: PChar);
  72. var
  73.   CE: PCacheElement;
  74. begin
  75.   New(CE);
  76.   CE^.Index := Index;
  77.   CE^.Item := P;
  78.   if Count = Limit then AtFree(Count - 1);
  79.   AtInsert(0, CE);
  80. end;
  81.  
  82. function TCache.Get(Index: LongInt): PChar;
  83. var
  84.   P: PCacheElement;
  85.  
  86.   function ItemWithIndex(P: PCacheElement): Boolean; far;
  87.   begin
  88.     ItemWithIndex := P^.Index = Index;
  89.   end;
  90.  
  91. begin
  92.   Get := nil;
  93.   P := FirstThat(@ItemWithIndex);
  94.   if P <> nil then Get := P^.Item;
  95. end;
  96.  
  97. procedure TCache.FreeItem(P: Pointer);
  98. begin
  99.   StrDispose(PCacheElement(P)^.Item);
  100.   Dispose(P);
  101. end;
  102.  
  103. { TPXTable }
  104.  
  105. constructor TPXTable.Init(TableName: PChar);
  106. var
  107.   Temp: array[0..25] of Char;
  108.   I: Integer;
  109. begin
  110.   FieldTypes := nil;
  111.   FieldNames := nil;
  112.   Status := 0;
  113.   CurRecord := -1;
  114.   if CheckError(PXTblOpen(TableName, TblHandle, 0, True)) and
  115.      CheckError(PXRecBufOpen(TblHandle, RecHandle)) and
  116.      CheckError(PXRecBufOpen(tblHandle, recHandle)) and
  117.      CheckError(PXRecNFlds(tblHandle, NumFlds)) and
  118.      CheckError(PXTblNRecs(tblHandle, NumRecs)) then
  119.   begin
  120.     GetMem(FieldTypes, NumFields * SizeOf(PChar));
  121.     GetMem(FieldNames, NumFields * SizeOf(PChar));
  122.     for I := 1 to NumFields do
  123.     begin
  124.       CheckError(PXFldName(TblHandle, I, SizeOf(Temp), Temp));
  125.       FieldNames^[I] := StrNew(Temp);
  126.       CheckError(PXFldType(TblHandle, I, SizeOf(Temp), Temp));
  127.       FieldTypes^[I] := StrNew(Temp);
  128.     end;
  129.     Cache := New(PCache, Init(300));
  130.   end;
  131. end;
  132.  
  133. destructor TPXTable.Done;
  134. var
  135.   I: Integer;
  136. begin
  137.   PXRecBufClose(RecHandle);
  138.   PXTblClose(TblHandle);
  139.   if (FieldTypes <> nil) and (FieldNames <> nil) then
  140.     for I := 1 to NumFields do
  141.     begin
  142.       StrDispose(FieldNames^[I]);
  143.       StrDispose(FieldTypes^[I]);
  144.     end;
  145.   if FieldTypes <> nil then FreeMem(FieldTypes, NumFields * SizeOf(PChar));
  146.   if FieldNames <> nil then FreeMem(FieldNames, NumFields * SizeOf(PChar));
  147.   if Cache <> nil then Dispose(PCache(Cache), Done);
  148.   TObject.Done;
  149. end;
  150.  
  151. function TPXTable.CheckError(Code: Integer): Boolean;
  152. begin
  153.   if Status = 0 then
  154.   begin
  155.     if Code <> 0 then PXError(Code);
  156.     Status := Code;
  157.   end;
  158.   CheckError := Status = 0;
  159. end;
  160.  
  161. procedure TPXTable.ClearError;
  162. begin
  163.   Status := 0;
  164. end;
  165.  
  166. function TPXTable.FieldName(Field: Integer): PChar;
  167. begin
  168.   FieldName := FieldNames^[Field];
  169. end;
  170.  
  171. function TPXTable.FieldType(Field: Integer): PChar;
  172. begin
  173.   FieldType := FieldTypes^[Field];
  174. end;
  175.  
  176. function TPXTable.FieldWidth(Field: Integer): Integer;
  177. var
  178.   Width, Code: Integer;
  179. begin
  180.   case FieldTypes^[Field][0] of
  181.     'N',
  182.     '$': FieldWidth := 14;
  183.     'A':
  184.       begin
  185.     Val(PChar(@FieldTypes^[Field][1]), Width, Code);
  186.     FieldWidth := Width
  187.       end;
  188.     'D': FieldWidth := 12;
  189.     'S': FieldWidth := 8;
  190.   else
  191.     FieldWidth := 0;
  192.   end;
  193. end;
  194.  
  195. function TPXTable.GetField(Rec, Fld: Integer): PChar;
  196. const
  197.   TheData: array[0..255] of Char = '';
  198. var
  199.   Tmp: array[0..255] of Char;
  200.   N: Double;
  201.   I: Integer;
  202.   L: LongInt;
  203.   ArgList: array[0..2] of Integer;
  204.   Index: LongInt;
  205.   P: PChar;
  206. begin
  207.   TheData[0] := #0;
  208.   GetField := TheData;
  209.   if Status <> 0 then Exit;
  210.   if (Rec < 1) or (Rec > NumRecords) then Exit;
  211.   if (Fld < 1) or (Fld > NumFields) then Exit;
  212.   Index := Rec * NumFields + Fld;
  213.   P := PCache(Cache)^.Get(Index);
  214.   if P = nil then
  215.   begin
  216.     if Rec <> CurRecord then
  217.     begin
  218.       CheckError(PXRecGoto(TblHandle, Rec));
  219.       CheckError(PXRecGet(TblHandle, RecHandle));
  220.       CurRecord := Rec;
  221.     end;
  222.     FillChar(TheData, SizeOf(TheData), ' ');
  223.     Tmp[0] := #0;
  224.     case FieldTypes^[Fld][0] of
  225.       'A':
  226.     CheckError(PXGetAlpha(RecHandle, Fld, SizeOf(Tmp), Tmp));
  227.       'N':
  228.     begin
  229.       CheckError(PXGetDoub(RecHandle, Fld, N));
  230.       if not IsBlankDouble(N) then
  231.         Str(N:12:4, Tmp);
  232.     end;
  233.       '$':
  234.     begin
  235.       CheckError(PXGetDoub(RecHandle, Fld, N));
  236.       if not IsBlankDouble(N) then
  237.         Str(N:12:2, Tmp);
  238.     end;
  239.       'S':
  240.     begin
  241.       CheckError(PXGetShort(RecHandle, Fld, I));
  242.       if not IsBlankShort(i) then
  243.         Str(I:6, Tmp)
  244.     end;
  245.       'D':
  246.     begin
  247.       CheckError(PXGetDate(RecHandle, Fld, L));
  248.       if Not IsBlankDate(L) then
  249.       begin
  250.         CheckError(PXDateDecode(L, ArgList[0], ArgList[1], ArgList[2]));
  251.         wvSprintf(Tmp, '%2d/%2d/%4d', ArgList);
  252.       end;
  253.     end;
  254.     end;
  255.     StrMove(TheData, Tmp, StrLen(Tmp));
  256.     TheData[FieldWidth(Fld)] := #0;
  257.     PCache(Cache)^.Add(Index, StrNew(TheData));
  258.   end
  259.   else
  260.     GetField := P;
  261. end;
  262.  
  263. function TPXTable.NumRecords: LongInt;
  264. begin
  265.   NumRecords := NumRecs;
  266. end;
  267.  
  268. function TPXTable.NumFields: Integer;
  269. begin
  270.   NumFields := NumFlds;
  271. end;
  272.  
  273. procedure TPXTable.PXError(Error: Integer);
  274. begin
  275.   MessageBox(GetFocus, PXErrMsg(Error), 'PXAccess', mb_OK)
  276. end;
  277.  
  278. end.
  279.