dataset.inc 30 KB

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