dataset.inc 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1999-2000 by Michael Van Canneyt, member of the
  4. Free Pascal development team
  5. Dataset implementation
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. { ---------------------------------------------------------------------
  13. TDataSet
  14. ---------------------------------------------------------------------}
  15. Const
  16. DefaultBufferCount = 10;
  17. constructor TDataSet.Create(AOwner: TComponent);
  18. begin
  19. Inherited Create(AOwner);
  20. FFieldDefs:=TFieldDefs.Create(Self);
  21. FFieldList:=TFields.Create(Self);
  22. FDataSources:=TList.Create;
  23. end;
  24. destructor TDataSet.Destroy;
  25. var
  26. i: Integer;
  27. begin
  28. Active:=False;
  29. FFieldDefs.Free;
  30. FFieldList.Free;
  31. With FDatasources do
  32. begin
  33. While Count>0 do
  34. TDatasource(Items[Count - 1]).DataSet:=Nil;
  35. Free;
  36. end;
  37. if Assigned(FBuffers) then
  38. begin
  39. for i := 0 to FBufferCount do
  40. FreeRecordBuffer(FBuffers[i]);
  41. FreeMem(FBuffers);
  42. end;
  43. Inherited Destroy;
  44. end;
  45. // This procedure must be called when the first record is made/read
  46. Procedure TDataset.ActivateBuffers;
  47. begin
  48. FBOF:=False;
  49. FEOF:=False;
  50. FActiveRecord:=0;
  51. end;
  52. Procedure TDataset.UpdateFieldDefs;
  53. begin
  54. //!! To be implemented
  55. end;
  56. Procedure TDataset.BindFields(Binding: Boolean);
  57. var i, FieldIndex: Integer;
  58. FieldDef: TFieldDef;
  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. FBlobFieldCount := 0;
  69. for i := 0 to Fields.Count - 1 do
  70. with Fields[i] do begin
  71. if Binding then begin
  72. FieldDef := nil;
  73. FieldIndex := FieldDefs.IndexOf(Fields[i].FieldName);
  74. if FieldIndex <> -1 then begin
  75. FieldDef := FieldDefs[FieldIndex];
  76. FFieldNo := FieldDef.FieldNo;
  77. if IsBlob then begin
  78. FSize := FieldDef.Size;
  79. FOffset := FBlobFieldCount;
  80. Inc(FBlobFieldCount);
  81. end;
  82. end else FFieldNo := FieldIndex;
  83. end else FFieldNo := 0;;
  84. end;
  85. end;
  86. Function TDataset.BookmarkAvailable: Boolean;
  87. Const BookmarkStates = [dsBrowse,dsEdit,dsInsert];
  88. begin
  89. Result:=(Not IsEmpty) and (State in BookmarkStates)
  90. and (getBookMarkFlag(ActiveBuffer)=bfCurrent);
  91. end;
  92. Procedure TDataset.CalculateFields(Buffer: PChar);
  93. begin
  94. { no internal calced fields or caches yet }
  95. DoOnCalcFields;
  96. end;
  97. Procedure TDataset.CheckActive;
  98. begin
  99. If Not Active then
  100. DataBaseError(SInactiveDataset);
  101. end;
  102. Procedure TDataset.CheckInactive;
  103. begin
  104. If Active then
  105. DataBaseError(SActiveDataset);
  106. end;
  107. Procedure TDataset.ClearBuffers;
  108. begin
  109. FRecordCount:=0;
  110. FactiveRecord:=0;
  111. FCurrentRecord:=-1;
  112. FBOF:=True;
  113. FEOF:=True;
  114. end;
  115. Procedure TDataset.ClearCalcFields(Buffer: PChar);
  116. begin
  117. //!! To be implemented
  118. end;
  119. Procedure TDataset.CloseBlob(Field: TField);
  120. begin
  121. //!! To be implemented
  122. end;
  123. Procedure TDataset.CloseCursor;
  124. begin
  125. //!! To be implemented
  126. end;
  127. Procedure TDataset.CreateFields;
  128. Var I : longint;
  129. begin
  130. {$ifdef DSDebug}
  131. Writeln ('Creating fields');
  132. Writeln ('Count : ',fielddefs.Count);
  133. For I:=0 to FieldDefs.Count-1 do
  134. Writeln('Def ',I,' : ',Fielddefs.items[i].Name,'(',Fielddefs.items[i].FieldNo,')');
  135. {$endif}
  136. For I:=0 to fielddefs.Count-1 do
  137. With Fielddefs.Items[I] do
  138. If DataType<>ftUnknown then
  139. begin
  140. {$ifdef DSDebug}
  141. Writeln('About to create field',FieldDefs.Items[i].Name);
  142. {$endif}
  143. CreateField(self);
  144. end;
  145. end;
  146. Procedure TDataset.DataEvent(Event: TDataEvent; Info: Ptrint);
  147. Var
  148. i : longint;
  149. begin
  150. // Do some bookkeeping;
  151. case Event of
  152. deFieldChange: begin
  153. if TField(Info).FieldKind in [fkData,fkInternalCalc] then
  154. SetModified(True);
  155. if State <> dsSetKey then begin
  156. if FInternalCalcFields and (TField(Info).FieldKind = fkData) then
  157. RefreshInternalCalcFields(ActiveBuffer)
  158. else if (FCalcFieldsSize <> 0) and FAutoCalcFields and
  159. (TField(Info).FieldKind = fkData) then
  160. CalculateFields(ActiveBuffer);
  161. TField(Info).Change;
  162. end;
  163. end;
  164. deDataSetChange, deDataSetScroll:
  165. if State <> dsInsert then UpdateCursorPos;
  166. end;
  167. // Distribute event to datasets;
  168. if FDisableControlsCount = 0 then
  169. for I := 0 to FDataSources.Count - 1 do
  170. TDataSource(FDataSources[I]).ProcessEvent(Event, Info);
  171. end;
  172. Procedure TDataset.DestroyFields;
  173. begin
  174. FFieldList.Clear;
  175. end;
  176. Procedure TDataset.DoAfterCancel;
  177. begin
  178. If assigned(FAfterCancel) then
  179. FAfterCancel(Self);
  180. end;
  181. Procedure TDataset.DoAfterClose;
  182. begin
  183. If assigned(FAfterClose) then
  184. FAfterClose(Self);
  185. end;
  186. Procedure TDataset.DoAfterDelete;
  187. begin
  188. If assigned(FAfterDelete) then
  189. FAfterDelete(Self);
  190. end;
  191. Procedure TDataset.DoAfterEdit;
  192. begin
  193. If assigned(FAfterEdit) then
  194. FAfterEdit(Self);
  195. end;
  196. Procedure TDataset.DoAfterInsert;
  197. begin
  198. If assigned(FAfterInsert) then
  199. FAfterInsert(Self);
  200. end;
  201. Procedure TDataset.DoAfterOpen;
  202. begin
  203. If assigned(FAfterOpen) then
  204. FAfterOpen(Self);
  205. end;
  206. Procedure TDataset.DoAfterPost;
  207. begin
  208. If assigned(FAfterPost) then
  209. FAfterPost(Self);
  210. end;
  211. Procedure TDataset.DoAfterScroll;
  212. begin
  213. If assigned(FAfterScroll) then
  214. FAfterScroll(Self);
  215. end;
  216. Procedure TDataset.DoBeforeCancel;
  217. begin
  218. If assigned(FBeforeCancel) then
  219. FBeforeCancel(Self);
  220. end;
  221. Procedure TDataset.DoBeforeClose;
  222. begin
  223. If assigned(FBeforeClose) then
  224. FBeforeClose(Self);
  225. end;
  226. Procedure TDataset.DoBeforeDelete;
  227. begin
  228. If assigned(FBeforeDelete) then
  229. FBeforeDelete(Self);
  230. end;
  231. Procedure TDataset.DoBeforeEdit;
  232. begin
  233. If assigned(FBeforeEdit) then
  234. FBeforeEdit(Self);
  235. end;
  236. Procedure TDataset.DoBeforeInsert;
  237. begin
  238. If assigned(FBeforeInsert) then
  239. FBeforeInsert(Self);
  240. end;
  241. Procedure TDataset.DoBeforeOpen;
  242. begin
  243. If assigned(FBeforeOpen) then
  244. FBeforeOpen(Self);
  245. end;
  246. Procedure TDataset.DoBeforePost;
  247. begin
  248. If assigned(FBeforePost) then
  249. FBeforePost(Self);
  250. end;
  251. Procedure TDataset.DoBeforeScroll;
  252. begin
  253. If assigned(FBeforeScroll) then
  254. FBeforeScroll(Self);
  255. end;
  256. Procedure TDataset.DoInternalOpen;
  257. begin
  258. FDefaultFields:=FieldCount=0;
  259. DoBeforeOpen;
  260. Try
  261. {$ifdef dsdebug}
  262. Writeln ('Calling internal open');
  263. {$endif}
  264. InternalOpen;
  265. FBOF:=True;
  266. {$ifdef dsdebug}
  267. Writeln ('Calling RecalcBufListSize');
  268. {$endif}
  269. FRecordcount := 0;
  270. RecalcBufListSize;
  271. FEOF := (FRecordcount = 0);
  272. {$ifdef dsdebug}
  273. Writeln ('Setting state to browse');
  274. {$endif}
  275. SetState(dsBrowse);
  276. DoAfterOpen;
  277. DoAfterScroll;
  278. except
  279. DoInternalClose(false);
  280. raise;
  281. end;
  282. end;
  283. Procedure TDataset.DoInternalClose(DoCheck : Boolean);
  284. begin
  285. if DoCheck then
  286. CheckBrowsemode;
  287. FreeFieldBuffers;
  288. ClearBuffers;
  289. SetBufListSize(-1);
  290. SetState(dsInactive);
  291. InternalClose;
  292. end;
  293. Procedure TDataset.DoOnCalcFields;
  294. begin
  295. If assigned(FOnCalcfields) then
  296. FOnCalcFields(Self);
  297. end;
  298. Procedure TDataset.DoOnNewRecord;
  299. begin
  300. If assigned(FOnNewRecord) then
  301. FOnNewRecord(Self);
  302. end;
  303. Function TDataset.FieldByNumber(FieldNo: Longint): TField;
  304. begin
  305. Result:=FFieldList.FieldByNumber(FieldNo);
  306. end;
  307. Function TDataset.FindRecord(Restart, GoForward: Boolean): Boolean;
  308. begin
  309. //!! To be implemented
  310. end;
  311. Procedure TDataset.FreeFieldBuffers;
  312. Var I : longint;
  313. begin
  314. For I:=0 to FFieldList.Count-1 do
  315. FFieldList[i].FreeBuffers;
  316. end;
  317. Function TDataset.GetBookmarkStr: TBookmarkStr;
  318. begin
  319. Result:='';
  320. If BookMarkAvailable then
  321. begin
  322. SetLength(Result,FBookMarkSize);
  323. GetBookMarkData(ActiveBuffer,Pointer(Result));
  324. end
  325. end;
  326. Function TDataset.GetBuffer (Index : longint) : Pchar;
  327. begin
  328. Result:=FBuffers[Index];
  329. end;
  330. Procedure TDataset.GetCalcFields(Buffer: PChar);
  331. begin
  332. //!! To be implemented
  333. end;
  334. Function TDataset.GetCanModify: Boolean;
  335. begin
  336. Result:= not FIsUnidirectional;
  337. end;
  338. Procedure TDataset.GetChildren(Proc: TGetChildProc; Root: TComponent);
  339. var
  340. I: Integer;
  341. Field: TField;
  342. begin
  343. for I := 0 to Fields.Count - 1 do begin
  344. Field := Fields[I];
  345. if (Field.Owner = Root) then
  346. Proc(Field);
  347. end;
  348. end;
  349. Function TDataset.GetDataSource: TDataSource;
  350. begin
  351. Result:=nil;
  352. end;
  353. function TDataSet.GetFieldData(Field: TField; Buffer: Pointer;
  354. NativeFormat: Boolean): Boolean;
  355. function ConvertData(Field: TField; Source: TDateTimeRec): TDateTime;
  356. var
  357. TimeStamp: TTimeStamp;
  358. begin
  359. case Field.DataType of
  360. ftDate:
  361. begin
  362. TimeStamp.Time := 0;
  363. TimeStamp.Date := Source.Date;
  364. end;
  365. ftTime:
  366. begin
  367. TimeStamp.Time := Source.Time;
  368. TimeStamp.Date := DateDelta;
  369. end;
  370. else
  371. try
  372. TimeStamp := MSecsToTimeStamp(Trunc(Source.DateTime));
  373. except
  374. TimeStamp.Time := 0;
  375. TimeStamp.Date := 0;
  376. end;
  377. end;
  378. // Result := TimeStampToDateTime(TimeStamp);
  379. Result := (TimeStamp.Date - DateDelta) + (TimeStamp.Time / MSecsPerDay);
  380. end;
  381. var
  382. d: TDateTimeRec;
  383. begin
  384. if NativeFormat then
  385. Result := GetFieldData(Field, Buffer) else
  386. if Field.DataType in [ ftDate, ftDateTime, ftTime ] then begin
  387. Result := GetFieldData(Field, @d);
  388. if Result then
  389. TDateTime(Buffer^) := ConvertData(Field, d);
  390. end else
  391. Result := GetFieldData(Field, Buffer);
  392. end;
  393. procedure TDataSet.SetFieldData(Field: TField; Buffer: Pointer;
  394. NativeFormat: Boolean);
  395. function ConvertData(Field: TField; Data: TDateTime): TDateTimeRec;
  396. var
  397. TimeStamp: TTimeStamp;
  398. begin
  399. TimeStamp.Time := Trunc(Frac(Data) * MSecsPerDay);
  400. TimeStamp.Date := DateDelta + Trunc(System.Int(Data));
  401. // TimeStamp := DateTimeToTimeStamp(Data);
  402. case Field.DataType of
  403. ftDate: Result.Date := TimeStamp.Date;
  404. ftTime: Result.Time := TimeStamp.Time;
  405. else
  406. Result.DateTime := TimeStampToMSecs(TimeStamp);
  407. end;
  408. end;
  409. var
  410. d: TDateTimeRec;
  411. begin
  412. if NativeFormat then
  413. SetFieldData(Field, Buffer)
  414. else
  415. if Field.DataType in [ ftDate, ftDateTime, ftTime ] then begin
  416. d := ConvertData(Field, TDateTime(Buffer^));
  417. SetFieldData(Field, @d);
  418. end else
  419. SetFieldData(Field, Buffer);
  420. end;
  421. Function TDataset.GetField (Index : Longint) : TField;
  422. begin
  423. Result:=FFIeldList[index];
  424. end;
  425. Function TDataset.GetFieldClass(FieldType: TFieldType): TFieldClass;
  426. begin
  427. Result := DefaultFieldClasses[FieldType];
  428. end;
  429. Function TDataset.GetIsIndexField(Field: TField): Boolean;
  430. begin
  431. //!! To be implemented
  432. end;
  433. Function TDataset.GetNextRecord: Boolean;
  434. procedure ExchangeBuffers(var buf1,buf2 : pointer);
  435. var tempbuf : pointer;
  436. begin
  437. tempbuf := buf1;
  438. buf1 := buf2;
  439. buf2 := tempbuf;
  440. end;
  441. begin
  442. {$ifdef dsdebug}
  443. Writeln ('Getting next record. Internal RecordCount : ',FRecordCount);
  444. {$endif}
  445. If FRecordCount>0 Then SetCurrentRecord(FRecordCount-1);
  446. Result:=GetRecord(FBuffers[FBuffercount],gmNext,True)=grOK;
  447. if result then
  448. begin
  449. If FRecordCount=0 then ActivateBuffers;
  450. if FRecordcount=FBuffercount then
  451. shiftbuffersbackward
  452. else
  453. begin
  454. inc(FRecordCount);
  455. FCurrentRecord:=FRecordCount - 1;
  456. ExchangeBuffers(Fbuffers[FCurrentRecord],FBuffers[FBuffercount]);
  457. end;
  458. end
  459. else
  460. cursorposchanged;
  461. {$ifdef dsdebug}
  462. Writeln ('Result getting next record : ',Result);
  463. {$endif}
  464. end;
  465. Function TDataset.GetNextRecords: Longint;
  466. begin
  467. Result:=0;
  468. {$ifdef dsdebug}
  469. Writeln ('Getting next record(s), need :',FBufferCount);
  470. {$endif}
  471. While (FRecordCount<FBufferCount) and GetNextRecord do
  472. Inc(Result);
  473. {$ifdef dsdebug}
  474. Writeln ('Result Getting next record(S), GOT :',RESULT);
  475. {$endif}
  476. end;
  477. Function TDataset.GetPriorRecord: Boolean;
  478. begin
  479. {$ifdef dsdebug}
  480. Writeln ('GetPriorRecord: Getting previous record');
  481. {$endif}
  482. If FRecordCount>0 Then SetCurrentRecord(0);
  483. Result:=GetRecord(FBuffers[FBuffercount],gmPrior,True)=grOK;
  484. if result then
  485. begin
  486. If FRecordCount=0 then ActivateBuffers;
  487. shiftbuffersforward;
  488. if FRecordcount<FBuffercount then
  489. inc(FRecordCount);
  490. end
  491. else
  492. cursorposchanged;
  493. {$ifdef dsdebug}
  494. Writeln ('Result getting prior record : ',Result);
  495. {$endif}
  496. end;
  497. Function TDataset.GetPriorRecords: Longint;
  498. begin
  499. Result:=0;
  500. {$ifdef dsdebug}
  501. Writeln ('Getting previous record(s), need :',FBufferCount);
  502. {$endif}
  503. While (FRecordCount<FbufferCount) and GetPriorRecord do
  504. Inc(Result);
  505. end;
  506. Function TDataset.GetRecNo: Longint;
  507. begin
  508. Result := -1;
  509. end;
  510. Function TDataset.GetRecordCount: Longint;
  511. begin
  512. Result := -1;
  513. end;
  514. Procedure TDataset.InitFieldDefs;
  515. begin
  516. if IsCursorOpen then InternalInitFieldDefs
  517. else
  518. try
  519. OpenCursor(True);
  520. finally
  521. CloseCursor;
  522. end;
  523. end;
  524. Procedure TDataset.InitRecord(Buffer: PChar);
  525. begin
  526. InternalInitRecord(Buffer);
  527. ClearCalcFields(Buffer);
  528. end;
  529. Procedure TDataset.InternalCancel;
  530. begin
  531. //!! To be implemented
  532. end;
  533. Procedure TDataset.InternalEdit;
  534. begin
  535. //!! To be implemented
  536. end;
  537. Procedure TDataset.InternalRefresh;
  538. begin
  539. //!! To be implemented
  540. end;
  541. Procedure TDataset.OpenCursor(InfoQuery: Boolean);
  542. begin
  543. //!! To be implemented
  544. end;
  545. Procedure TDataset.RefreshInternalCalcFields(Buffer: PChar);
  546. begin
  547. //!! To be implemented
  548. end;
  549. Function TDataset.SetTempState(const Value: TDataSetState): TDataSetState;
  550. begin
  551. result := FState;
  552. FState := value;
  553. inc(FDisableControlsCount);
  554. end;
  555. Procedure TDataset.RestoreState(const Value: TDataSetState);
  556. begin
  557. FState := value;
  558. dec(FDisableControlsCount);
  559. end;
  560. function TDataset.GetActive : boolean;
  561. begin
  562. result := FState <> dsInactive;
  563. end;
  564. Procedure TDataset.SetActive (Value : Boolean);
  565. begin
  566. if value and (Fstate = dsInactive) then
  567. begin
  568. if csLoading in ComponentState then
  569. begin
  570. FOpenAfterRead := true;
  571. exit;
  572. end
  573. else
  574. DoInternalOpen;
  575. end
  576. else if not value and (Fstate <> dsinactive) then
  577. DoInternalClose(True);
  578. end;
  579. procedure TDataset.Loaded;
  580. begin
  581. inherited;
  582. if FOpenAfterRead then SetActive(true);
  583. end;
  584. procedure TDataSet.RecalcBufListSize;
  585. var
  586. i, j, ABufferCount: Integer;
  587. DataLink: TDataLink;
  588. begin
  589. {$ifdef dsdebug}
  590. Writeln('Recalculating buffer list size - check cursor');
  591. {$endif}
  592. If Not IsCursorOpen Then
  593. Exit;
  594. {$ifdef dsdebug}
  595. Writeln('Recalculating buffer list size');
  596. {$endif}
  597. ABufferCount := DefaultBufferCount;
  598. for i := 0 to FDataSources.Count - 1 do
  599. for j := 0 to TDataSource(FDataSources[i]).DataLinks.Count - 1 do
  600. begin
  601. DataLink:=TDataLink(TDataSource(FDataSources[i]).DataLinks[j]);
  602. if DataLink.BufferCount>ABufferCount then
  603. ABufferCount:=DataLink.BufferCount;
  604. end;
  605. If (FBufferCount=ABufferCount) Then
  606. exit;
  607. {$ifdef dsdebug}
  608. Writeln('Setting buffer list size');
  609. {$endif}
  610. SetBufListSize(ABufferCount);
  611. {$ifdef dsdebug}
  612. Writeln('Getting next buffers');
  613. {$endif}
  614. GetNextRecords;
  615. {$Ifdef dsDebug}
  616. WriteLn(
  617. 'SetBufferCount: FActiveRecord=',FActiveRecord,
  618. ' FCurrentRecord=',FCurrentRecord,
  619. ' FBufferCount= ',FBufferCount,
  620. ' FRecordCount=',FRecordCount);
  621. {$Endif}
  622. end;
  623. Procedure TDataset.SetBookmarkStr(const Value: TBookmarkStr);
  624. begin
  625. GotoBookMark(Pointer(Value))
  626. end;
  627. Procedure TDataset.SetBufListSize(Value: Longint);
  628. Var I : longint;
  629. begin
  630. {$ifdef dsdebug}
  631. Writeln ('SetBufListSize: ',Value);
  632. {$endif}
  633. If Value=FBufferCount Then
  634. exit;
  635. If Value>FBufferCount then
  636. begin
  637. {$ifdef dsdebug}
  638. Writeln (' Reallocating memory :',(Value+1)*SizeOf(PChar));
  639. {$endif}
  640. ReAllocMem(FBuffers,(Value+1)*SizeOf(PChar));
  641. {$ifdef dsdebug}
  642. Writeln (' Filling memory :',(Value+1-FBufferCount)*SizeOf(PChar));
  643. {$endif}
  644. if FBufferCount > 0 then inc(FBufferCount); // Cause FBuffers[FBufferCount] is already allocated
  645. FillChar(FBuffers[FBufferCount],(Value+1-FBufferCount)*SizeOF(Pchar),#0);
  646. {$ifdef dsdebug}
  647. Writeln (' Filled memory :');
  648. {$endif}
  649. Try
  650. {$ifdef dsdebug}
  651. Writeln (' Assigning buffers :',(Value)*SizeOf(PChar));
  652. {$endif}
  653. For I:=FBufferCount to Value do
  654. FBuffers[i]:=AllocRecordBuffer;
  655. {$ifdef dsdebug}
  656. Writeln (' Assigned buffers ',FBufferCount,' :',(Value)*SizeOf(PChar));
  657. {$endif}
  658. except
  659. I:=FBufferCount;
  660. While (I<(Value+1)) and (FBuffers[i]<>Nil) do
  661. begin
  662. FreeRecordBuffer(FBuffers[i]);
  663. Inc(i);
  664. end;
  665. raise;
  666. end;
  667. end
  668. else
  669. begin
  670. {$ifdef dsdebug}
  671. Writeln (' Freeing buffers :',FBufferCount-Value);
  672. {$endif}
  673. if (value > -1) and (FActiveRecord>Value-1) then
  674. begin
  675. for i := 0 to (FActiveRecord-Value) do
  676. shiftbuffersbackward;
  677. FActiverecord := Value -1;
  678. end;
  679. If Assigned(FBuffers) then
  680. begin
  681. For I:=Value+1 to FBufferCount do
  682. FreeRecordBuffer(FBuffers[i]);
  683. ReAllocMem(FBuffers,(Value+1)*SizeOf(Pchar));
  684. end;
  685. if FRecordcount > Value then FRecordcount := Value;
  686. end;
  687. If Value=-1 then
  688. Value:=0;
  689. FBufferCount:=Value;
  690. {$ifdef dsdebug}
  691. Writeln (' SetBufListSize: Final FBufferCount=',FBufferCount);
  692. {$endif}
  693. end;
  694. Procedure TDataset.SetChildOrder(Component: TComponent; Order: Longint);
  695. var
  696. Field: TField;
  697. begin
  698. Field := Component as TField;
  699. if Fields.IndexOf(Field) >= 0 then
  700. Field.Index := Order;
  701. end;
  702. Procedure TDataset.SetCurrentRecord(Index: Longint);
  703. begin
  704. If FCurrentRecord<>Index then
  705. begin
  706. {$ifdef DSdebug}
  707. Writeln ('Setting current record to',index);
  708. {$endif}
  709. Case GetBookMarkFlag(FBuffers[Index]) of
  710. bfCurrent : InternalSetToRecord(FBuffers[Index]);
  711. bfBOF : InternalFirst;
  712. bfEOF : InternalLast;
  713. end;
  714. FCurrentRecord:=index;
  715. end;
  716. end;
  717. Procedure TDataset.SetField (Index : Longint;Value : TField);
  718. begin
  719. //!! To be implemented
  720. end;
  721. Procedure TDataset.SetFilterOptions(Value: TFilterOptions);
  722. begin
  723. //!! To be implemented
  724. end;
  725. Procedure TDataset.SetFilterText(const Value: string);
  726. begin
  727. FFilterText := value;
  728. end;
  729. Procedure TDataset.SetFiltered(Value: Boolean);
  730. begin
  731. FFiltered := value;
  732. end;
  733. Procedure TDataset.SetFound(const Value: Boolean);
  734. begin
  735. //!! To be implemented
  736. end;
  737. Procedure TDataset.SetModified(Value: Boolean);
  738. begin
  739. FModified := value;
  740. end;
  741. Procedure TDataset.SetName(const Value: TComponentName);
  742. function CheckName(FieldName: string): string;
  743. var i,j: integer;
  744. begin
  745. Result := FieldName;
  746. i := 0;
  747. j := 0;
  748. while (i < Fields.Count) do begin
  749. if Result = Fields[i].FieldName then begin
  750. inc(j);
  751. Result := FieldName + IntToStr(j);
  752. end else Inc(i);
  753. end;
  754. end;
  755. var i: integer;
  756. nm: string;
  757. old: string;
  758. begin
  759. if Self.Name = Value then Exit;
  760. old := Self.Name;
  761. inherited SetName(Value);
  762. if (csDesigning in ComponentState) then
  763. for i := 0 to Fields.Count - 1 do begin
  764. nm := old + Fields[i].FieldName;
  765. if Copy(Fields[i].Name, 1, Length(nm)) = nm then
  766. Fields[i].Name := CheckName(Value + Fields[i].FieldName);
  767. end;
  768. end;
  769. Procedure TDataset.SetOnFilterRecord(const Value: TFilterRecordEvent);
  770. begin
  771. //!! To be implemented
  772. end;
  773. Procedure TDataset.SetRecNo(Value: Longint);
  774. begin
  775. //!! To be implemented
  776. end;
  777. Procedure TDataset.SetState(Value: TDataSetState);
  778. begin
  779. If Value<>FState then
  780. begin
  781. FState:=Value;
  782. DataEvent(deUpdateState,0);
  783. end;
  784. end;
  785. Function TDataset.TempBuffer: PChar;
  786. begin
  787. //!! To be implemented
  788. end;
  789. Procedure TDataset.UpdateIndexDefs;
  790. begin
  791. // Empty Abstract
  792. end;
  793. Function TDataset.ControlsDisabled: Boolean;
  794. begin
  795. Result := (FDisableControlsCount > 0);
  796. end;
  797. Function TDataset.ActiveBuffer: PChar;
  798. begin
  799. {$ifdef dsdebug}
  800. Writeln ('Active buffer requested. Returning:',ActiveRecord);
  801. {$endif}
  802. Result:=FBuffers[FActiveRecord];
  803. end;
  804. Procedure TDataset.Append;
  805. begin
  806. DoInsertAppend(True);
  807. end;
  808. Procedure TDataset.InternalInsert;
  809. begin
  810. //!! To be implemented
  811. end;
  812. Procedure TDataset.AppendRecord(const Values: array of const);
  813. begin
  814. //!! To be implemented
  815. end;
  816. Function TDataset.BookmarkValid(ABookmark: TBookmark): Boolean;
  817. {
  818. Should be overridden by descendant objects.
  819. }
  820. begin
  821. Result:=False
  822. end;
  823. Procedure TDataset.Cancel;
  824. begin
  825. If State in [dsEdit,dsInsert] then
  826. begin
  827. DataEvent(deCheckBrowseMode,0);
  828. DoBeforeCancel;
  829. UpdateCursorPos;
  830. InternalCancel;
  831. FreeFieldBuffers;
  832. if (state = dsInsert) and (FRecordcount = 1) then
  833. begin
  834. FEOF := true;
  835. FBOF := true;
  836. FRecordcount := 0;
  837. SetState(dsBrowse);
  838. DataEvent(deDatasetChange,0);
  839. end
  840. else
  841. begin
  842. SetState(dsBrowse);
  843. SetCurrentRecord(FActiverecord);
  844. resync([]);
  845. end;
  846. DoAfterCancel;
  847. end;
  848. end;
  849. Procedure TDataset.CheckBrowseMode;
  850. begin
  851. CheckActive;
  852. DataEvent(deCheckBrowseMode,0);
  853. Case State of
  854. dsedit,dsinsert: begin
  855. UpdateRecord;
  856. If Modified then Post else Cancel;
  857. end;
  858. dsSetKey: Post;
  859. end;
  860. end;
  861. Procedure TDataset.ClearFields;
  862. begin
  863. //!! To be implemented
  864. end;
  865. Procedure TDataset.Close;
  866. begin
  867. Active:=False;
  868. end;
  869. Function TDataset.CompareBookmarks(Bookmark1, Bookmark2: TBookmark): Longint;
  870. begin
  871. Result:=0;
  872. end;
  873. Function TDataset.CreateBlobStream(Field: TField; Mode: TBlobStreamMode): TStream;
  874. begin
  875. Result:=Nil;
  876. end;
  877. Procedure TDataset.CursorPosChanged;
  878. begin
  879. FCurrentRecord:=-1;
  880. end;
  881. Procedure TDataset.Delete;
  882. begin
  883. If Not CanModify then
  884. DatabaseError(SDatasetReadOnly,Self);
  885. if State in [dsInsert] then
  886. begin
  887. Cancel;
  888. end else begin
  889. DataEvent(deCheckBrowseMode,0);
  890. {$ifdef dsdebug}
  891. writeln ('Delete: checking required fields');
  892. {$endif}
  893. DoBeforeDelete;
  894. DoBeforeScroll;
  895. If Not TryDoing(@InternalDelete,OnPostError) then exit;
  896. {$ifdef dsdebug}
  897. writeln ('Delete: Internaldelete succeeded');
  898. {$endif}
  899. FreeFieldBuffers;
  900. SetState(dsBrowse);
  901. {$ifdef dsdebug}
  902. writeln ('Delete: Browse mode set');
  903. {$endif}
  904. SetCurrentRecord(FActiverecord);
  905. Resync([]);
  906. DoAfterDelete;
  907. DoAfterScroll;
  908. end;
  909. end;
  910. Procedure TDataset.DisableControls;
  911. begin
  912. If FDisableControlsCount=0 then
  913. begin
  914. { Save current state,
  915. needed to detect change of state when enabling controls.
  916. }
  917. FDisableControlsState:=FState;
  918. FEnableControlsEvent:=deDatasetChange;
  919. end;
  920. Inc(FDisableControlsCount);
  921. end;
  922. Procedure TDataset.DoInsertAppend(DoAppend : Boolean);
  923. procedure DoInsert;
  924. Var BookBeforeInsert : TBookmarkStr;
  925. TempBuf : pointer;
  926. begin
  927. // need to scroll up al buffers after current one,
  928. // but copy current bookmark to insert buffer.
  929. If FRecordcount > 0 then
  930. BookBeforeInsert:=Bookmark;
  931. if FActiveRecord < FRecordCount-1 then
  932. begin
  933. TempBuf := FBuffers[FBuffercount];
  934. move(FBuffers[FActiveRecord],FBuffers[FActiveRecord+1],(Fbuffercount-FActiveRecord)*sizeof(FBuffers[0]));
  935. FBuffers[FActiveRecord]:=TempBuf;
  936. end
  937. else if FRecordcount=FBuffercount then
  938. shiftbuffersbackward
  939. else begin
  940. if FRecordCount>0 then
  941. inc(FActiveRecord);
  942. end;
  943. // Active buffer is now edit buffer. Initialize.
  944. InitRecord(FBuffers[FActiveRecord]);
  945. cursorposchanged;
  946. // Put bookmark in edit buffer.
  947. if FRecordCount=0 then
  948. begin
  949. fEOF := false;
  950. SetBookmarkFlag(ActiveBuffer,bfBOF)
  951. end
  952. else
  953. begin
  954. fBOF := false;
  955. // 29:01:05, JvdS: Why is this here?!? It can result in records with the same bookmark-data?
  956. // I would say that the 'internalinsert' should do this. But I don't know how Tdbf handles it
  957. if FRecordcount > 0 then
  958. SetBookMarkData(ActiveBuffer,pointer(BookBeforeInsert));
  959. end;
  960. InternalInsert;
  961. // update buffer count.
  962. If FRecordCount<FBufferCount then
  963. Inc(FRecordCount);
  964. end;
  965. begin
  966. If Not CanModify then
  967. DatabaseError(SDatasetReadOnly,Self);
  968. CheckBrowseMode;
  969. DoBeforeInsert;
  970. DoBeforeScroll;
  971. If Not DoAppend then
  972. begin
  973. {$ifdef dsdebug}
  974. Writeln ('going to insert mode');
  975. {$endif}
  976. DoInsert;
  977. end
  978. else
  979. begin
  980. {$ifdef dsdebug}
  981. Writeln ('going to append mode');
  982. {$endif}
  983. ClearBuffers;
  984. InternalLast;
  985. GetPriorRecords;
  986. if FRecordCount>0 then
  987. FActiveRecord:=FRecordCount-1;
  988. DoInsert;
  989. SetBookmarkFlag(ActiveBuffer,bfEOF);
  990. FBOF :=False;
  991. FEOF := true;
  992. end;
  993. SetState(dsInsert);
  994. try
  995. DoOnNewRecord;
  996. except
  997. SetCurrentRecord(FActiverecord);
  998. resync([]);
  999. raise;
  1000. end;
  1001. // mark as not modified.
  1002. FModified:=False;
  1003. // Final events.
  1004. DataEvent(deDatasetChange,0);
  1005. DoAfterInsert;
  1006. DoAfterScroll;
  1007. {$ifdef dsdebug}
  1008. Writeln ('Done with append');
  1009. {$endif}
  1010. end;
  1011. Procedure TDataset.Edit;
  1012. begin
  1013. If Not CanModify then
  1014. DatabaseError(SDatasetReadOnly,Self);
  1015. If State in [dsedit,dsinsert] then exit;
  1016. If FRecordCount = 0 then
  1017. begin
  1018. Append;
  1019. Exit;
  1020. end;
  1021. CheckBrowseMode;
  1022. DoBeforeEdit;
  1023. If Not TryDoing(@InternalEdit,OnEditError) then
  1024. exit;
  1025. SetState(dsedit);
  1026. DataEvent(deRecordChange,0);
  1027. DoAfterEdit;
  1028. end;
  1029. Procedure TDataset.EnableControls;
  1030. begin
  1031. If FDisableControlsCount>0 then
  1032. begin
  1033. Dec(FDisableControlsCount);
  1034. If FDisableControlsCount=0 then
  1035. begin
  1036. // State changed since disablecontrols ?
  1037. If FDisableControlsState<>FState then
  1038. DataEvent(deUpdateState,0);
  1039. If (FDisableControlsState<>dsInactive) and (FState<>dsInactive) then
  1040. DataEvent(FEnableControlsEvent,0);
  1041. end;
  1042. end;
  1043. end;
  1044. Function TDataset.FieldByName(const FieldName: string): TField;
  1045. begin
  1046. Result:=FindField(FieldName);
  1047. If Result=Nil then
  1048. DatabaseErrorFmt(SFieldNotFound,[FieldName],Self);
  1049. end;
  1050. Function TDataset.FindField(const FieldName: string): TField;
  1051. begin
  1052. Result:=FFieldList.FindField(FieldName);
  1053. end;
  1054. Function TDataset.FindFirst: Boolean;
  1055. begin
  1056. //!! To be implemented
  1057. end;
  1058. Function TDataset.FindLast: Boolean;
  1059. begin
  1060. //!! To be implemented
  1061. end;
  1062. Function TDataset.FindNext: Boolean;
  1063. begin
  1064. //!! To be implemented
  1065. end;
  1066. Function TDataset.FindPrior: Boolean;
  1067. begin
  1068. //!! To be implemented
  1069. end;
  1070. Procedure TDataset.First;
  1071. begin
  1072. CheckBrowseMode;
  1073. DoBeforeScroll;
  1074. ClearBuffers;
  1075. try
  1076. InternalFirst;
  1077. GetNextRecords;
  1078. finally
  1079. FBOF:=True;
  1080. DataEvent(deDatasetChange,0);
  1081. DoAfterScroll;
  1082. end;
  1083. end;
  1084. Procedure TDataset.FreeBookmark(ABookmark: TBookmark);
  1085. begin
  1086. FreeMem(ABookMark,FBookMarkSize);
  1087. end;
  1088. Function TDataset.GetBookmark: TBookmark;
  1089. begin
  1090. if BookmarkAvailable then
  1091. begin
  1092. GetMem (Result,FBookMarkSize);
  1093. GetBookMarkdata(ActiveBuffer,Result);
  1094. end
  1095. else
  1096. Result:=Nil;
  1097. end;
  1098. Function TDataset.GetCurrentRecord(Buffer: PChar): Boolean;
  1099. begin
  1100. Result:=False;
  1101. end;
  1102. Procedure TDataset.GetFieldList(List: TList; const FieldNames: string);
  1103. Function NextName(Var S : String) : String;
  1104. Var
  1105. P : integer;
  1106. begin
  1107. P:=Pos(';',S);
  1108. If (P=0) then
  1109. P:=Length(S)+1;
  1110. Result:=Copy(S,1,P-1);
  1111. system.Delete(S,1,P);
  1112. end;
  1113. var
  1114. F: TField;
  1115. Names,N : String;
  1116. begin
  1117. Names:=FieldNames;
  1118. N:=Nextname(Names);
  1119. while (N<>'') do
  1120. begin
  1121. F:=FieldByName(N);
  1122. If Assigned(List) then
  1123. List.Add(F);
  1124. N:=NextName(Names);
  1125. end;
  1126. end;
  1127. Procedure TDataset.GetFieldNames(List: TStrings);
  1128. begin
  1129. FFieldList.GetFieldNames(List);
  1130. end;
  1131. Procedure TDataset.GotoBookmark(ABookmark: TBookmark);
  1132. begin
  1133. If Assigned(ABookMark) then
  1134. begin
  1135. CheckBrowseMode;
  1136. DoBeforeScroll;
  1137. InternalGotoBookMark(ABookMark);
  1138. Resync([rmExact,rmCenter]);
  1139. DoAfterScroll;
  1140. end;
  1141. end;
  1142. Procedure TDataset.Insert;
  1143. begin
  1144. DoInsertAppend(False);
  1145. end;
  1146. Procedure TDataset.InsertRecord(const Values: array of const);
  1147. begin
  1148. //!! To be implemented
  1149. end;
  1150. Function TDataset.IsEmpty: Boolean;
  1151. begin
  1152. Result:=(Bof and Eof);
  1153. end;
  1154. Function TDataset.IsLinkedTo(DataSource: TDataSource): Boolean;
  1155. begin
  1156. //!! Not tested, I never used nested DS
  1157. if (DataSource = nil) or (DataSource.Dataset = nil) then begin
  1158. Result := False
  1159. end else if DataSource.Dataset = Self then begin
  1160. Result := True;
  1161. end else begin
  1162. Result := DataSource.Dataset.IsLinkedTo(DataSource.Dataset.DataSource);
  1163. end;
  1164. //!! DataSetField not implemented
  1165. end;
  1166. Function TDataset.IsSequenced: Boolean;
  1167. begin
  1168. Result := True;
  1169. end;
  1170. Procedure TDataset.Last;
  1171. begin
  1172. CheckBrowseMode;
  1173. DoBeforeScroll;
  1174. ClearBuffers;
  1175. try
  1176. InternalLast;
  1177. GetPriorRecords;
  1178. if FRecordCount>0 then
  1179. FActiveRecord:=FRecordCount-1
  1180. finally
  1181. FEOF:=true;
  1182. DataEvent(deDataSetChange, 0);
  1183. DoAfterScroll;
  1184. end;
  1185. end;
  1186. Function TDataset.MoveBy(Distance: Longint): Longint;
  1187. Var
  1188. TheResult: Integer;
  1189. Function Scrollforward : Integer;
  1190. begin
  1191. Result:=0;
  1192. {$ifdef dsdebug}
  1193. Writeln('Scrolling forward :',Distance);
  1194. Writeln('Active buffer : ',FActiveRecord);
  1195. Writeln('RecordCount : ',FRecordCount);
  1196. WriteLn('BufferCount : ',FBufferCount);
  1197. {$endif}
  1198. FBOF:=False;
  1199. While (Distance>0) and not FEOF do
  1200. begin
  1201. If FActiveRecord<FRecordCount-1 then
  1202. begin
  1203. Inc(FActiveRecord);
  1204. Dec(Distance);
  1205. Inc(TheResult); //Inc(Result);
  1206. end
  1207. else
  1208. begin
  1209. {$ifdef dsdebug}
  1210. Writeln('Moveby : need next record');
  1211. {$endif}
  1212. If GetNextRecord then
  1213. begin
  1214. Dec(Distance);
  1215. Dec(Result);
  1216. Inc(TheResult); //Inc(Result);
  1217. end
  1218. else
  1219. FEOF:=true;
  1220. end;
  1221. end
  1222. end;
  1223. Function ScrollBackward : Integer;
  1224. begin
  1225. if FIsUniDirectional then DatabaseError(SUniDirectional);
  1226. Result:=0;
  1227. {$ifdef dsdebug}
  1228. Writeln('Scrolling backward:',Abs(Distance));
  1229. Writeln('Active buffer : ',FActiveRecord);
  1230. Writeln('RecordCunt : ',FRecordCount);
  1231. WriteLn('BufferCount : ',FBufferCount);
  1232. {$endif}
  1233. FEOF:=False;
  1234. While (Distance<0) and not FBOF do
  1235. begin
  1236. If FActiveRecord>0 then
  1237. begin
  1238. Dec(FActiveRecord);
  1239. Inc(Distance);
  1240. Dec(TheResult); //Dec(Result);
  1241. end
  1242. else
  1243. begin
  1244. {$ifdef dsdebug}
  1245. Writeln('Moveby : need next record');
  1246. {$endif}
  1247. If GetPriorRecord then
  1248. begin
  1249. Inc(Distance);
  1250. Inc(Result);
  1251. Dec(TheResult); //Dec(Result);
  1252. end
  1253. else
  1254. FBOF:=true;
  1255. end;
  1256. end
  1257. end;
  1258. Var
  1259. Scrolled : Integer;
  1260. begin
  1261. CheckBrowseMode;
  1262. Result:=0; TheResult:=0;
  1263. If ((Distance>0) and FEOF) or
  1264. ((Distance<0) and FBOF) then
  1265. exit;
  1266. DoBeforeScroll;
  1267. Try
  1268. Scrolled := 0;
  1269. If Distance>0 then
  1270. Scrolled:=ScrollForward
  1271. else
  1272. Scrolled:=ScrollBackward;
  1273. finally
  1274. {$ifdef dsdebug}
  1275. WriteLn('ActiveRecord=', FActiveRecord,' FEOF=',FEOF,' FBOF=',FBOF);
  1276. {$Endif}
  1277. // If FRecordCount<>PrevRecordCount then
  1278. if Scrolled = 0 then
  1279. DataEvent(deDatasetChange,0)
  1280. else
  1281. DataEvent(deDatasetScroll,Scrolled);
  1282. DoAfterScroll;
  1283. Result:=TheResult;
  1284. end;
  1285. end;
  1286. Procedure TDataset.Next;
  1287. begin
  1288. MoveBy(1);
  1289. end;
  1290. Procedure TDataset.Open;
  1291. begin
  1292. Active:=True;
  1293. end;
  1294. Procedure TDataset.Post;
  1295. Procedure Checkrequired;
  1296. Var I : longint;
  1297. begin
  1298. For I:=0 to FFieldList.Count-1 do
  1299. With FFieldList[i] do
  1300. // Required fields that are NOT autoinc !! Autoinc cannot be set !!
  1301. if Required and not ReadOnly and
  1302. (FieldKind=fkData) and Not (DataType=ftAutoInc) then
  1303. DatabaseErrorFmt(SNeedField,[DisplayName],Self);
  1304. end;
  1305. begin
  1306. if State in [dsEdit,dsInsert] then
  1307. begin
  1308. DataEvent(deUpdateRecord,0);
  1309. DataEvent(deCheckBrowseMode,0);
  1310. {$ifdef dsdebug}
  1311. writeln ('Post: checking required fields');
  1312. {$endif}
  1313. CheckRequired;
  1314. DoBeforePost;
  1315. If Not TryDoing(@InternalPost,OnPostError) then exit;
  1316. cursorposchanged;
  1317. {$ifdef dsdebug}
  1318. writeln ('Post: Internalpost succeeded');
  1319. {$endif}
  1320. FreeFieldBuffers;
  1321. // First set the state to dsBrowse, then the Resync, to prevent the calling of
  1322. // the deDatasetChange event, while the state is still 'editable', while the db isn't
  1323. SetState(dsBrowse);
  1324. Resync([]);
  1325. {$ifdef dsdebug}
  1326. writeln ('Post: Browse mode set');
  1327. {$endif}
  1328. DoAfterPost;
  1329. end;
  1330. end;
  1331. Procedure TDataset.Prior;
  1332. begin
  1333. MoveBy(-1);
  1334. end;
  1335. Procedure TDataset.Refresh;
  1336. begin
  1337. CheckbrowseMode;
  1338. UpdateCursorPos;
  1339. InternalRefresh;
  1340. SetCurrentRecord(FActiverecord);
  1341. Resync([]);
  1342. end;
  1343. Procedure TDataset.RegisterDataSource(ADatasource : TDataSource);
  1344. begin
  1345. FDatasources.Add(ADataSource);
  1346. RecalcBufListSize;
  1347. end;
  1348. Procedure TDataset.Resync(Mode: TResyncMode);
  1349. var i,count : integer;
  1350. begin
  1351. // See if we can find the requested record.
  1352. {$ifdef dsdebug}
  1353. Writeln ('Resync called');
  1354. {$endif}
  1355. // place the cursor of the underlying dataset to the active record
  1356. // SetCurrentRecord(FActiverecord);
  1357. // Now look if the data on the current cursor of the underlying dataset is still available
  1358. If GetRecord(Fbuffers[0],gmcurrent,False)<>grOk Then
  1359. // If that fails and rmExact is set, then raise an exception
  1360. If rmExact in Mode then
  1361. DatabaseError(SNoSuchRecord,Self)
  1362. // else, if rmexact is not set, try to fetch the next or prior record in the underlying dataset
  1363. else if (GetRecord(Fbuffers[0],gmnext,True)<>grOk) and
  1364. (GetRecord(Fbuffers[0],gmprior,True)<>grOk) then
  1365. begin
  1366. {$ifdef dsdebug}
  1367. Writeln ('Resync: fuzzy resync');
  1368. {$endif}
  1369. // nothing found, invalidate buffer and bail out.
  1370. ClearBuffers;
  1371. DataEvent(deDatasetChange,0);
  1372. exit;
  1373. end;
  1374. FCurrentRecord := 0;
  1375. FEOF := false;
  1376. FBOF := false;
  1377. // If we've arrived here, FBuffer[0] is the current record
  1378. If (rmCenter in Mode) then
  1379. count := (FRecordCount div 2)
  1380. else
  1381. count := FActiveRecord;
  1382. i := 0;
  1383. FRecordcount := 1;
  1384. FActiveRecord := 0;
  1385. // Fill the buffers before the active record
  1386. while (i < count) and GetPriorRecord do
  1387. inc(i);
  1388. FActiveRecord := i;
  1389. // Fill the rest of the buffer
  1390. getnextrecords;
  1391. // If the buffer is not full yet, try to fetch some more prior records
  1392. if FRecordcount < FBuffercount then inc(FActiverecord,getpriorrecords);
  1393. // That's all folks!
  1394. DataEvent(deDatasetChange,0);
  1395. end;
  1396. Procedure TDataset.SetFields(const Values: array of const);
  1397. Var I : longint;
  1398. begin
  1399. For I:=0 to high(Values) do
  1400. Fields[I].AssignValue(Values[I]);
  1401. end;
  1402. Function TDataset.Translate(Src, Dest: PChar; ToOem: Boolean): Integer;
  1403. begin
  1404. //!! To be implemented
  1405. end;
  1406. Function Tdataset.TryDoing (P : TDataOperation; Ev : TDatasetErrorEvent) : Boolean;
  1407. Var Retry : TDataAction;
  1408. begin
  1409. {$ifdef dsdebug}
  1410. Writeln ('Trying to do');
  1411. If P=Nil then writeln ('Procedure to call is nil !!!');
  1412. {$endif dsdebug}
  1413. Result:=True;
  1414. Retry:=daRetry;
  1415. while Retry=daRetry do
  1416. Try
  1417. {$ifdef dsdebug}
  1418. Writeln ('Trying : updatecursorpos');
  1419. {$endif dsdebug}
  1420. UpdateCursorPos;
  1421. {$ifdef dsdebug}
  1422. Writeln ('Trying to do it');
  1423. {$endif dsdebug}
  1424. P;
  1425. exit;
  1426. except
  1427. On E : EDatabaseError do
  1428. begin
  1429. retry:=daFail;
  1430. If Assigned(Ev) then
  1431. Ev(Self,E,Retry);
  1432. Case Retry of
  1433. daFail : Raise;
  1434. daAbort : Result:=False;
  1435. end;
  1436. end;
  1437. else
  1438. Raise;
  1439. end;
  1440. {$ifdef dsdebug}
  1441. Writeln ('Exit Trying to do');
  1442. {$endif dsdebug}
  1443. end;
  1444. Procedure TDataset.UpdateCursorPos;
  1445. begin
  1446. If FRecordCount>0 then
  1447. SetCurrentRecord(FactiveRecord);
  1448. end;
  1449. Procedure TDataset.UpdateRecord;
  1450. begin
  1451. if not (State in dsEditModes) then
  1452. DatabaseError(SNotInEditState, Self);
  1453. DataEvent(deUpdateRecord, 0);
  1454. end;
  1455. Function TDataSet.UpdateStatus: TUpdateStatus;
  1456. begin
  1457. Result:=usUnmodified;
  1458. end;
  1459. Procedure TDataset.RemoveField (Field : TField);
  1460. begin
  1461. //!! To be implemented
  1462. end;
  1463. Function TDataset.Getfieldcount : Longint;
  1464. begin
  1465. Result:=FFieldList.Count;
  1466. end;
  1467. Procedure TDataset.ShiftBuffersBackward;
  1468. var TempBuf : pointer;
  1469. begin
  1470. TempBuf := FBuffers[0];
  1471. move(FBuffers[1],FBuffers[0],(fbuffercount)*sizeof(FBuffers[0]));
  1472. FBuffers[buffercount]:=TempBuf;
  1473. end;
  1474. Procedure TDataset.ShiftBuffersForward;
  1475. var TempBuf : pointer;
  1476. begin
  1477. TempBuf := FBuffers[FBufferCount];
  1478. move(FBuffers[0],FBuffers[1],(fbuffercount)*sizeof(FBuffers[0]));
  1479. FBuffers[0]:=TempBuf;
  1480. end;
  1481. function TDataset.GetFieldValues(Fieldname : string) : string;
  1482. begin
  1483. result := findfield(Fieldname).asstring;
  1484. end;
  1485. procedure TDataset.SetFieldValues(Fieldname : string;value : string);
  1486. begin
  1487. findfield(Fieldname).asstring := value;
  1488. end;
  1489. Function TDataset.Locate(const keyfields: string; const keyvalues: Variant; options: TLocateOptions) : boolean;
  1490. begin
  1491. if fIsUnidirectional then
  1492. DataBaseError(SUniDirectional);
  1493. Result := False;
  1494. end;
  1495. Function TDataset.Lookup(const KeyFields: string; const KeyValues: Variant; const ResultFields: string): Variant;
  1496. begin
  1497. Result := False;
  1498. end;
  1499. Procedure TDataset.UnRegisterDataSource(ADatasource : TDatasource);
  1500. begin
  1501. FDataSources.Remove(ADataSource);
  1502. end;
  1503. {
  1504. $Log: dataset.inc,v $
  1505. Revision 1.36 2005/04/13 22:08:16 joost
  1506. - fixed mem-leak in TDataset.SetBufListSize
  1507. Revision 1.35 2005/04/10 22:18:43 joost
  1508. Patch from Alexandrov Alexandru
  1509. - implemented TDataset.BindFields
  1510. - master-detail relation implemented
  1511. - improved variant-support for fields
  1512. - implemented TField.Assign and TField.AssignValue
  1513. Revision 1.34 2005/04/10 18:26:27 joost
  1514. - implemented TDataset.Locate
  1515. Revision 1.33 2005/03/29 10:07:34 michael
  1516. + fix for activerecord, bof false after append.
  1517. Revision 1.32 2005/02/14 17:13:12 peter
  1518. * truncate log
  1519. Revision 1.31 2005/02/07 11:19:27 joost
  1520. - Fixed insertion at buffer-limit
  1521. - Added TDataset.InternalInsert
  1522. - The deDatasetScrollEvent was not always raised
  1523. - Changed resync-order in AppendRecord
  1524. Revision 1.30 2005/01/12 10:27:57 michael
  1525. * Patch from Joost Van der Sluis:
  1526. - implemented ControlsDisabled
  1527. }