dataset.inc 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503
  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. Dataset 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. TDataSet
  15. ---------------------------------------------------------------------}
  16. Const
  17. DefaultBufferCount = 10;
  18. constructor TDataSet.Create(AOwner: TComponent);
  19. begin
  20. Inherited Create(AOwner);
  21. FFieldDefs:=TFieldDefs.Create(Self);
  22. FFieldList:=TFields.Create(Self);
  23. end;
  24. destructor TDataSet.Destroy;
  25. begin
  26. Active:=False;
  27. FFieldDefs.Free;
  28. FFieldList.Free;
  29. Inherited Destroy;
  30. end;
  31. Procedure TDataset.ActivateBuffers;
  32. begin
  33. FBOF:=False;
  34. FEOF:=False;
  35. FRecordCount:=1;
  36. FActiveRecord:=0;
  37. end;
  38. Procedure TDataset.UpdateFieldDefs;
  39. begin
  40. //!! To be implemented
  41. end;
  42. Procedure TDataset.BindFields(Binding: Boolean);
  43. Var I : longint;
  44. begin
  45. {
  46. Here some magic will be needed later; for now just simply set
  47. Just set fieldno from listindex...
  48. Later we should take it from the fielddefs.
  49. }
  50. For I:=0 to FFieldList.Count-1 do
  51. FFieldList[i].FFieldNo:=I;
  52. end;
  53. Function TDataset.BookmarkAvailable: Boolean;
  54. Const BookmarkStates = [dsBrowse,dsEdit,dsInsert];
  55. begin
  56. Result:=(Not IsEmpty) and (State in BookmarkStates)
  57. and (getBookMarkFlag(ActiveBuffer)=bfCurrent);
  58. end;
  59. Procedure TDataset.CalculateFields(Buffer: PChar);
  60. begin
  61. //!! To be implemented
  62. end;
  63. Procedure TDataset.CheckActive;
  64. begin
  65. If Not Active then
  66. DataBaseError(SInactiveDataset);
  67. end;
  68. Procedure TDataset.CheckInactive;
  69. begin
  70. If Active then
  71. DataBaseError(SActiveDataset);
  72. end;
  73. Procedure TDataset.ClearBuffers;
  74. begin
  75. FRecordCount:=0;
  76. FactiveRecord:=0;
  77. FCurrentRecord:=-1;
  78. FBOF:=True;
  79. FEOF:=True;
  80. end;
  81. Procedure TDataset.ClearCalcFields(Buffer: PChar);
  82. begin
  83. //!! To be implemented
  84. end;
  85. Procedure TDataset.CloseBlob(Field: TField);
  86. begin
  87. //!! To be implemented
  88. end;
  89. Procedure TDataset.CloseCursor;
  90. begin
  91. //!! To be implemented
  92. end;
  93. Procedure TDataset.CreateFields;
  94. Var I : longint;
  95. begin
  96. {$ifdef DSDebug}
  97. Writeln ('Creating fields');
  98. {$endif}
  99. For I:=0 to fielddefs.Count-1 do
  100. With Fielddefs.Items[I] do
  101. If DataType<>ftUnknown then
  102. CreateField(self);
  103. end;
  104. Procedure TDataset.DataEvent(Event: TDataEvent; Info: Longint);
  105. begin
  106. //!! To be implemented
  107. end;
  108. Procedure TDataset.DestroyFields;
  109. begin
  110. FFieldList.Clear;
  111. end;
  112. Procedure TDataset.DoAfterCancel;
  113. begin
  114. If assigned(FAfterCancel) then
  115. FAfterCancel(Self);
  116. end;
  117. Procedure TDataset.DoAfterClose;
  118. begin
  119. If assigned(FAfterClose) then
  120. FAfterClose(Self);
  121. end;
  122. Procedure TDataset.DoAfterDelete;
  123. begin
  124. If assigned(FAfterDelete) then
  125. FAfterDelete(Self);
  126. end;
  127. Procedure TDataset.DoAfterEdit;
  128. begin
  129. If assigned(FAfterEdit) then
  130. FAfterEdit(Self);
  131. end;
  132. Procedure TDataset.DoAfterInsert;
  133. begin
  134. If assigned(FAfterInsert) then
  135. FAfterInsert(Self);
  136. end;
  137. Procedure TDataset.DoAfterOpen;
  138. begin
  139. If assigned(FAfterOpen) then
  140. FAfterOpen(Self);
  141. end;
  142. Procedure TDataset.DoAfterPost;
  143. begin
  144. If assigned(FAfterPost) then
  145. FAfterPost(Self);
  146. end;
  147. Procedure TDataset.DoAfterScroll;
  148. begin
  149. If assigned(FAfterScroll) then
  150. FAfterScroll(Self);
  151. end;
  152. Procedure TDataset.DoBeforeCancel;
  153. begin
  154. If assigned(FBeforeCancel) then
  155. FBeforeCancel(Self);
  156. end;
  157. Procedure TDataset.DoBeforeClose;
  158. begin
  159. If assigned(FBeforeClose) then
  160. FBeforeClose(Self);
  161. end;
  162. Procedure TDataset.DoBeforeDelete;
  163. begin
  164. If assigned(FBeforeDelete) then
  165. FBeforeDelete(Self);
  166. end;
  167. Procedure TDataset.DoBeforeEdit;
  168. begin
  169. If assigned(FBeforeEdit) then
  170. FBeforeEdit(Self);
  171. end;
  172. Procedure TDataset.DoBeforeInsert;
  173. begin
  174. If assigned(FBeforeInsert) then
  175. FBeforeInsert(Self);
  176. end;
  177. Procedure TDataset.DoBeforeOpen;
  178. begin
  179. If assigned(FBeforeOpen) then
  180. FBeforeOpen(Self);
  181. end;
  182. Procedure TDataset.DoBeforePost;
  183. begin
  184. If assigned(FBeforePost) then
  185. FBeforePost(Self);
  186. end;
  187. Procedure TDataset.DoBeforeScroll;
  188. begin
  189. If assigned(FBeforeScroll) then
  190. FBeforeScroll(Self);
  191. end;
  192. Procedure TDataset.DoInternalOpen;
  193. begin
  194. FBufferCount:=0;
  195. FDefaultFields:=FieldCount=0;
  196. DoBeforeOpen;
  197. Try
  198. {$ifdef dsdebug}
  199. Writeln ('Calling internal open');
  200. {$endif}
  201. InternalOpen;
  202. FBOF:=True;
  203. {$ifdef dsdebug}
  204. Writeln ('Setting state to browse');
  205. {$endif}
  206. SetState(dsBrowse);
  207. {$ifdef dsdebug}
  208. Writeln ('Setting buffer size');
  209. {$endif}
  210. SetBufListSize(DefaultBufferCount);
  211. {$ifdef dsdebug}
  212. Writeln ('Getting next records');
  213. {$endif}
  214. GetNextRecords;
  215. DoAfterOpen;
  216. DoAfterScroll;
  217. except
  218. SetState(dsInactive);
  219. DoInternalClose;
  220. raise;
  221. end;
  222. end;
  223. Function TDataset.RequiredBuffers : longint;
  224. {
  225. If later some datasource requires more buffers (grids etc)
  226. then it should be taken into account here...
  227. }
  228. begin
  229. Result:=0;
  230. end;
  231. Procedure TDataset.DoInternalClose;
  232. begin
  233. FreeFieldBuffers;
  234. ClearBuffers;
  235. SetState(dsInactive);
  236. InternalClose;
  237. end;
  238. Procedure TDataset.DoOnCalcFields;
  239. begin
  240. If assigned(FOnCalcfields) then
  241. FOnCalcFields(Self);
  242. end;
  243. Procedure TDataset.DoOnNewRecord;
  244. begin
  245. If assigned(FOnNewRecord) then
  246. FOnNewRecord(Self);
  247. end;
  248. Function TDataset.FieldByNumber(FieldNo: Longint): TField;
  249. begin
  250. Result:=FFieldList.FieldByNumber(FieldNo);
  251. end;
  252. Function TDataset.FindRecord(Restart, GoForward: Boolean): Boolean;
  253. begin
  254. //!! To be implemented
  255. end;
  256. Procedure TDataset.FreeFieldBuffers;
  257. Var I : longint;
  258. begin
  259. For I:=0 to FFieldList.Count-1 do
  260. FFieldList[i].FreeBuffers;
  261. end;
  262. Function TDataset.GetBookmarkStr: TBookmarkStr;
  263. begin
  264. Result:='';
  265. If BookMarkAvailable then
  266. begin
  267. SetLength(Result,FBookMarkSize);
  268. GetBookMarkData(ActiveBuffer,Pointer(Result));
  269. end
  270. end;
  271. Function TDataset.GetBuffer (Index : longint) : Pchar;
  272. begin
  273. Result:=FBuffers[Index];
  274. end;
  275. Procedure TDataset.GetCalcFields(Buffer: PChar);
  276. begin
  277. //!! To be implemented
  278. end;
  279. Function TDataset.GetCanModify: Boolean;
  280. begin
  281. Result:=True;
  282. end;
  283. Procedure TDataset.GetChildren(Proc: TGetChildProc; Root: TComponent);
  284. begin
  285. //!! To be implemented
  286. end;
  287. Function TDataset.GetField (Index : Longint) : TField;
  288. begin
  289. Result:=FFIeldList[index];
  290. end;
  291. {
  292. This is not yet allowed, FPC doesn't allow typed consts of Classes...
  293. Const
  294. DefFieldClasses : Array [TFieldType] of TFieldClass =
  295. ( { ftUnknown} Tfield,
  296. { ftString} TStringField,
  297. { ftSmallint} TLongIntField,
  298. { ftInteger} TLongintField,
  299. { ftWord} TLongintField,
  300. { ftBoolean} TBooleanField,
  301. { ftFloat} TFloatField,
  302. { ftDate} TDateField,
  303. { ftTime} TTimeField,
  304. { ftDateTime} TDateTimeField,
  305. { ftBytes} TBytesField,
  306. { ftVarBytes} TVarBytesField,
  307. { ftAutoInc} TAutoIncField,
  308. { ftBlob} TBlobField,
  309. { ftMemo} TMemoField,
  310. { ftGraphic} TGraphicField,
  311. { ftFmtMemo} TMemoField,
  312. { ftParadoxOle} Nil,
  313. { ftDBaseOle} Nil,
  314. { ftTypedBinary} Nil,
  315. { ftCursor} Nil
  316. );
  317. }
  318. Function TDataset.GetFieldClass(FieldType: TFieldType): TFieldClass;
  319. begin
  320. Case FieldType of
  321. ftUnknown : Result:=Tfield;
  322. ftString: Result := TStringField;
  323. ftSmallint: Result := TSmallIntField;
  324. ftInteger: Result := TLongintField;
  325. ftWord: Result := TWordField;
  326. ftBoolean: Result := TBooleanField;
  327. ftFloat: Result := TFloatField;
  328. ftDate: Result := TDateField;
  329. ftTime: Result := TTimeField;
  330. ftDateTime: Result := TDateTimeField;
  331. ftBytes: Result := TBytesField;
  332. ftVarBytes: Result := TVarBytesField;
  333. ftAutoInc: Result := TAutoIncField;
  334. ftBlob: Result := TBlobField;
  335. ftMemo: Result := TMemoField;
  336. ftGraphic: Result := TGraphicField;
  337. ftFmtMemo: Result := TMemoField;
  338. ftParadoxOle: Result := Nil;
  339. ftDBaseOle: Result := Nil;
  340. ftTypedBinary: Result := Nil;
  341. ftCursor: Result := Nil;
  342. end;
  343. end;
  344. Function TDataset.GetIsIndexField(Field: TField): Boolean;
  345. begin
  346. //!! To be implemented
  347. end;
  348. Function TDataset.GetNextRecord: Boolean;
  349. Var Shifted : Boolean;
  350. begin
  351. {$ifdef dsdebug}
  352. Writeln ('Getting next record. Internal RecordCount : ',FRecordCount);
  353. {$endif}
  354. Shifted:=FRecordCount=FBufferCount;
  355. If Shifted then
  356. begin
  357. ShiftBuffers(0,1);
  358. Dec(FRecordCount);
  359. end;
  360. {$ifdef dsdebug}
  361. Writeln ('Getting data into buffer : ',FRecordCount);
  362. {$endif}
  363. Result:=GetRecord(FBuffers[FRecordCount],gmNext,True)=grOK;
  364. If Result then
  365. begin
  366. If FRecordCount=0 then
  367. ActivateBuffers
  368. else
  369. If FRecordCount<FBufferCount then
  370. Inc(FRecordCount);
  371. FCurrentRecord:=FRecordCount;
  372. end
  373. else
  374. begin
  375. if shifted then
  376. begin
  377. ShiftBuffers(0,-1);
  378. inc(FRecordCount);
  379. end;
  380. CursorPosChanged;
  381. end;
  382. {$ifdef dsdebug}
  383. Writeln ('Result getting next record : ',Result);
  384. {$endif}
  385. end;
  386. Function TDataset.GetNextRecords: Longint;
  387. begin
  388. Result:=0;
  389. {$ifdef dsdebug}
  390. Writeln ('Getting next record(s), need :',FBufferCount);
  391. {$endif}
  392. While (FRecordCount<FBufferCount) and GetNextRecord do
  393. Inc(Result);
  394. {$ifdef dsdebug}
  395. Writeln ('Result Getting next record(s), GOT :',RESULT);
  396. {$endif}
  397. end;
  398. Function TDataset.GetPriorRecord: Boolean;
  399. Var Shifted : boolean;
  400. begin
  401. {$ifdef dsdebug}
  402. Writeln ('Getting previous record');
  403. {$endif}
  404. Shifted:=FRecordCount>0;
  405. If Shifted Then
  406. begin
  407. SetCurrentRecord(0);
  408. ShiftBuffers(0,-1);
  409. end;
  410. Result:=GetRecord(FBuffers[0],gmPrior,True)=grOK;
  411. If Result then
  412. begin
  413. If FRecordCount=0 then
  414. ActivateBuffers
  415. else
  416. begin
  417. If FrecordCount<FBufferCount then
  418. Inc(FRecordCount);
  419. end;
  420. FCurrentRecord:=0;
  421. end
  422. else
  423. begin
  424. If Shifted then
  425. begin
  426. ShiftBuffers(0,1);
  427. end;
  428. CursorPosChanged;
  429. end;
  430. end;
  431. Function TDataset.GetPriorRecords: Longint;
  432. begin
  433. Result:=0;
  434. {$ifdef dsdebug}
  435. Writeln ('Getting previous record(s), need :',FBufferCount);
  436. {$endif}
  437. While (FRecordCount<FbufferCount) and GetPriorRecord do
  438. Inc(Result);
  439. end;
  440. Function TDataset.GetRecNo: Longint;
  441. begin
  442. //!! To be implemented
  443. end;
  444. Function TDataset.GetRecordCount: Longint;
  445. begin
  446. //!! To be implemented
  447. end;
  448. Procedure TDataset.InitFieldDefs;
  449. begin
  450. //!! To be implemented
  451. end;
  452. Procedure TDataset.InitRecord(Buffer: PChar);
  453. begin
  454. InternalInitRecord(Buffer);
  455. ClearCalcFields(Buffer);
  456. end;
  457. Procedure TDataset.InternalCancel;
  458. begin
  459. //!! To be implemented
  460. end;
  461. Procedure TDataset.InternalEdit;
  462. begin
  463. //!! To be implemented
  464. end;
  465. Procedure TDataset.InternalRefresh;
  466. begin
  467. //!! To be implemented
  468. end;
  469. Procedure TDataset.Loaded;
  470. begin
  471. //!! To be implemented
  472. end;
  473. Procedure TDataset.OpenCursor(InfoQuery: Boolean);
  474. begin
  475. //!! To be implemented
  476. end;
  477. Procedure TDataset.RefreshInternalCalcFields(Buffer: PChar);
  478. begin
  479. //!! To be implemented
  480. end;
  481. Procedure TDataset.RestoreState(const Value: TDataSetState);
  482. begin
  483. //!! To be implemented
  484. end;
  485. Procedure TDataset.SetActive (Value : Boolean);
  486. begin
  487. If Value<>Factive then
  488. If Value then
  489. DoInternalOpen
  490. else
  491. DoInternalClose;
  492. FActive:=Value;
  493. end;
  494. Procedure TDataset.SetBookmarkStr(const Value: TBookmarkStr);
  495. begin
  496. GotoBookMark(Pointer(Value))
  497. end;
  498. Procedure TDataset.SetBufListSize(Value: Longint);
  499. Var I : longint;
  500. begin
  501. If Value=FBufferCount Then exit;
  502. I:=RequiredBuffers; // Save 1 call.
  503. If Value<I Then
  504. Value:=I;
  505. If Value>FBufferCount then
  506. begin
  507. {$ifdef dsdebug}
  508. Writeln ('Reallocating memory :',(Value+1)*SizeOf(PChar));
  509. {$endif}
  510. ReAllocMem(FBuffers,(Value+1)*SizeOf(PChar));
  511. {$ifdef dsdebug}
  512. Writeln ('Filling memory :',(Value-FBufferCount)*SizeOf(PChar));
  513. {$endif}
  514. FillChar(FBuffers[FBufferCount],(Value+1-FBufferCount)*SizeOF(Pchar),#0);
  515. {$ifdef dsdebug}
  516. Writeln ('Filled memory :');
  517. {$endif}
  518. Try
  519. {$ifdef dsdebug}
  520. Writeln ('Assigning buffers :',(Value+1)*SizeOf(PChar));
  521. {$endif}
  522. For I:=FBufferCount to Value do
  523. FBuffers[i]:=AllocRecordBuffer;
  524. {$ifdef dsdebug}
  525. Writeln ('Assigned buffers :',(Value+1)*SizeOf(PChar));
  526. {$endif}
  527. except
  528. I:=FBufferCount;
  529. While (I<=Value) and (FBuffers[i]<>Nil) do
  530. begin
  531. FreeRecordBuffer(FBuffers[i]);
  532. Inc(i);
  533. end;
  534. raise;
  535. end;
  536. end
  537. else
  538. begin
  539. For I:=Value+1 to FBufferCount do
  540. FreeRecordBuffer(FBuffers[i]);
  541. ReAllocMem(FBuffers,Value*SizeOf(Pchar));
  542. end;
  543. FBufferCount:=Value;
  544. end;
  545. Procedure TDataset.SetChildOrder(Component: TComponent; Order: Longint);
  546. begin
  547. //!! To be implemented
  548. end;
  549. Procedure TDataset.SetCurrentRecord(Index: Longint);
  550. begin
  551. If FCurrentRecord<>Index then
  552. begin
  553. {$ifdef DSdebug}
  554. Writeln ('Setting current record to',index);
  555. {$endif}
  556. Case GetBookMarkFlag(FBuffers[Index]) of
  557. bfCurrent : InternalSetToRecord(FBuffers[Index]);
  558. bfBOF : InternalFirst;
  559. bfEOF : InternalLast;
  560. end;
  561. FCurrentRecord:=index;
  562. end;
  563. end;
  564. Procedure TDataset.SetField (Index : Longint;Value : TField);
  565. begin
  566. //!! To be implemented
  567. end;
  568. Procedure TDataset.SetFilterOptions(Value: TFilterOptions);
  569. begin
  570. //!! To be implemented
  571. end;
  572. Procedure TDataset.SetFilterText(const Value: string);
  573. begin
  574. //!! To be implemented
  575. end;
  576. Procedure TDataset.SetFiltered(Value: Boolean);
  577. begin
  578. //!! To be implemented
  579. end;
  580. Procedure TDataset.SetFound(const Value: Boolean);
  581. begin
  582. //!! To be implemented
  583. end;
  584. Procedure TDataset.SetModified(Value: Boolean);
  585. begin
  586. //!! To be implemented
  587. end;
  588. Procedure TDataset.SetName(const Value: TComponentName);
  589. begin
  590. //!! To be implemented
  591. end;
  592. Procedure TDataset.SetOnFilterRecord(const Value: TFilterRecordEvent);
  593. begin
  594. //!! To be implemented
  595. end;
  596. Procedure TDataset.SetRecNo(Value: Longint);
  597. begin
  598. //!! To be implemented
  599. end;
  600. Procedure TDataset.SetState(Value: TDataSetState);
  601. begin
  602. If Value<>FState then
  603. begin
  604. FState:=Value;
  605. end;
  606. end;
  607. Function TDataset.SetTempState(const Value: TDataSetState): TDataSetState;
  608. begin
  609. //!! To be implemented
  610. end;
  611. Function TDataset.TempBuffer: PChar;
  612. begin
  613. //!! To be implemented
  614. end;
  615. Procedure TDataset.UpdateIndexDefs;
  616. begin
  617. //!! To be implemented
  618. end;
  619. Function TDataset.ControlsDisabled: Boolean;
  620. begin
  621. //!! To be implemented
  622. end;
  623. Function TDataset.ActiveBuffer: PChar;
  624. begin
  625. {$ifdef dsdebug}
  626. // Writeln ('Active buffer requested. Returning:',ActiveRecord);
  627. {$endif}
  628. Result:=FBuffers[ActiveRecord];
  629. end;
  630. Procedure TDataset.Append;
  631. begin
  632. DoInsertAppend(True);
  633. end;
  634. Procedure TDataset.AppendRecord(const Values: array of const);
  635. begin
  636. //!! To be implemented
  637. end;
  638. Function TDataset.BookmarkValid(ABookmark: TBookmark): Boolean;
  639. {
  640. Should be overridden by descendant objects.
  641. }
  642. begin
  643. Result:=False
  644. end;
  645. Procedure TDataset.Cancel;
  646. begin
  647. If State in [dsEdit,dsInsert] then
  648. begin
  649. DoBeforeCancel;
  650. UpdateCursorPos;
  651. InternalCancel;
  652. FreeFieldBuffers;
  653. SetState(dsBrowse);
  654. Resync([]);
  655. DoAfterCancel;
  656. end;
  657. end;
  658. Procedure TDataset.CheckBrowseMode;
  659. begin
  660. CheckActive;
  661. If State In [dsedit,dsinsert] then
  662. begin
  663. UpdateRecord;
  664. If Modified then
  665. Post
  666. else
  667. Cancel;
  668. end;
  669. end;
  670. Procedure TDataset.ClearFields;
  671. begin
  672. //!! To be implemented
  673. end;
  674. Procedure TDataset.Close;
  675. begin
  676. Active:=False;
  677. end;
  678. Function TDataset.CompareBookmarks(Bookmark1, Bookmark2: TBookmark): Longint;
  679. begin
  680. Result:=0;
  681. end;
  682. Function TDataset.CreateBlobStream(Field: TField; Mode: TBlobStreamMode): TStream;
  683. begin
  684. Result:=Nil;
  685. end;
  686. Procedure TDataset.CursorPosChanged;
  687. begin
  688. FCurrentRecord:=-1;
  689. end;
  690. Procedure TDataset.Delete;
  691. begin
  692. //!! To be implemented
  693. end;
  694. Procedure TDataset.DisableControls;
  695. begin
  696. //!! To be implemented
  697. end;
  698. Procedure TDataset.DoInsertAppend(DoAppend : Boolean);
  699. Var Buffer : PChar;
  700. BookBeforeInsert : TBookmarkStr;
  701. begin
  702. If Not CanModify then
  703. DatabaseError(SDatasetReadOnly,Self);
  704. CheckBrowseMode;
  705. DoBeforeInsert;
  706. DoBeforeScroll;
  707. If Not DoAppend then
  708. begin
  709. {$ifdef dsdebug}
  710. Writeln ('going to insert mode');
  711. {$endif}
  712. // need to scroll up al buffers after current one,
  713. // but copy current bookmark to insert buffer.
  714. BookBeforeInsert:=Bookmark;
  715. ShiftBuffers(1,FActiveRecord);
  716. // Active buffer is now edit buffer. Initialize.
  717. InitRecord(ActiveBuffer);
  718. // Put bookmark in edit buffer.
  719. if FRecordCount=0 then
  720. SetBookmarkFlag(ActiveBuffer,bfBOF)
  721. else
  722. SetBookMarkData(ActiveBuffer,Pointer(BookBeforeInsert));
  723. // update buffer count.
  724. If FRecordCount<FBufferCount then
  725. Inc(FRecordCount);
  726. end
  727. else
  728. // Tricky, need to get last record and scroll down.
  729. begin
  730. {$ifdef dsdebug}
  731. Writeln ('going to append mode');
  732. {$endif}
  733. Buffer:=FBuffers[0];
  734. InitRecord(Buffer);
  735. // just mark buffer as last. GetPreviousrecords will do an internallast
  736. // Because of this...
  737. SetBookMarkFlag(Buffer,bfEOF);
  738. FRecordCount:=1;
  739. {$ifdef dsdebug}
  740. Writeln ('getting prior records');
  741. {$endif}
  742. GetPriorRecords;
  743. // update active record.
  744. FactiveRecord:=FRecordCount-1;
  745. end;
  746. SetState(dsInsert);
  747. try
  748. DoOnNewRecord;
  749. except
  750. UpdateCursorPos;
  751. resync([]);
  752. raise;
  753. end;
  754. // mark as not modified.
  755. FModified:=False;
  756. // Final events.
  757. DoAfterInsert;
  758. DoAfterScroll;
  759. {$ifdef dsdebug}
  760. Writeln ('Done with append');
  761. {$endif}
  762. end;
  763. Procedure TDataset.Edit;
  764. begin
  765. If Not CanModify then
  766. DatabaseError(SDatasetReadOnly,Self);
  767. If State in [dsedit,dsinsert] then exit;
  768. If FRecordCount = 0 then
  769. begin
  770. Insert;
  771. Exit;
  772. end;
  773. CheckBrowseMode;
  774. DoBeforeEdit;
  775. If Not TryDoing(@InternalEdit,OnEditError) then
  776. exit;
  777. SetState(dsedit);
  778. DoAfterEdit;
  779. end;
  780. Procedure TDataset.EnableControls;
  781. begin
  782. //!! To be implemented
  783. end;
  784. Function TDataset.FieldByName(const FieldName: string): TField;
  785. begin
  786. Result:=FindField(FieldName);
  787. If Result=Nil then
  788. DatabaseErrorFmt(SFieldNotFound,[FieldName],Self);
  789. end;
  790. Function TDataset.FindField(const FieldName: string): TField;
  791. begin
  792. Result:=FFieldList.FindField(FieldName);
  793. end;
  794. Function TDataset.FindFirst: Boolean;
  795. begin
  796. //!! To be implemented
  797. end;
  798. Function TDataset.FindLast: Boolean;
  799. begin
  800. //!! To be implemented
  801. end;
  802. Function TDataset.FindNext: Boolean;
  803. begin
  804. //!! To be implemented
  805. end;
  806. Function TDataset.FindPrior: Boolean;
  807. begin
  808. //!! To be implemented
  809. end;
  810. Procedure TDataset.First;
  811. begin
  812. CheckBrowseMode;
  813. DoBeforeScroll;
  814. ClearBuffers;
  815. try
  816. InternalFirst;
  817. GetNextRecords;
  818. finally
  819. FBOF:=True;
  820. DoAfterScroll;
  821. end;
  822. end;
  823. Procedure TDataset.FreeBookmark(ABookmark: TBookmark);
  824. begin
  825. FreeMem(ABookMark,FBookMarkSize);
  826. end;
  827. Function TDataset.GetBookmark: TBookmark;
  828. begin
  829. if BookmarkAvailable then
  830. begin
  831. GetMem (Result,FBookMarkSize);
  832. GetBookMarkdata(ActiveBuffer,Result);
  833. end
  834. else
  835. Result:=Nil;
  836. end;
  837. Function TDataset.GetCurrentRecord(Buffer: PChar): Boolean;
  838. begin
  839. Result:=False;
  840. end;
  841. Procedure TDataset.GetFieldList(List: TList; const FieldNames: string);
  842. begin
  843. end;
  844. Procedure TDataset.GetFieldNames(List: TStrings);
  845. begin
  846. FFieldList.GetFieldNames(List);
  847. end;
  848. Procedure TDataset.GotoBookmark(ABookmark: TBookmark);
  849. begin
  850. If Assigned(ABookMark) then
  851. begin
  852. CheckBrowseMode;
  853. DoBeforeScroll;
  854. InternalGotoBookMark(ABookMark);
  855. Resync([rmExact,rmCenter]);
  856. DoAfterScroll;
  857. end;
  858. end;
  859. Procedure TDataset.Insert;
  860. begin
  861. DoInsertAppend(False);
  862. end;
  863. Procedure TDataset.InsertRecord(const Values: array of const);
  864. begin
  865. //!! To be implemented
  866. end;
  867. Function TDataset.IsEmpty: Boolean;
  868. begin
  869. Result:=(Bof and Eof);
  870. end;
  871. Function TDataset.IsSequenced: Boolean;
  872. begin
  873. //!! To be implemented
  874. end;
  875. Procedure TDataset.Last;
  876. begin
  877. CheckBrowseMode;
  878. DoBeforeScroll;
  879. ClearBuffers;
  880. try
  881. InternalLast;
  882. GetPriorRecords;
  883. FActiveRecord:=FRecordCount-1;
  884. finally
  885. FEOF:=true;
  886. DoAfterScroll;
  887. end;
  888. end;
  889. Function TDataset.MoveBy(Distance: Longint): Longint;
  890. Procedure Scrollforward;
  891. begin
  892. {$ifdef dsdebug}
  893. Writeln('Scrolling forward :',Distance);
  894. Writeln('Active buffer : ',FActiveRecord);
  895. Writeln('RecordCunt : ',FRecordCount);
  896. {$endif}
  897. While (Distance>0) and not FEOF do
  898. begin
  899. If FActiveRecord<FRecordCount-1 then
  900. begin
  901. Inc(FActiveRecord);
  902. Dec(Distance)
  903. end
  904. else
  905. begin
  906. {$ifdef dsdebug}
  907. Writeln('Moveby : need next record');
  908. {$endif}
  909. If GetNextRecord then
  910. Dec(Distance)
  911. else
  912. FEOF:=true;
  913. end;
  914. end
  915. end;
  916. Procedure ScrollBackward;
  917. begin
  918. {$ifdef dsdebug}
  919. Writeln('Scrolling backward:',Abs(Distance));
  920. Writeln('Active buffer : ',FActiveRecord);
  921. Writeln('RecordCunt : ',FRecordCount);
  922. {$endif}
  923. While (Distance<0) and not FBOF do
  924. begin
  925. If FActiveRecord>0 then
  926. begin
  927. Dec(FActiveRecord);
  928. Inc(Distance)
  929. end
  930. else
  931. begin
  932. {$ifdef dsdebug}
  933. Writeln('Moveby : need next record');
  934. {$endif}
  935. If GetPriorRecord then
  936. Inc(Distance)
  937. else
  938. FBOF:=true;
  939. end;
  940. end
  941. end;
  942. begin
  943. CheckBrowseMode;
  944. Result:=0;
  945. DoBeforeScroll;
  946. If ((Distance>0) and FEOF) or
  947. ((Distance<0) and FBOF) then
  948. exit;
  949. Try
  950. If Distance>0 then
  951. ScrollForward
  952. else
  953. ScrollBackward;
  954. finally
  955. DoAfterScroll;
  956. end;
  957. end;
  958. Procedure TDataset.Next;
  959. begin
  960. MoveBy(1);
  961. end;
  962. Procedure TDataset.Open;
  963. begin
  964. Active:=True;
  965. end;
  966. Procedure TDataset.Post;
  967. Procedure Checkrequired;
  968. Var I : longint;
  969. begin
  970. For I:=0 to FFieldList.Count-1 do
  971. With FFieldList[i] do
  972. // Required fields that are NOT autoinc !! Autoinc cannot be set !!
  973. if Required and not ReadOnly and
  974. (FieldKind=fkData) and Not (DataType=ftAutoInc) then
  975. DatabaseErrorFmt(SNeedField,[DisplayName],Self);
  976. end;
  977. begin
  978. if State in [dsEdit,dsInsert] then
  979. begin
  980. {$ifdef dsdebug}
  981. writeln ('Post: checking required fields');
  982. {$endif}
  983. CheckRequired;
  984. DoBeforePost;
  985. If Not TryDoing(@InternalPost,OnPostError) then exit;
  986. {$ifdef dsdebug}
  987. writeln ('Post: Internalpost succeeded');
  988. {$endif}
  989. FreeFieldBuffers;
  990. {$ifdef dsdebug}
  991. writeln ('Post: Freeing field buffers');
  992. {$endif}
  993. SetState(dsBrowse);
  994. {$ifdef dsdebug}
  995. writeln ('Post: Browse mode set');
  996. {$endif}
  997. Resync([]);
  998. DoAfterPost;
  999. end;
  1000. end;
  1001. Procedure TDataset.Prior;
  1002. begin
  1003. MoveBy(-1);
  1004. end;
  1005. Procedure TDataset.Refresh;
  1006. begin
  1007. CheckbrowseMode;
  1008. UpdateCursorPos;
  1009. InternalRefresh;
  1010. Resync([]);
  1011. end;
  1012. Procedure TDataset.Resync(Mode: TResyncMode);
  1013. Var Count,ShiftCount : Longint;
  1014. begin
  1015. // See if we can find the requested record.
  1016. If rmExact in Mode then
  1017. begin
  1018. { throw an exception if not found.
  1019. Normally the descendant should do this if DoCheck is true. }
  1020. If GetRecord(Fbuffers[FRecordCount-1],gmcurrent,True)<>grOk Then
  1021. DatabaseError(SNoSuchRecord,Self);
  1022. end
  1023. else
  1024. { Can we find a record in the neighbourhood ?
  1025. Use Shortcut evaluation for this, or we'll have some funny results. }
  1026. If (GetRecord(Fbuffers[FRecordCount-1],gmcurrent,True)<>grOk) and
  1027. (GetRecord(Fbuffers[FRecordCount-1],gmprior,True)<>grOk) and
  1028. (GetRecord(Fbuffers[FRecordCount-1],gmprior,True)<>grOk) then
  1029. begin
  1030. // nothing found, invalidate buffer and bail out.
  1031. ClearBuffers;
  1032. Exit;
  1033. end;
  1034. If (rmCenter in Mode) then
  1035. ShiftCount:=FbufferCount div 2
  1036. else
  1037. // keep current position.
  1038. ShiftCount:=FActiveRecord;
  1039. // Reposition on 0
  1040. ShiftBuffers(0,FRecordCount-1);
  1041. ActivateBuffers;
  1042. Count:=0;
  1043. Writeln ('Getting previous',ShiftCount,' records');
  1044. While (Count<ShiftCount) and GetPriorRecord do Inc(Count);
  1045. FActiveRecord:=Count;
  1046. // fill rest of buffers, adjust ActiveBuffer.
  1047. SetCurrentRecord(FRecordCount-1);
  1048. GetNextRecords;
  1049. Inc(FActiveRecord,GetPriorRecords);
  1050. end;
  1051. Procedure TDataset.SetFields(const Values: array of const);
  1052. Var I : longint;
  1053. begin
  1054. For I:=0 to high(Values) do
  1055. Case Values[I].vtype of
  1056. vtInteger : FieldByNumber(i).AsLongInt:=Values[I].VInteger;
  1057. // needs Completion..
  1058. end;
  1059. end;
  1060. Procedure TDataset.Translate(Src, Dest: PChar; ToOem: Boolean);
  1061. begin
  1062. //!! To be implemented
  1063. end;
  1064. Function Tdataset.TryDoing (P : TDataOperation; Ev : TDatasetErrorEvent) : Boolean;
  1065. Var Retry : TDataAction;
  1066. begin
  1067. {$ifdef dsdebug}
  1068. Writeln ('Trying to do');
  1069. If P=Nil then writeln ('Procedure to call is nil !!!');
  1070. {$endif dsdebug}
  1071. Result:=True;
  1072. Retry:=daRetry;
  1073. while Retry=daRetry do
  1074. Try
  1075. {$ifdef dsdebug}
  1076. Writeln ('Trying : updatecursorpos');
  1077. {$endif dsdebug}
  1078. UpdateCursorPos;
  1079. {$ifdef dsdebug}
  1080. Writeln ('Trying to do it');
  1081. {$endif dsdebug}
  1082. P;
  1083. exit;
  1084. except
  1085. On E : EDatabaseError do
  1086. begin
  1087. retry:=daFail;
  1088. If Assigned(Ev) then
  1089. Ev(Self,E,Retry);
  1090. Case Retry of
  1091. daFail : Raise;
  1092. daAbort : Result:=False;
  1093. end;
  1094. end;
  1095. else
  1096. Raise;
  1097. end;
  1098. {$ifdef dsdebug}
  1099. Writeln ('Exit Trying to do');
  1100. {$endif dsdebug}
  1101. end;
  1102. Procedure TDataset.UpdateCursorPos;
  1103. begin
  1104. If FRecordCount>0 then
  1105. SetCurrentRecord(FactiveRecord);
  1106. end;
  1107. Procedure TDataset.UpdateRecord;
  1108. begin
  1109. //!! To be implemented
  1110. end;
  1111. Procedure TDataset.RemoveField (Field : TField);
  1112. begin
  1113. //!! To be implemented
  1114. end;
  1115. Function TDataset.Getfieldcount : Longint;
  1116. begin
  1117. Result:=FFieldList.Count;
  1118. end;
  1119. Procedure TDataset.ShiftBuffers (Offset, Distance : longint);
  1120. Var Temp : Pointer;
  1121. MoveSize : Longint;
  1122. Procedure ShiftBuffersUp;
  1123. begin
  1124. {$ifdef DSDEBUG}
  1125. writeln ('Shifting buffers up from ',OffSet,' with distance :',Distance);
  1126. writeln ('Moving ',(FBufferCount-Distance), ' Buffers at ',Distance);
  1127. {$endif}
  1128. Move(FBuffers[Offset],Temp^,MoveSize);
  1129. Move(FBuffers[Offset+Distance],FBuffers[Offset],(FBufferCount-Distance-Offset)*SizeOf(Pchar));
  1130. Move(Temp^,FBuffers[FBufferCount-Distance-Offset],MoveSize);
  1131. end;
  1132. Procedure ShiftBuffersDown;
  1133. begin
  1134. // Distance is NEGATIVE
  1135. {$ifdef DSDEBUG}
  1136. writeln ('Shifting buffers down with distance :',Abs(Distance));
  1137. writeln ('Moving ',Movesize div 4,' Buffers at ',FBufferCount+Distance);
  1138. {$endif}
  1139. Move(FBuffers[FbufferCount+Distance],Temp^ ,MoveSize);
  1140. Move(FBuffers[0],FBuffers[Abs(Distance)],(FBufferCount+Distance)*SizeOf(Pchar));
  1141. Move(Temp^ ,FBuffers[0],MoveSize);
  1142. end;
  1143. begin
  1144. If Abs(Distance)>=BufferCount then Exit;
  1145. try
  1146. MoveSize:=SizeOf(Pchar)*Abs(Distance);
  1147. GetMem(Temp,MoveSize);
  1148. If Distance<0 Then
  1149. ShiftBuffersDown
  1150. else If Distance>0 then
  1151. ShiftBuffersUp;
  1152. Finally
  1153. FreeMem(temp);
  1154. end;
  1155. end;
  1156. {
  1157. $Log$
  1158. Revision 1.9 2000-01-07 01:24:32 peter
  1159. * updated copyright to 2000
  1160. Revision 1.8 2000/01/06 01:20:32 peter
  1161. * moved out of packages/ back to topdir
  1162. Revision 1.1 2000/01/03 19:33:05 peter
  1163. * moved to packages dir
  1164. Revision 1.6 1999/12/01 22:11:02 michael
  1165. + tested edit and insert methods
  1166. Revision 1.5 1999/11/12 22:53:32 michael
  1167. + Added append() insert() tested append. Datetime as string works now
  1168. Revision 1.4 1999/11/11 17:31:09 michael
  1169. + Added Checks for all simple field types.
  1170. + Initial implementation of Insert/Append
  1171. Revision 1.3 1999/11/09 13:33:47 peter
  1172. * reallocmem fixes
  1173. Revision 1.2 1999/10/24 17:07:54 michael
  1174. + Added copyright header
  1175. }