bufdataset.inc 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999-2000 by Michael Van Canneyt, member of the
  5. Free Pascal development team
  6. BufDataset implementation
  7. See the file COPYING.FPC, included in this distribution,
  8. for details about the copyright.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. **********************************************************************}
  13. { ---------------------------------------------------------------------
  14. TBufDataSet
  15. ---------------------------------------------------------------------}
  16. constructor TBufDataset.Create(AOwner : TComponent);
  17. begin
  18. Inherited Create(AOwner);
  19. SetLength(FUpdateBuffer,0);
  20. BookmarkSize := sizeof(TBufBookmark);
  21. // temporary set it here
  22. FPacketRecords := 10;
  23. end;
  24. destructor TBufDataset.Destroy;
  25. begin
  26. inherited destroy;
  27. end;
  28. Function TBufDataset.GetCanModify: Boolean;
  29. begin
  30. Result:= False;
  31. end;
  32. function TBufDataset.AllocRecordBuffer: PChar;
  33. begin
  34. result := AllocMem(FRecordsize + sizeof(TBufBookmark));
  35. result^ := #1; // this 'deletes' the record
  36. end;
  37. procedure TBufDataset.FreeRecordBuffer(var Buffer: PChar);
  38. begin
  39. ReAllocMem(Buffer,0);
  40. end;
  41. procedure TBufDataset.InternalOpen;
  42. begin
  43. CalcRecordSize;
  44. FBRecordcount := 0;
  45. FBDeletedRecords := 0;
  46. FBBuffercount := 0;
  47. FBCurrentrecord := -1;
  48. FOpen:=True;
  49. FIsEOF := false;
  50. FIsbOF := true;
  51. end;
  52. procedure TBufDataset.InternalClose;
  53. var i : integer;
  54. begin
  55. FOpen:=False;
  56. CancelUpdates;
  57. for i := 0 to FBRecordCount-1 do FreeRecordBuffer(FBBuffers[i]);
  58. If FBRecordCount > 0 then ReAllocMem(FBBuffers,0);
  59. FBRecordcount := 0;
  60. FBBuffercount := 0;
  61. FBCurrentrecord := -1;
  62. FIsEOF := true;
  63. FIsbOF := true;
  64. end;
  65. procedure TBufDataset.InternalFirst;
  66. begin
  67. FBCurrentRecord := -1;
  68. FIsEOF := false;
  69. end;
  70. procedure TBufDataset.InternalLast;
  71. begin
  72. repeat
  73. until getnextpacket < FPacketRecords;
  74. FIsBOF := false;
  75. FBCurrentRecord := FBRecordcount;
  76. end;
  77. procedure unSetDeleted(NullMask : pbyte); //inline;
  78. begin
  79. NullMask[0] := NullMask[0] and not 1;
  80. end;
  81. procedure SetDeleted(NullMask : pbyte); //inline;
  82. begin
  83. NullMask[0] := NullMask[0] or 1;
  84. end;
  85. function GetDeleted(NullMask : pbyte) : boolean; //inline;
  86. begin
  87. result := (NullMask[0] and 1) = 1;
  88. end;
  89. procedure unSetFieldIsNull(NullMask : pbyte;x : longint); //inline;
  90. begin
  91. inc(x);
  92. NullMask[x div 8] := (NullMask[x div 8]) and not (1 shl (x mod 8));
  93. end;
  94. procedure SetFieldIsNull(NullMask : pbyte;x : longint); //inline;
  95. begin
  96. inc(x);
  97. NullMask[x div 8] := (NullMask[x div 8]) or (1 shl (x mod 8));
  98. end;
  99. function GetFieldIsNull(NullMask : pbyte;x : longint) : boolean; //inline;
  100. begin
  101. inc(x);
  102. result := ord(NullMask[x div 8]) and (1 shl (x mod 8)) > 0
  103. end;
  104. function TBufDataset.GetRecord(Buffer: PChar; GetMode: TGetMode; DoCheck: Boolean): TGetResult;
  105. var x : longint;
  106. RecUpdBuf : PRecUpdateBuffer;
  107. FieldUpdBuf : PFieldUpdateBuffer;
  108. NullMask : pbyte;
  109. begin
  110. Result := grOK;
  111. case GetMode of
  112. gmPrior :
  113. if FIsBOF then
  114. result := grBOF
  115. else if FBCurrentRecord <= 0 then
  116. begin
  117. Result := grBOF;
  118. FBCurrentRecord := -1;
  119. end
  120. else
  121. begin
  122. Dec(FBCurrentRecord);
  123. FIsEof := false;
  124. end;
  125. gmCurrent :
  126. if (FBCurrentRecord < 0) or (FBCurrentRecord >= FBRecordCount) then
  127. Result := grError;
  128. gmNext :
  129. if FIsEOF then
  130. result := grEOF
  131. else if FBCurrentRecord >= (FBRecordCount - 1) then
  132. begin
  133. if getnextpacket > 0 then
  134. begin
  135. Inc(FBCurrentRecord);
  136. FIsBof := false;
  137. end
  138. else
  139. begin
  140. FIsEOF := true;
  141. result:=grEOF;
  142. end
  143. end
  144. else
  145. begin
  146. Inc(FBCurrentRecord);
  147. FIsBof := false;
  148. end;
  149. end;
  150. if Result = grOK then
  151. begin
  152. if GetDeleted(pbyte(FBBuffers[FBCurrentRecord])) then
  153. begin
  154. if getmode = gmCurrent then
  155. if DoCheck then
  156. begin
  157. Result := grError;
  158. DatabaseError(SDeletedRecord);
  159. exit;
  160. end
  161. else
  162. getmode := gmnext;
  163. Result := GetRecord(Buffer,getmode,DoCheck);
  164. exit
  165. end;
  166. with PBufBookmark(Buffer + RecordSize)^ do
  167. begin
  168. BookmarkData := FBCurrentRecord;
  169. BookmarkFlag := bfCurrent;
  170. end;
  171. move(FBBuffers[FBCurrentRecord]^,buffer^,RecordSize);
  172. // Cached Updates:
  173. If GetRecordUpdateBuffer(FBCurrentRecord,RecUpdBuf) then
  174. begin
  175. NullMask := pbyte(buffer);
  176. inc(buffer,FNullmaskSize);
  177. for x := 0 to FieldDefs.count-1 do
  178. begin
  179. if GetFieldUpdateBuffer(x,RecUpdBuf,FieldUpdBuf) then
  180. If not FieldUpdBuf^.IsNull then
  181. begin
  182. unSetFieldIsNull(NullMask,x);
  183. move(FieldUpdBuf^.NewValue^,buffer^,GetFieldSize(FieldDefs[x]));
  184. end
  185. else
  186. SetFieldIsNull(NullMask,x);
  187. Inc(Buffer, GetFieldSize(FieldDefs[x]));
  188. end;
  189. end;
  190. end
  191. else if (Result = grError) and doCheck then
  192. DatabaseError('No record');
  193. end;
  194. function TBufDataset.GetRecordUpdateBuffer(rno : integer;var RecUpdBuf : PRecUpdateBuffer) : boolean;
  195. var r : integer;
  196. begin
  197. Result := False;
  198. for r := 0 to high(FUpdateBuffer) do
  199. if (FUpdateBuffer[r].RecordNo = rno) and (@FUpdateBuffer[r] <> FEditBuf) then // Neglect the edit-buffer
  200. begin
  201. RecUpdBuf := @FUpdateBuffer[r];
  202. Result := True;
  203. Break;
  204. end;
  205. end;
  206. function TBufDataset.GetFieldUpdateBuffer(fieldno : integer;RecUpdBuf : PRecUpdateBuffer;var FieldUpdBuf : pFieldUpdateBuffer) : boolean;
  207. var f : integer;
  208. begin
  209. Result := False;
  210. for f := 0 to High(RecUpdBuf^.FieldsUpdateBuffer) do
  211. if RecUpdBuf^.FieldsUpdateBuffer[f].FieldNo = fieldno then
  212. begin
  213. FieldUpdBuf := @RecUpdBuf^.FieldsUpdateBuffer[f];
  214. Result := True;
  215. Break;
  216. end;
  217. end;
  218. procedure TBufDataset.InternalSetToRecord(Buffer: PChar);
  219. begin
  220. FBCurrentRecord := PBufBookmark(Buffer + RecordSize)^.BookmarkData;
  221. FIsEOF := False;
  222. FIsBOF := False;
  223. end;
  224. procedure TBufDataset.SetBookmarkData(Buffer: PChar; Data: Pointer);
  225. begin
  226. PBufBookmark(Buffer + RecordSize)^.BookmarkData := PInteger(Data)^;
  227. end;
  228. procedure TBufDataset.SetBookmarkFlag(Buffer: PChar; Value: TBookmarkFlag);
  229. begin
  230. PBufBookmark(Buffer + RecordSize)^.BookmarkFlag := Value;
  231. end;
  232. procedure TBufDataset.GetBookmarkData(Buffer: PChar; Data: Pointer);
  233. begin
  234. PInteger(Data)^ := PBufBookmark(Buffer + RecordSize)^.BookmarkData;
  235. end;
  236. function TBufDataset.GetBookmarkFlag(Buffer: PChar): TBookmarkFlag;
  237. begin
  238. Result := PBufBookmark(Buffer + RecordSize)^.BookmarkFlag;
  239. end;
  240. procedure TBufDataset.InternalGotoBookmark(ABookmark: Pointer);
  241. begin
  242. FBCurrentRecord := Plongint(ABookmark)^;
  243. FIsEOF := False;
  244. FIsBOF := False;
  245. end;
  246. function TBufDataset.getnextpacket : integer;
  247. var i : integer;
  248. b : boolean;
  249. begin
  250. i := 0;
  251. if FPacketRecords > 0 then
  252. begin
  253. if FBBufferCount < FBRecordCount+FPacketRecords then
  254. begin
  255. FBBufferCount := FBBuffercount + FPacketRecords;
  256. ReAllocMem(FBBuffers,FBBuffercount*SizeOf(PChar));
  257. end;
  258. repeat
  259. FBBuffers[FBRecordCount+i] := AllocRecordBuffer;
  260. b := (loadbuffer(FBBuffers[FBRecordCount+i])<>grOk);
  261. inc(i);
  262. until (i = FPacketRecords) or b;
  263. if b then
  264. begin
  265. dec(i);
  266. FreeRecordBuffer(FBBuffers[FBRecordCount+i]);
  267. end;
  268. FBRecordCount := FBRecordCount + i;
  269. end;
  270. result := i;
  271. end;
  272. function TBufDataset.GetFieldSize(FieldDef : TFieldDef) : longint;
  273. begin
  274. case FieldDef.DataType of
  275. ftString : result := FieldDef.Size + 1;
  276. ftSmallint,
  277. ftInteger,
  278. ftword : result := sizeof(longint);
  279. ftBoolean : result := sizeof(wordbool);
  280. ftBCD : result := sizeof(currency);
  281. ftFloat : result := sizeof(double);
  282. ftTime,
  283. ftDate,
  284. ftDateTime : result := sizeof(TDateTime)
  285. else Result := 10
  286. end;
  287. end;
  288. function TBufDataset.LoadBuffer(Buffer : PChar): TGetResult;
  289. var NullMask : pbyte;
  290. x : longint;
  291. begin
  292. if not Fetch then
  293. begin
  294. Result := grEOF;
  295. Exit;
  296. end;
  297. NullMask := pointer(buffer);
  298. fillchar(Nullmask^,FNullmaskSize,0);
  299. inc(buffer,FNullmaskSize);
  300. for x := 0 to FieldDefs.count-1 do
  301. begin
  302. if not LoadField(FieldDefs[x],buffer) then
  303. SetFieldIsNull(NullMask,x);
  304. inc(buffer,GetFieldSize(FieldDefs[x]));
  305. end;
  306. Result := grOK;
  307. end;
  308. function TBufDataset.GetFieldData(Field: TField; Buffer: Pointer): Boolean;
  309. var
  310. x : longint;
  311. CurrBuff : pchar;
  312. begin
  313. Result := False;
  314. If Field.Fieldno > 0 then // If = 0, then calculated field or something similar
  315. begin
  316. if state = dsOldValue then
  317. begin
  318. if FApplyingUpdates then
  319. CurrBuff := FBBuffers[fbcurrentrecord] // This makes it possible for ApplyUpdates to get values from deleted records
  320. else
  321. CurrBuff := FBBuffers[GetRecNo];
  322. end
  323. else
  324. begin
  325. CurrBuff := ActiveBuffer;
  326. if not assigned(CurrBuff) or GetDeleted(pbyte(CurrBuff)) then
  327. begin
  328. result := false;
  329. exit;
  330. end;
  331. end;
  332. if GetFieldIsnull(pbyte(CurrBuff),Field.Fieldno-1) then
  333. begin
  334. result := false;
  335. exit;
  336. end;
  337. inc(Currbuff,FNullmaskSize);
  338. for x := 0 to FieldDefs.count-1 do
  339. begin
  340. if (Field.FieldName = FieldDefs[x].Name) then
  341. begin
  342. // a nil-buffer is allowed for the fields.isNull function
  343. if assigned(buffer) then Move(CurrBuff^, Buffer^, GetFieldSize(FieldDefs[x]));
  344. Result := True;
  345. Break;
  346. end
  347. else Inc(CurrBuff, GetFieldSize(FieldDefs[x]));
  348. end;
  349. end;
  350. end;
  351. procedure TBufDataset.SetFieldData(Field: TField; Buffer: Pointer);
  352. var
  353. x : longint;
  354. CurrBuff : pointer;
  355. NullMask : pbyte;
  356. FieldUpdBuf : PFieldUpdateBuffer;
  357. begin
  358. if not (state in [dsEdit, dsInsert]) then
  359. begin
  360. DatabaseErrorFmt(SNotInEditState,[NAme],self);
  361. exit;
  362. end;
  363. If Field.Fieldno > 0 then // If = 0, then calculated field or something
  364. begin
  365. CurrBuff := ActiveBuffer;
  366. NullMask := CurrBuff;
  367. inc(Currbuff,FNullmaskSize);
  368. for x := 0 to FieldDefs.count-1 do
  369. begin
  370. if (Field.FieldName = FieldDefs[x].Name) then
  371. begin
  372. if assigned(buffer) then
  373. begin
  374. Move(Buffer^, CurrBuff^, GetFieldSize(FieldDefs[x]));
  375. unSetFieldIsNull(NullMask,x);
  376. end
  377. else
  378. SetFieldIsNull(NullMask,x);
  379. // cached updates
  380. with FEditBuf^ do
  381. begin
  382. if not GetFieldUpdateBuffer(x,FEditBuf,FieldUpdBuf) then
  383. begin
  384. SetLength(FieldsUpdateBuffer,length(FieldsUpdateBuffer)+1);
  385. FieldUpdBuf := @FieldsUpdateBuffer[high(FieldsUpdateBuffer)];
  386. GetMem(FieldUpdBuf^.NewValue,GetFieldSize(FieldDefs[x]));
  387. FieldUpdBuf^.FieldNo := x;
  388. end;
  389. if assigned(buffer) then
  390. begin
  391. Move(Buffer^, FieldUpdBuf^.NewValue^, GetFieldSize(FieldDefs[x]));
  392. FieldUpdBuf^.IsNull := False;
  393. end
  394. else FieldUpdBuf^.IsNull := True;
  395. end;
  396. Break;
  397. end
  398. else Inc(CurrBuff, GetFieldSize(FieldDefs[x]));
  399. end;
  400. if not (State in [dsCalcFields, dsFilter, dsNewValue]) then
  401. DataEvent(deFieldChange, Ptrint(Field));
  402. end;
  403. end;
  404. procedure TBufDataset.InternalEdit;
  405. begin
  406. if not GetRecordUpdateBuffer(recno,FEditBuf) then
  407. begin
  408. If not assigned(FEditBuf) then
  409. begin
  410. SetLength(FUpdateBuffer,length(FUpdateBuffer)+1);
  411. FEditBuf := @FUpdateBuffer[high(FUpdateBuffer)];
  412. end;
  413. FEditBuf^.UpdateKind := ukModify;
  414. FEditBuf^.RecordNo := getrecno;
  415. end;
  416. end;
  417. procedure TBufDataset.InternalInsert;
  418. begin
  419. if FBRecordCount > FBBufferCount-1 then
  420. begin
  421. inc(FBBufferCount);
  422. ReAllocMem(FBBuffers,FBBuffercount*SizeOf(PChar));
  423. end;
  424. inc(FBRecordCount);
  425. FBCurrentRecord := FBRecordCount -1;
  426. FBBuffers[FBCurrentRecord] := AllocRecordBuffer;
  427. fillchar(FBBuffers[FBCurrentRecord]^,FNullmaskSize,255);
  428. unSetDeleted(pbyte(FBBuffers[FBCurrentRecord]));
  429. fillchar(ActiveBuffer^,FNullmaskSize,255);
  430. unSetDeleted(pbyte(ActiveBuffer));
  431. // cached updates:
  432. If not assigned(FEditBuf) then
  433. begin
  434. SetLength(FUpdateBuffer,length(FUpdateBuffer)+1);
  435. FEditBuf := @FUpdateBuffer[high(FUpdateBuffer)];
  436. end;
  437. FEditBuf^.RecordNo := FBCurrentRecord;
  438. FEditBuf^.UpdateKind := ukInsert;
  439. with PBufBookmark(ActiveBuffer + RecordSize)^ do
  440. begin
  441. BookmarkData := FBCurrentRecord;
  442. BookmarkFlag := bfInserted;
  443. end;
  444. end;
  445. procedure TBufDataset.InternalDelete;
  446. var tel : integer;
  447. begin
  448. SetDeleted(pbyte(FBBuffers[FBCurrentRecord]));
  449. SetDeleted(pbyte(ActiveBuffer));
  450. inc(FBDeletedRecords);
  451. if GetRecordUpdateBuffer(recno,FEditBuf) and (FEditBuf^.UpdateKind = ukInsert) then
  452. begin
  453. if assigned(FEditBuf^.FieldsUpdateBuffer) then
  454. for tel := 0 to high(FEditBuf^.FieldsUpdateBuffer) do
  455. if not FEditBuf^.FieldsUpdateBuffer[tel].IsNull then
  456. freemem(FEditBuf^.FieldsUpdateBuffer[tel].NewValue);
  457. setlength(FEditBuf^.FieldsUpdateBuffer,0);
  458. FEditBuf^.RecordNo := -1;
  459. end
  460. else
  461. begin
  462. If not assigned(FEditBuf) then
  463. begin
  464. SetLength(FUpdateBuffer,length(FUpdateBuffer)+1);
  465. FEditBuf := @FUpdateBuffer[high(FUpdateBuffer)];
  466. end;
  467. FEditBuf^.RecordNo := FBCurrentRecord;
  468. FEditBuf^.UpdateKind := ukDelete;
  469. end;
  470. FEditBuf := nil;
  471. end;
  472. function TBufDataset.ApplyRecUpdate(UpdateKind : TUpdateKind) : boolean;
  473. begin
  474. Result := False;
  475. end;
  476. procedure TBufDataset.CancelUpdates;
  477. var r,f : integer;
  478. begin
  479. for r := 0 to high(FUpdateBuffer) do
  480. begin
  481. if FUpdateBuffer[r].RecordNo > -1 then
  482. if FUpdateBuffer[r].UpdateKind = ukDelete then
  483. begin
  484. dec(FBDeletedRecords);
  485. unSetDeleted(pbyte(FBBuffers[FUpdateBuffer[r].RecordNo]));
  486. end
  487. else if FUpdateBuffer[r].UpdateKind = ukInsert then
  488. begin
  489. inc(FBDeletedRecords);
  490. SetDeleted(pbyte(FBBuffers[FUpdateBuffer[r].RecordNo]));
  491. end;
  492. for f := 0 to high(FUpdateBuffer[r].FieldsUpdateBuffer) do
  493. FreeMem(FUpdateBuffer[r].FieldsUpdateBuffer[f].newvalue);
  494. end;
  495. SetLength(FUpdateBuffer,0);
  496. if FOpen then Resync([]);
  497. end;
  498. procedure TBufDataset.ApplyUpdates;
  499. var SaveBookmark : Integer;
  500. r,i : Integer;
  501. buffer : PChar;
  502. x : integer;
  503. FieldUpdBuf : PFieldUpdateBuffer;
  504. NullMask : pbyte;
  505. begin
  506. CheckBrowseMode;
  507. SaveBookMark := GetRecNo;
  508. r := 0;
  509. while r < Length(FUpdateBuffer) do
  510. begin
  511. if (@FUpdateBuffer[r] <> FEditBuf) and // Neglect edit-buffer
  512. (FUpdateBuffer[r].RecordNo <> -1) then // And the 'deleted' buffers
  513. begin
  514. FApplyingUpdates := true;
  515. if FUpdateBuffer[r].UpdateKind = ukDelete then
  516. InternalGotoBookmark(@(FUpdateBuffer[r].RecordNo))
  517. else
  518. SetRecNo(FUpdateBuffer[r].RecordNo);
  519. if ApplyRecUpdate(FUpdateBuffer[r].UpdateKind) then
  520. begin
  521. buffer := FBBuffers[FUpdateBuffer[r].RecordNo];
  522. NullMask := pbyte(buffer);
  523. inc(buffer,FNullmaskSize);
  524. for x := 0 to FieldDefs.count-1 do
  525. begin
  526. if GetFieldUpdateBuffer(x,@FUpdateBuffer[r],FieldUpdBuf) then
  527. If not FieldUpdBuf^.IsNull then
  528. begin
  529. unSetFieldIsNull(NullMask,x);
  530. move(FieldUpdBuf^.NewValue^,buffer^,GetFieldSize(FieldDefs[x]));
  531. FreeMem(FieldUpdBuf^.NewValue);
  532. end
  533. else
  534. SetFieldIsNull(NullMask,x);
  535. Inc(Buffer, GetFieldSize(FieldDefs[x]));
  536. end;
  537. for i := r to high(FUpdateBuffer)-1 do
  538. FUpdateBuffer[i] := FupdateBuffer[i+1];
  539. dec(r);
  540. SetLength(FUpdateBuffer,high(FUpdateBuffer));
  541. end;
  542. FApplyingUpdates := False;
  543. end;
  544. inc(r);
  545. end;
  546. Refresh;
  547. if not GetDeleted(pbyte(FBBuffers[savebookmark])) then
  548. SetRecNo(SaveBookMark);
  549. end;
  550. procedure TBufDataset.InternalPost;
  551. begin
  552. if state in [dsEdit, dsInsert] then
  553. begin
  554. if Length(FUpdateBuffer[High(FUpdateBuffer)].FieldsUpdateBuffer) > 0 then
  555. FEditBuf := nil;
  556. end;
  557. end;
  558. procedure TBufDataset.InternalCancel;
  559. var tel : integer;
  560. begin
  561. if state in [dsEdit, dsInsert] then
  562. begin
  563. if state = dsInsert then
  564. begin
  565. SetDeleted(pbyte(FBBuffers[FBCurrentRecord]));
  566. SetDeleted(pbyte(ActiveBuffer));
  567. inc(FBDeletedRecords);
  568. end;
  569. FEditBuf^.RecordNo := -1;
  570. // clear the fieldbuffers
  571. if assigned(FEditBuf^.FieldsUpdateBuffer) then
  572. for tel := 0 to high(FEditBuf^.FieldsUpdateBuffer) do
  573. if not FEditBuf^.FieldsUpdateBuffer[tel].IsNull then
  574. freemem(FEditBuf^.FieldsUpdateBuffer[tel].NewValue);
  575. setlength(FEditBuf^.FieldsUpdateBuffer,0);
  576. end;
  577. end;
  578. procedure TBufDataset.CalcRecordSize;
  579. var x : longint;
  580. begin
  581. FNullmaskSize := 1+((FieldDefs.count) div 8);
  582. FRecordSize := FNullmaskSize;
  583. for x := 0 to FieldDefs.count-1 do
  584. inc(FRecordSize, GetFieldSize(FieldDefs[x]));
  585. end;
  586. function TBufDataset.GetRecordSize : Word;
  587. begin
  588. result := FRecordSize;
  589. end;
  590. procedure TBufDataset.InternalInitRecord(Buffer: PChar);
  591. begin
  592. FillChar(Buffer^, FRecordSize, #0);
  593. end;
  594. procedure TBufDataset.SetRecNo(Value: Longint);
  595. begin
  596. GotoBookmark(@value);
  597. end;
  598. function TBufDataset.GetRecNo: Longint;
  599. begin
  600. GetBookmarkData(ActiveBuffer,@Result);
  601. end;
  602. function TBufDataset.IsCursorOpen: Boolean;
  603. begin
  604. Result := FOpen;
  605. end;
  606. Function TBufDataset.GetRecordCount: Longint;
  607. begin
  608. Result := FBRecordCount-FBDeletedRecords;
  609. end;