dataset.inc 39 KB

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