ACCESS3.BOX 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430
  1. (*********************************************************)
  2. (* *)
  3. (* TURBO-ACCESS for MS-DOS, PC-DOS *)
  4. (* *)
  5. (* Toolbox version: 1.21 *)
  6. (* *)
  7. (* ACCESS module *)
  8. (* *)
  9. (* Use with TURBO PASCAL 3.0 or later *)
  10. (* *)
  11. (* Copyright (C) 1984,85,86 by *)
  12. (* Borland International *)
  13. (* *)
  14. (*********************************************************)
  15. (*
  16. IMPORTANT:
  17. Use this file, ACCESS.BOX, when compiling with TURBO 3.0.
  18. Use ACCESS2.BOX when compiling with TURBO 2.0.
  19. *)
  20. (*$A+,I-,R-*)
  21. type
  22. TaStr64 = string[64];
  23. DataFile = record
  24. case Integer of
  25. 0 : (F : file;
  26. FirstFree,
  27. NumberFree,
  28. Int1,
  29. Int2,
  30. NumRec : Integer);
  31. 1 : (Fil2 : array[0..12] of Byte;
  32. TaName : array[1..64] of Char);
  33. end;
  34. TaKeyStr = string[MaxKeyLen];
  35. TaItem = record
  36. DataRef,PageRef : Integer;
  37. Key : TaKeyStr;
  38. end;
  39. TaPage = record
  40. ItemsOnPage : 0..PageSize;
  41. BckwPageRef : Integer;
  42. ItemArray : array[1..PageSize] of TaItem;
  43. end;
  44. TaPagePtr = ^TaPage;
  45. TaSearchStep =
  46. record
  47. PageRef,ItemArrIndex : Integer;
  48. end;
  49. TaPath = array[1..MaxHeight] of TaSearchStep;
  50. IndexFile = record
  51. DataF : DataFile;
  52. AllowDuplKeys : Boolean;
  53. KeyL,RR,PP : Integer;
  54. Path : TaPath;
  55. end;
  56. IndexFilePtr = ^IndexFile;
  57. TaStackRec = record
  58. Page : TaPage;
  59. IndexFPtr : IndexFilePtr;
  60. PageRef : Integer;
  61. Updated : Boolean;
  62. end;
  63. TaStackRecPtr = ^TaStackRec;
  64. TaPageStack = array[1..PageStackSize] of TaStackRec;
  65. TaPageMap = array[1..PageStackSize] of Integer;
  66. TaRecordBuffer =
  67. record
  68. case Integer of
  69. 0 : (Page : TaStackRec);
  70. 1 : (R : array[1..MaxDataRecSize] of Byte);
  71. 2 : (I : Integer);
  72. end;
  73. var
  74. IOstatus : Integer;
  75. OK : Boolean;
  76. TaRecBuf : TaRecordBuffer;
  77. TaPageStk : TaPageStack;
  78. TaPgMap : TaPageMap;
  79. procedure TaIOcheck(var DatF : DataFile; R : Integer);
  80. var
  81. I : Integer;
  82. begin
  83. if IOstatus <> 0 then with DatF do
  84. begin
  85. Writeln;
  86. Writeln('TURBO-access I/O error ',IOstatus);
  87. Write('File ');
  88. I := 1;
  89. while Ord(TaName[I]) <> 0 do
  90. begin
  91. Write(TaName[I]); I := Succ(I);
  92. end;
  93. Writeln(' Record ',R);
  94. Writeln('Program aborted');
  95. Halt;
  96. end;
  97. end;
  98. procedure GetRec(var DatF : DataFile;
  99. R : Integer;
  100. var Buffer );
  101. begin
  102. Seek(DatF.F,R);
  103. IOstatus := IOresult;
  104. TaIOcheck(DatF,R);
  105. BlockRead(DatF.F,Buffer,1);
  106. IOstatus := IOresult;
  107. TaIOcheck(DatF,R);
  108. end;
  109. procedure PutRec(var DatF : DataFile;
  110. R : Integer;
  111. var Buffer );
  112. begin
  113. Seek(DatF.F,R);
  114. IOstatus := IOresult;
  115. TaIOcheck(DatF,R);
  116. BlockWrite(DatF.F,Buffer,1);
  117. IOstatus := IOresult;
  118. TaIOcheck(DatF,R);
  119. end;
  120. procedure MakeFile(var DatF : DataFile;
  121. FName : TaStr64;
  122. RecLen : Integer);
  123. begin
  124. Assign(DatF.F,FName);
  125. IOstatus := IOresult;
  126. TaIOcheck(DatF, 0);
  127. Rewrite(DatF.F,RecLen);
  128. IOstatus := IOresult;
  129. if IOstatus = $F1 then
  130. OK := false
  131. else
  132. begin
  133. TaIOcheck(DatF,0);
  134. DatF.FirstFree := -1;
  135. DatF.NumberFree := 0;
  136. DatF.Int1 := 0;
  137. DatF.Int2 := 0;
  138. Move(DatF.FirstFree,TaRecBuf,8);
  139. PutRec(DatF,0,TaRecBuf);
  140. DatF.NumRec := 1;
  141. OK := true;
  142. end;
  143. end;
  144. procedure OpenFile(var DatF : DataFile;
  145. FName : TaStr64;
  146. RecLen : Integer);
  147. begin
  148. Assign(DatF.F,FName);
  149. IOstatus := IOresult;
  150. TaIOcheck(DatF,0);
  151. Reset(DatF.F,RecLen);
  152. IOstatus := IOresult;
  153. if IOstatus = 1 then OK := false
  154. else
  155. begin
  156. TaIOcheck(DatF,0);
  157. GetRec(DatF,0,TaRecBuf);
  158. Move(TaRecBuf,DatF.FirstFree,8);
  159. DatF.NumRec := FileSize(DatF.F);
  160. OK := true;
  161. end;
  162. end;
  163. procedure CloseFile(var DatF : DataFile);
  164. begin
  165. DatF.Int2 := DatF.NumRec;
  166. Move(DatF.FirstFree,TaRecBuf,8);
  167. PutRec(DatF,0,TaRecBuf);
  168. Close(DatF.F);
  169. IOstatus := IOresult;
  170. TaIOcheck(DatF,0);
  171. end;
  172. procedure NewRec(var DatF : DataFile;
  173. var R : Integer );
  174. begin
  175. if DatF.FirstFree = -1 then
  176. begin
  177. R := DatF.NumRec;
  178. DatF.NumRec := Succ(DatF.NumRec)
  179. end
  180. else
  181. begin
  182. R := DatF.FirstFree;
  183. GetRec(DatF,R,TaRecBuf);
  184. DatF.FirstFree := TaRecBuf.I;
  185. DatF.NumberFree := DatF.NumberFree - 1;
  186. end;
  187. end;
  188. procedure AddRec(var DatF : DataFile;
  189. var R : Integer;
  190. var Buffer );
  191. begin
  192. NewRec(DatF,R);
  193. PutRec(DatF,R,Buffer);
  194. end;
  195. procedure DeleteRec(var DatF : DataFile;
  196. R : Integer);
  197. begin
  198. TaRecBuf.I := DatF.FirstFree;
  199. PutRec(DatF,R,TaRecBuf);
  200. DatF.FirstFree := R;
  201. DatF.NumberFree := DatF.NumberFree + 1;
  202. end;
  203. function FileLen(var DatF : DataFile) : Integer;
  204. begin
  205. FileLen := DatF.NumRec;
  206. end;
  207. function UsedRecs(var DatF : DataFile) : Integer;
  208. begin
  209. UsedRecs := DatF.NumRec - DatF.NumberFree - 1;
  210. end;
  211. procedure InitIndex;
  212. var
  213. I : Integer;
  214. begin
  215. for I := 1 to PageStackSize do
  216. begin
  217. TaPageStk[I].IndexFPtr := nil;
  218. TaPageStk[I].Updated := false;
  219. TaPgMap[I] := I;
  220. end;
  221. end;
  222. procedure TaPack(var Page : TaPage;
  223. KeyL : Integer);
  224. var
  225. I : Integer;
  226. P : array[0..MaxInt] of Byte absolute Page;
  227. begin
  228. if KeyL <> MaxKeyLen then
  229. for I := 1 to PageSize do
  230. Move(Page.ItemArray[I],P[(I - 1) * (KeyL + 5) + 3],KeyL + 5);
  231. end;
  232. procedure TaUnpack(var Page : TaPage;
  233. KeyL : Integer);
  234. var
  235. I : Integer;
  236. P : array[0..MaxInt] of Byte absolute Page;
  237. begin
  238. if KeyL <> MaxKeyLen then
  239. for I := PageSize downto 1 do
  240. Move(P[(I - 1) * (KeyL + 5) + 3],Page.ItemArray[I],KeyL + 5);
  241. end;
  242. procedure MakeIndex(var IdxF : IndexFile;
  243. FName : TaStr64;
  244. KeyLen,
  245. S : Integer);
  246. var
  247. K : Integer;
  248. begin
  249. K := (KeyLen + 5)*PageSize + 3;
  250. MakeFile(IdxF.DataF,FName,K);
  251. IdxF.AllowDuplKeys := S <> 0;
  252. IdxF.KeyL := KeyLen;
  253. IdxF.RR := 0;
  254. IdxF.PP := 0;
  255. end;
  256. procedure OpenIndex(var IdxF : IndexFile;
  257. FName : TaStr64;
  258. KeyLen,
  259. S : Integer);
  260. var
  261. K : Integer;
  262. begin
  263. K := (KeyLen + 5) * PageSize + 3;
  264. OpenFile(IdxF.DataF,FName,K);
  265. IdxF.AllowDuplKeys := S <> 0;
  266. IdxF.KeyL := KeyLen;
  267. IdxF.RR := IdxF.DataF.Int1;
  268. IdxF.PP := 0;
  269. end;
  270. procedure CloseIndex(var IdxF : IndexFile);
  271. var
  272. I : Integer;
  273. begin
  274. for I := 1 to PageStackSize do
  275. with TaPageStk[I] do
  276. if IndexFPtr = Addr(IdxF) then
  277. begin
  278. IndexFPtr := nil;
  279. if Updated then
  280. begin
  281. TaPack(Page,IdxF.KeyL);
  282. PutRec(IdxF.DataF,PageRef,Page);
  283. Updated := false;
  284. end;
  285. end;
  286. IdxF.DataF.Int1 := IdxF.RR;
  287. CloseFile(IdxF.DataF);
  288. end;
  289. procedure TaLast(I : Integer);
  290. var
  291. J,K : Integer;
  292. begin
  293. J := 1;
  294. while (TaPgMap[J] <> I) and (J < PageStackSize) do
  295. J := J + 1;
  296. for K := J to PageStackSize - 1 do
  297. TaPgMap[K] := TaPgMap[K + 1];
  298. TaPgMap[PageStackSize] := I;
  299. end;
  300. procedure TaGetPage(var IdxF : IndexFile;
  301. R : Integer;
  302. var PgPtr : TaPagePtr);
  303. var
  304. I : Integer;
  305. Found : Boolean;
  306. begin
  307. I := 0;
  308. repeat
  309. I := I + 1;
  310. with TaPageStk[I] do
  311. Found := (IndexFPtr = Addr(IdxF)) and (PageRef = R);
  312. until Found or (I = PageStackSize);
  313. if not Found then
  314. begin
  315. I := TaPgMap[1];
  316. with TaPageStk[I] do
  317. begin
  318. if Updated then
  319. begin
  320. TaPack(Page,IndexFPtr^.KeyL);
  321. PutRec(IndexFPtr^.DataF,PageRef,Page);
  322. end;
  323. GetRec(IdxF.DataF,R,Page);
  324. TaUnpack(Page,IdxF.KeyL);
  325. IndexFPtr := Addr(IdxF);
  326. PageRef := R;
  327. Updated := false;
  328. end;
  329. end;
  330. TaLast(I);
  331. PgPtr := Addr(TaPageStk[I]);
  332. end;
  333. procedure TaNewPage(var IdxF : IndexFile;
  334. var R : Integer;
  335. var PgPtr : TaPagePtr);
  336. var
  337. I : Integer;
  338. begin
  339. I := TaPgMap[1];
  340. with TaPageStk[I] do
  341. begin
  342. if Updated then
  343. begin
  344. TaPack(Page,IndexFPtr^.KeyL);
  345. PutRec(IndexFPtr^.DataF,PageRef,Page);
  346. end;
  347. NewRec(IdxF.DataF,R);
  348. IndexFPtr := Addr(IdxF);
  349. PageRef := R;
  350. Updated := false;
  351. end;
  352. TaLast(I);
  353. PgPtr := Addr(TaPageStk[I]);
  354. end;
  355. procedure TaUpdatePage(PgPtr : TaPagePtr);
  356. var
  357. P : TaStackRecPtr absolute PgPtr;
  358. begin
  359. P^.Updated := true;
  360. end;
  361. procedure TaReturnPage(var PgPtr : TaPagePtr);
  362. var
  363. P : TaStackRecPtr absolute PgPtr;
  364. begin
  365. with P^ do
  366. begin
  367. DeleteRec(IndexFPtr^.DataF,PageRef);
  368. IndexFPtr := nil;
  369. Updated := false;
  370. end;
  371. end;
  372. procedure TaXKey(var K;
  373. KeyL : Integer);
  374. var
  375. Key : TaKeyStr absolute K;
  376. begin
  377. if Ord(Key[0]) > KeyL then Key[0] := Chr(KeyL);
  378. end;
  379. function TaCompKeys(var K1,
  380. K2;
  381. DR1,
  382. DR2 : Integer;
  383. Dup : Boolean ) : Integer;
  384. var
  385. Key1 : TaKeyStr absolute K1;
  386. Key2 : TaKeyStr absolute K2;
  387. begin
  388. if Key1 = Key2 then
  389. if Dup then
  390. TaCompKeys := DR1 - DR2
  391. else TaCompKeys := 0
  392. else
  393. if Key1 > Key2 then
  394. TaCompKeys := 1
  395. else TaCompKeys := - 1;
  396. end;
  397. procedure ClearKey(var IdxF : IndexFile);
  398. begin
  399. IdxF.PP := 0;
  400. end;
  401.