1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843 |
- {
- This file is part of the Free Pascal run time library.
- Copyright (c) 1999-2000 by Michael Van Canneyt, member of the
- Free Pascal development team
- Dataset implementation
- See the file COPYING.FPC, included in this distribution,
- for details about the copyright.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- **********************************************************************}
- { ---------------------------------------------------------------------
- TDataSet
- ---------------------------------------------------------------------}
- Const
- DefaultBufferCount = 10;
- constructor TDataSet.Create(AOwner: TComponent);
- begin
- Inherited Create(AOwner);
- FFieldDefs:=TFieldDefs.Create(Self);
- FFieldList:=TFields.Create(Self);
- FDataSources:=TList.Create;
- end;
- destructor TDataSet.Destroy;
- var
- i: Integer;
- begin
- Active:=False;
- FFieldDefs.Free;
- FFieldList.Free;
- With FDatasources do
- begin
- While Count>0 do
- TDatasource(Items[Count - 1]).DataSet:=Nil;
- Free;
- end;
- if Assigned(FBuffers) then
- begin
- for i := 0 to FBufferCount do
- FreeRecordBuffer(FBuffers[i]);
- FreeMem(FBuffers);
- end;
- Inherited Destroy;
- end;
- // This procedure must be called when the first record is made/read
- Procedure TDataset.ActivateBuffers;
- begin
- FBOF:=False;
- FEOF:=False;
- FActiveRecord:=0;
- end;
- Procedure TDataset.UpdateFieldDefs;
- begin
- //!! To be implemented
- end;
- Procedure TDataset.BindFields(Binding: Boolean);
- var i, FieldIndex: Integer;
- FieldDef: TFieldDef;
- begin
- {
- Here some magic will be needed later; for now just simply set
- Just set fieldno from listindex...
- Later we should take it from the fielddefs.
- // ATM Set by CreateField ...
- For I:=0 to FFieldList.Count-1 do
- FFieldList[i].FFieldNo:=I;
- }
- FBlobFieldCount := 0;
- for i := 0 to Fields.Count - 1 do
- with Fields[i] do begin
- if Binding then begin
- FieldDef := nil;
- FieldIndex := FieldDefs.IndexOf(Fields[i].FieldName);
- if FieldIndex <> -1 then begin
- FieldDef := FieldDefs[FieldIndex];
- FFieldNo := FieldDef.FieldNo;
- if IsBlob then begin
- FSize := FieldDef.Size;
- FOffset := FBlobFieldCount;
- Inc(FBlobFieldCount);
- end;
- end else FFieldNo := FieldIndex;
- end else FFieldNo := 0;;
- end;
- end;
- Function TDataset.BookmarkAvailable: Boolean;
- Const BookmarkStates = [dsBrowse,dsEdit,dsInsert];
- begin
- Result:=(Not IsEmpty) and (State in BookmarkStates)
- and (getBookMarkFlag(ActiveBuffer)=bfCurrent);
- end;
- Procedure TDataset.CalculateFields(Buffer: PChar);
- begin
- { no internal calced fields or caches yet }
- DoOnCalcFields;
- end;
- Procedure TDataset.CheckActive;
- begin
- If Not Active then
- DataBaseError(SInactiveDataset);
- end;
- Procedure TDataset.CheckInactive;
- begin
- If Active then
- DataBaseError(SActiveDataset);
- end;
- Procedure TDataset.ClearBuffers;
- begin
- FRecordCount:=0;
- FactiveRecord:=0;
- FCurrentRecord:=-1;
- FBOF:=True;
- FEOF:=True;
- end;
- Procedure TDataset.ClearCalcFields(Buffer: PChar);
- begin
- //!! To be implemented
- end;
- Procedure TDataset.CloseBlob(Field: TField);
- begin
- //!! To be implemented
- end;
- Procedure TDataset.CloseCursor;
- begin
- //!! To be implemented
- end;
- Procedure TDataset.CreateFields;
- Var I : longint;
- begin
- {$ifdef DSDebug}
- Writeln ('Creating fields');
- Writeln ('Count : ',fielddefs.Count);
- For I:=0 to FieldDefs.Count-1 do
- Writeln('Def ',I,' : ',Fielddefs.items[i].Name,'(',Fielddefs.items[i].FieldNo,')');
- {$endif}
- For I:=0 to fielddefs.Count-1 do
- With Fielddefs.Items[I] do
- If DataType<>ftUnknown then
- begin
- {$ifdef DSDebug}
- Writeln('About to create field',FieldDefs.Items[i].Name);
- {$endif}
- CreateField(self);
- end;
- end;
- Procedure TDataset.DataEvent(Event: TDataEvent; Info: Ptrint);
- Var
- i : longint;
- begin
- // Do some bookkeeping;
- case Event of
- deFieldChange: begin
- if TField(Info).FieldKind in [fkData,fkInternalCalc] then
- SetModified(True);
- if State <> dsSetKey then begin
- if FInternalCalcFields and (TField(Info).FieldKind = fkData) then
- RefreshInternalCalcFields(ActiveBuffer)
- else if (FCalcFieldsSize <> 0) and FAutoCalcFields and
- (TField(Info).FieldKind = fkData) then
- CalculateFields(ActiveBuffer);
- TField(Info).Change;
- end;
- end;
- deDataSetChange, deDataSetScroll:
- if State <> dsInsert then UpdateCursorPos;
- end;
- // Distribute event to datasets;
- if FDisableControlsCount = 0 then
- for I := 0 to FDataSources.Count - 1 do
- TDataSource(FDataSources[I]).ProcessEvent(Event, Info);
- end;
- Procedure TDataset.DestroyFields;
- begin
- FFieldList.Clear;
- end;
- Procedure TDataset.DoAfterCancel;
- begin
- If assigned(FAfterCancel) then
- FAfterCancel(Self);
- end;
- Procedure TDataset.DoAfterClose;
- begin
- If assigned(FAfterClose) then
- FAfterClose(Self);
- end;
- Procedure TDataset.DoAfterDelete;
- begin
- If assigned(FAfterDelete) then
- FAfterDelete(Self);
- end;
- Procedure TDataset.DoAfterEdit;
- begin
- If assigned(FAfterEdit) then
- FAfterEdit(Self);
- end;
- Procedure TDataset.DoAfterInsert;
- begin
- If assigned(FAfterInsert) then
- FAfterInsert(Self);
- end;
- Procedure TDataset.DoAfterOpen;
- begin
- If assigned(FAfterOpen) then
- FAfterOpen(Self);
- end;
- Procedure TDataset.DoAfterPost;
- begin
- If assigned(FAfterPost) then
- FAfterPost(Self);
- end;
- Procedure TDataset.DoAfterScroll;
- begin
- If assigned(FAfterScroll) then
- FAfterScroll(Self);
- end;
- Procedure TDataset.DoBeforeCancel;
- begin
- If assigned(FBeforeCancel) then
- FBeforeCancel(Self);
- end;
- Procedure TDataset.DoBeforeClose;
- begin
- If assigned(FBeforeClose) then
- FBeforeClose(Self);
- end;
- Procedure TDataset.DoBeforeDelete;
- begin
- If assigned(FBeforeDelete) then
- FBeforeDelete(Self);
- end;
- Procedure TDataset.DoBeforeEdit;
- begin
- If assigned(FBeforeEdit) then
- FBeforeEdit(Self);
- end;
- Procedure TDataset.DoBeforeInsert;
- begin
- If assigned(FBeforeInsert) then
- FBeforeInsert(Self);
- end;
- Procedure TDataset.DoBeforeOpen;
- begin
- If assigned(FBeforeOpen) then
- FBeforeOpen(Self);
- end;
- Procedure TDataset.DoBeforePost;
- begin
- If assigned(FBeforePost) then
- FBeforePost(Self);
- end;
- Procedure TDataset.DoBeforeScroll;
- begin
- If assigned(FBeforeScroll) then
- FBeforeScroll(Self);
- end;
- Procedure TDataset.DoInternalOpen;
- begin
- FDefaultFields:=FieldCount=0;
- DoBeforeOpen;
- Try
- {$ifdef dsdebug}
- Writeln ('Calling internal open');
- {$endif}
- InternalOpen;
- FBOF:=True;
- {$ifdef dsdebug}
- Writeln ('Calling RecalcBufListSize');
- {$endif}
- FRecordcount := 0;
- RecalcBufListSize;
- FEOF := (FRecordcount = 0);
- {$ifdef dsdebug}
- Writeln ('Setting state to browse');
- {$endif}
- SetState(dsBrowse);
- DoAfterOpen;
- DoAfterScroll;
- except
- DoInternalClose(false);
- raise;
- end;
- end;
- Procedure TDataset.DoInternalClose(DoCheck : Boolean);
- begin
- if DoCheck then
- CheckBrowsemode;
- FreeFieldBuffers;
- ClearBuffers;
- SetBufListSize(-1);
- SetState(dsInactive);
- InternalClose;
- end;
- Procedure TDataset.DoOnCalcFields;
- begin
- If assigned(FOnCalcfields) then
- FOnCalcFields(Self);
- end;
- Procedure TDataset.DoOnNewRecord;
- begin
- If assigned(FOnNewRecord) then
- FOnNewRecord(Self);
- end;
- Function TDataset.FieldByNumber(FieldNo: Longint): TField;
- begin
- Result:=FFieldList.FieldByNumber(FieldNo);
- end;
- Function TDataset.FindRecord(Restart, GoForward: Boolean): Boolean;
- begin
- //!! To be implemented
- end;
- Procedure TDataset.FreeFieldBuffers;
- Var I : longint;
- begin
- For I:=0 to FFieldList.Count-1 do
- FFieldList[i].FreeBuffers;
- end;
- Function TDataset.GetBookmarkStr: TBookmarkStr;
- begin
- Result:='';
- If BookMarkAvailable then
- begin
- SetLength(Result,FBookMarkSize);
- GetBookMarkData(ActiveBuffer,Pointer(Result));
- end
- end;
- Function TDataset.GetBuffer (Index : longint) : Pchar;
- begin
- Result:=FBuffers[Index];
- end;
- Procedure TDataset.GetCalcFields(Buffer: PChar);
- begin
- //!! To be implemented
- end;
- Function TDataset.GetCanModify: Boolean;
- begin
- Result:= not FIsUnidirectional;
- end;
- Procedure TDataset.GetChildren(Proc: TGetChildProc; Root: TComponent);
- begin
- //!! To be implemented
- end;
- Function TDataset.GetDataSource: TDataSource;
- begin
- Result:=nil;
- end;
- Function TDataset.GetField (Index : Longint) : TField;
- begin
- Result:=FFIeldList[index];
- end;
- {
- This is not yet allowed, FPC doesn't allow typed consts of Classes...
- Const
- DefFieldClasses : Array [TFieldType] of TFieldClass =
- ( { ftUnknown} Tfield,
- { ftString} TStringField,
- { ftSmallint} TLongIntField,
- { ftInteger} TLongintField,
- { ftWord} TLongintField,
- { ftBoolean} TBooleanField,
- { ftFloat} TFloatField,
- { ftDate} TDateField,
- { ftTime} TTimeField,
- { ftDateTime} TDateTimeField,
- { ftBytes} TBytesField,
- { ftVarBytes} TVarBytesField,
- { ftAutoInc} TAutoIncField,
- { ftBlob} TBlobField,
- { ftMemo} TMemoField,
- { ftGraphic} TGraphicField,
- { ftFmtMemo} TMemoField,
- { ftParadoxOle} Nil,
- { ftDBaseOle} Nil,
- { ftTypedBinary} Nil,
- { ftCursor} Nil
- );
- }
- Function TDataset.GetFieldClass(FieldType: TFieldType): TFieldClass;
- begin
- Case FieldType of
- ftUnknown : Result:=Tfield;
- ftString: Result := TStringField;
- ftLargeint: Result := TLargeintField;
- ftSmallint: Result := TSmallIntField;
- ftInteger: Result := TLongintField;
- ftWord: Result := TWordField;
- ftBoolean: Result := TBooleanField;
- ftFloat: Result := TFloatField;
- ftBCD: Result := TBCDField;
- ftDate: Result := TDateField;
- ftTime: Result := TTimeField;
- ftDateTime: Result := TDateTimeField;
- ftBytes: Result := TBytesField;
- ftVarBytes: Result := TVarBytesField;
- ftAutoInc: Result := TAutoIncField;
- ftBlob: Result := TBlobField;
- ftMemo: Result := TMemoField;
- ftGraphic: Result := TGraphicField;
- ftFmtMemo: Result := TMemoField;
- ftParadoxOle: Result := Nil;
- ftDBaseOle: Result := Nil;
- ftTypedBinary: Result := Nil;
- ftCursor: Result := Nil
- else
- Result := nil;
- end;
- end;
- Function TDataset.GetIsIndexField(Field: TField): Boolean;
- begin
- //!! To be implemented
- end;
- Function TDataset.GetNextRecord: Boolean;
- procedure ExchangeBuffers(var buf1,buf2 : pointer);
- var tempbuf : pointer;
- begin
- tempbuf := buf1;
- buf1 := buf2;
- buf2 := tempbuf;
- end;
- begin
- {$ifdef dsdebug}
- Writeln ('Getting next record. Internal RecordCount : ',FRecordCount);
- {$endif}
- If FRecordCount>0 Then SetCurrentRecord(FRecordCount-1);
- Result:=GetRecord(FBuffers[FBuffercount],gmNext,True)=grOK;
- if result then
- begin
- If FRecordCount=0 then ActivateBuffers;
- if FRecordcount=FBuffercount then
- shiftbuffersbackward
- else
- begin
- inc(FRecordCount);
- FCurrentRecord:=FRecordCount - 1;
- ExchangeBuffers(Fbuffers[FCurrentRecord],FBuffers[FBuffercount]);
- end;
- end
- else
- cursorposchanged;
- {$ifdef dsdebug}
- Writeln ('Result getting next record : ',Result);
- {$endif}
- end;
- Function TDataset.GetNextRecords: Longint;
- begin
- Result:=0;
- {$ifdef dsdebug}
- Writeln ('Getting next record(s), need :',FBufferCount);
- {$endif}
- While (FRecordCount<FBufferCount) and GetNextRecord do
- Inc(Result);
- {$ifdef dsdebug}
- Writeln ('Result Getting next record(S), GOT :',RESULT);
- {$endif}
- end;
- Function TDataset.GetPriorRecord: Boolean;
- begin
- {$ifdef dsdebug}
- Writeln ('GetPriorRecord: Getting previous record');
- {$endif}
- If FRecordCount>0 Then SetCurrentRecord(0);
- Result:=GetRecord(FBuffers[FBuffercount],gmPrior,True)=grOK;
- if result then
- begin
- If FRecordCount=0 then ActivateBuffers;
- shiftbuffersforward;
- if FRecordcount<FBuffercount then
- inc(FRecordCount);
- end
- else
- cursorposchanged;
- {$ifdef dsdebug}
- Writeln ('Result getting prior record : ',Result);
- {$endif}
- end;
- Function TDataset.GetPriorRecords: Longint;
- begin
- Result:=0;
- {$ifdef dsdebug}
- Writeln ('Getting previous record(s), need :',FBufferCount);
- {$endif}
- While (FRecordCount<FbufferCount) and GetPriorRecord do
- Inc(Result);
- end;
- Function TDataset.GetRecNo: Longint;
- begin
- Result := -1;
- end;
- Function TDataset.GetRecordCount: Longint;
- begin
- Result := -1;
- end;
- Procedure TDataset.InitFieldDefs;
- begin
- //!! To be implemented
- end;
- Procedure TDataset.InitRecord(Buffer: PChar);
- begin
- InternalInitRecord(Buffer);
- ClearCalcFields(Buffer);
- end;
- Procedure TDataset.InternalCancel;
- begin
- //!! To be implemented
- end;
- Procedure TDataset.InternalEdit;
- begin
- //!! To be implemented
- end;
- Procedure TDataset.InternalRefresh;
- begin
- //!! To be implemented
- end;
- Procedure TDataset.OpenCursor(InfoQuery: Boolean);
- begin
- //!! To be implemented
- end;
- Procedure TDataset.RefreshInternalCalcFields(Buffer: PChar);
- begin
- //!! To be implemented
- end;
- Function TDataset.SetTempState(const Value: TDataSetState): TDataSetState;
- begin
- result := FState;
- FState := value;
- inc(FDisableControlsCount);
- end;
- Procedure TDataset.RestoreState(const Value: TDataSetState);
- begin
- FState := value;
- dec(FDisableControlsCount);
- end;
- function TDataset.GetActive : boolean;
- begin
- result := FState <> dsInactive;
- end;
- Procedure TDataset.SetActive (Value : Boolean);
- begin
- if value and (Fstate = dsInactive) then
- begin
- if csLoading in ComponentState then
- begin
- FOpenAfterRead := true;
- exit;
- end
- else
- DoInternalOpen;
- end
- else if not value and (Fstate <> dsinactive) then
- DoInternalClose(True);
- end;
- procedure TDataset.Loaded;
- begin
- inherited;
- if FOpenAfterRead then SetActive(true);
- end;
- procedure TDataSet.RecalcBufListSize;
- var
- i, j, ABufferCount: Integer;
- DataLink: TDataLink;
- begin
- {$ifdef dsdebug}
- Writeln('Recalculating buffer list size - check cursor');
- {$endif}
- If Not IsCursorOpen Then
- Exit;
- {$ifdef dsdebug}
- Writeln('Recalculating buffer list size');
- {$endif}
- ABufferCount := DefaultBufferCount;
- for i := 0 to FDataSources.Count - 1 do
- for j := 0 to TDataSource(FDataSources[i]).DataLinks.Count - 1 do
- begin
- DataLink:=TDataLink(TDataSource(FDataSources[i]).DataLinks[j]);
- if DataLink.BufferCount>ABufferCount then
- ABufferCount:=DataLink.BufferCount;
- end;
- If (FBufferCount=ABufferCount) Then
- exit;
- {$ifdef dsdebug}
- Writeln('Setting buffer list size');
- {$endif}
- SetBufListSize(ABufferCount);
- {$ifdef dsdebug}
- Writeln('Getting next buffers');
- {$endif}
- GetNextRecords;
- {$Ifdef dsDebug}
- WriteLn(
- 'SetBufferCount: FActiveRecord=',FActiveRecord,
- ' FCurrentRecord=',FCurrentRecord,
- ' FBufferCount= ',FBufferCount,
- ' FRecordCount=',FRecordCount);
- {$Endif}
- end;
- Procedure TDataset.SetBookmarkStr(const Value: TBookmarkStr);
- begin
- GotoBookMark(Pointer(Value))
- end;
- Procedure TDataset.SetBufListSize(Value: Longint);
- Var I : longint;
- begin
- {$ifdef dsdebug}
- Writeln ('SetBufListSize: ',Value);
- {$endif}
- If Value=FBufferCount Then
- exit;
- If Value>FBufferCount then
- begin
- {$ifdef dsdebug}
- Writeln (' Reallocating memory :',(Value+1)*SizeOf(PChar));
- {$endif}
- ReAllocMem(FBuffers,(Value+1)*SizeOf(PChar));
- {$ifdef dsdebug}
- Writeln (' Filling memory :',(Value+1-FBufferCount)*SizeOf(PChar));
- {$endif}
- if FBufferCount > 0 then inc(FBufferCount); // Cause FBuffers[FBufferCount] is already allocated
- FillChar(FBuffers[FBufferCount],(Value+1-FBufferCount)*SizeOF(Pchar),#0);
- {$ifdef dsdebug}
- Writeln (' Filled memory :');
- {$endif}
- Try
- {$ifdef dsdebug}
- Writeln (' Assigning buffers :',(Value)*SizeOf(PChar));
- {$endif}
- For I:=FBufferCount to Value do
- FBuffers[i]:=AllocRecordBuffer;
- {$ifdef dsdebug}
- Writeln (' Assigned buffers ',FBufferCount,' :',(Value)*SizeOf(PChar));
- {$endif}
- except
- I:=FBufferCount;
- While (I<(Value+1)) and (FBuffers[i]<>Nil) do
- begin
- FreeRecordBuffer(FBuffers[i]);
- Inc(i);
- end;
- raise;
- end;
- end
- else
- begin
- {$ifdef dsdebug}
- Writeln (' Freeing buffers :',FBufferCount-Value);
- {$endif}
- if (value > -1) and (FActiveRecord>Value-1) then
- begin
- for i := 0 to (FActiveRecord-Value) do
- shiftbuffersbackward;
- FActiverecord := Value -1;
- end;
- If Assigned(FBuffers) then
- begin
- For I:=Value+1 to FBufferCount do
- FreeRecordBuffer(FBuffers[i]);
- ReAllocMem(FBuffers,(Value+1)*SizeOf(Pchar));
- end;
- if FRecordcount > Value then FRecordcount := Value;
- end;
- If Value=-1 then
- Value:=0;
- FBufferCount:=Value;
- {$ifdef dsdebug}
- Writeln (' SetBufListSize: Final FBufferCount=',FBufferCount);
- {$endif}
- end;
- Procedure TDataset.SetChildOrder(Component: TComponent; Order: Longint);
- begin
- //!! To be implemented
- end;
- Procedure TDataset.SetCurrentRecord(Index: Longint);
- begin
- If FCurrentRecord<>Index then
- begin
- {$ifdef DSdebug}
- Writeln ('Setting current record to',index);
- {$endif}
- Case GetBookMarkFlag(FBuffers[Index]) of
- bfCurrent : InternalSetToRecord(FBuffers[Index]);
- bfBOF : InternalFirst;
- bfEOF : InternalLast;
- end;
- FCurrentRecord:=index;
- end;
- end;
- Procedure TDataset.SetField (Index : Longint;Value : TField);
- begin
- //!! To be implemented
- end;
- Procedure TDataset.SetFilterOptions(Value: TFilterOptions);
- begin
- //!! To be implemented
- end;
- Procedure TDataset.SetFilterText(const Value: string);
- begin
- FFilterText := value;
- end;
- Procedure TDataset.SetFiltered(Value: Boolean);
- begin
- FFiltered := value;
- end;
- Procedure TDataset.SetFound(const Value: Boolean);
- begin
- //!! To be implemented
- end;
- Procedure TDataset.SetModified(Value: Boolean);
- begin
- FModified := value;
- end;
- Procedure TDataset.SetName(const Value: TComponentName);
- begin
- //!! To be implemented
- inherited SetName(Value);
- end;
- Procedure TDataset.SetOnFilterRecord(const Value: TFilterRecordEvent);
- begin
- //!! To be implemented
- end;
- Procedure TDataset.SetRecNo(Value: Longint);
- begin
- //!! To be implemented
- end;
- Procedure TDataset.SetState(Value: TDataSetState);
- begin
- If Value<>FState then
- begin
- FState:=Value;
- DataEvent(deUpdateState,0);
- end;
- end;
- Function TDataset.TempBuffer: PChar;
- begin
- //!! To be implemented
- end;
- Procedure TDataset.UpdateIndexDefs;
- begin
- // Empty Abstract
- end;
- Function TDataset.ControlsDisabled: Boolean;
- begin
- Result := (FDisableControlsCount > 0);
- end;
- Function TDataset.ActiveBuffer: PChar;
- begin
- {$ifdef dsdebug}
- Writeln ('Active buffer requested. Returning:',ActiveRecord);
- {$endif}
- Result:=FBuffers[FActiveRecord];
- end;
- Procedure TDataset.Append;
- begin
- DoInsertAppend(True);
- end;
- Procedure TDataset.InternalInsert;
- begin
- //!! To be implemented
- end;
- Procedure TDataset.AppendRecord(const Values: array of const);
- begin
- //!! To be implemented
- end;
- Function TDataset.BookmarkValid(ABookmark: TBookmark): Boolean;
- {
- Should be overridden by descendant objects.
- }
- begin
- Result:=False
- end;
- Procedure TDataset.Cancel;
- begin
- If State in [dsEdit,dsInsert] then
- begin
- DataEvent(deCheckBrowseMode,0);
- DoBeforeCancel;
- UpdateCursorPos;
- InternalCancel;
- FreeFieldBuffers;
- if (state = dsInsert) and (FRecordcount = 1) then
- begin
- FEOF := true;
- FBOF := true;
- FRecordcount := 0;
- SetState(dsBrowse);
- DataEvent(deDatasetChange,0);
- end
- else
- begin
- SetState(dsBrowse);
- SetCurrentRecord(FActiverecord);
- resync([]);
- end;
- DoAfterCancel;
- end;
- end;
- Procedure TDataset.CheckBrowseMode;
- begin
- CheckActive;
- DataEvent(deCheckBrowseMode,0);
- Case State of
- dsedit,dsinsert: begin
- UpdateRecord;
- If Modified then Post else Cancel;
- end;
- dsSetKey: Post;
- end;
- end;
- Procedure TDataset.ClearFields;
- begin
- //!! To be implemented
- end;
- Procedure TDataset.Close;
- begin
- Active:=False;
- end;
- Function TDataset.CompareBookmarks(Bookmark1, Bookmark2: TBookmark): Longint;
- begin
- Result:=0;
- end;
- Function TDataset.CreateBlobStream(Field: TField; Mode: TBlobStreamMode): TStream;
- begin
- Result:=Nil;
- end;
- Procedure TDataset.CursorPosChanged;
- begin
- FCurrentRecord:=-1;
- end;
- Procedure TDataset.Delete;
- begin
- If Not CanModify then
- DatabaseError(SDatasetReadOnly,Self);
- if State in [dsInsert] then
- begin
- Cancel;
- end else begin
- DataEvent(deCheckBrowseMode,0);
- {$ifdef dsdebug}
- writeln ('Delete: checking required fields');
- {$endif}
- DoBeforeDelete;
- DoBeforeScroll;
- If Not TryDoing(@InternalDelete,OnPostError) then exit;
- {$ifdef dsdebug}
- writeln ('Delete: Internaldelete succeeded');
- {$endif}
- FreeFieldBuffers;
- SetState(dsBrowse);
- {$ifdef dsdebug}
- writeln ('Delete: Browse mode set');
- {$endif}
- SetCurrentRecord(FActiverecord);
- Resync([]);
- DoAfterDelete;
- DoAfterScroll;
- end;
- end;
- Procedure TDataset.DisableControls;
- begin
- If FDisableControlsCount=0 then
- begin
- { Save current state,
- needed to detect change of state when enabling controls.
- }
- FDisableControlsState:=FState;
- FEnableControlsEvent:=deDatasetChange;
- end;
- Inc(FDisableControlsCount);
- end;
- Procedure TDataset.DoInsertAppend(DoAppend : Boolean);
- procedure DoInsert;
- Var BookBeforeInsert : TBookmarkStr;
- TempBuf : pointer;
- begin
- // need to scroll up al buffers after current one,
- // but copy current bookmark to insert buffer.
- If FRecordcount > 0 then
- BookBeforeInsert:=Bookmark;
- if FActiveRecord < FRecordCount-1 then
- begin
- TempBuf := FBuffers[FBuffercount];
- move(FBuffers[FActiveRecord],FBuffers[FActiveRecord+1],(Fbuffercount-FActiveRecord)*sizeof(FBuffers[0]));
- FBuffers[FActiveRecord]:=TempBuf;
- end
- else if FRecordcount=FBuffercount then
- shiftbuffersbackward
- else begin
- if FRecordCount>0 then
- inc(FActiveRecord);
- end;
- // Active buffer is now edit buffer. Initialize.
- InitRecord(FBuffers[FActiveRecord]);
- cursorposchanged;
- // Put bookmark in edit buffer.
- if FRecordCount=0 then
- begin
- fEOF := false;
- SetBookmarkFlag(ActiveBuffer,bfBOF)
- end
- else
- begin
- fBOF := false;
- // 29:01:05, JvdS: Why is this here?!? It can result in records with the same bookmark-data?
- // I would say that the 'internalinsert' should do this. But I don't know how Tdbf handles it
- if FRecordcount > 0 then
- SetBookMarkData(ActiveBuffer,pointer(BookBeforeInsert));
- end;
- InternalInsert;
- // update buffer count.
- If FRecordCount<FBufferCount then
- Inc(FRecordCount);
- end;
- begin
- If Not CanModify then
- DatabaseError(SDatasetReadOnly,Self);
- CheckBrowseMode;
- DoBeforeInsert;
- DoBeforeScroll;
- If Not DoAppend then
- begin
- {$ifdef dsdebug}
- Writeln ('going to insert mode');
- {$endif}
- DoInsert;
- end
- else
- begin
- {$ifdef dsdebug}
- Writeln ('going to append mode');
- {$endif}
- ClearBuffers;
- InternalLast;
- GetPriorRecords;
- if FRecordCount>0 then
- FActiveRecord:=FRecordCount-1;
- DoInsert;
- SetBookmarkFlag(ActiveBuffer,bfEOF);
- FBOF :=False;
- FEOF := true;
- end;
- SetState(dsInsert);
- try
- DoOnNewRecord;
- except
- SetCurrentRecord(FActiverecord);
- resync([]);
- raise;
- end;
- // mark as not modified.
- FModified:=False;
- // Final events.
- DataEvent(deDatasetChange,0);
- DoAfterInsert;
- DoAfterScroll;
- {$ifdef dsdebug}
- Writeln ('Done with append');
- {$endif}
- end;
- Procedure TDataset.Edit;
- begin
- If Not CanModify then
- DatabaseError(SDatasetReadOnly,Self);
- If State in [dsedit,dsinsert] then exit;
- If FRecordCount = 0 then
- begin
- Append;
- Exit;
- end;
- CheckBrowseMode;
- DoBeforeEdit;
- If Not TryDoing(@InternalEdit,OnEditError) then
- exit;
- SetState(dsedit);
- DataEvent(deRecordChange,0);
- DoAfterEdit;
- end;
- Procedure TDataset.EnableControls;
- begin
- If FDisableControlsCount>0 then
- begin
- Dec(FDisableControlsCount);
- If FDisableControlsCount=0 then
- begin
- // State changed since disablecontrols ?
- If FDisableControlsState<>FState then
- DataEvent(deUpdateState,0);
- If (FDisableControlsState<>dsInactive) and (FState<>dsInactive) then
- DataEvent(FEnableControlsEvent,0);
- end;
- end;
- end;
- Function TDataset.FieldByName(const FieldName: string): TField;
- begin
- Result:=FindField(FieldName);
- If Result=Nil then
- DatabaseErrorFmt(SFieldNotFound,[FieldName],Self);
- end;
- Function TDataset.FindField(const FieldName: string): TField;
- begin
- Result:=FFieldList.FindField(FieldName);
- end;
- Function TDataset.FindFirst: Boolean;
- begin
- //!! To be implemented
- end;
- Function TDataset.FindLast: Boolean;
- begin
- //!! To be implemented
- end;
- Function TDataset.FindNext: Boolean;
- begin
- //!! To be implemented
- end;
- Function TDataset.FindPrior: Boolean;
- begin
- //!! To be implemented
- end;
- Procedure TDataset.First;
- begin
- CheckBrowseMode;
- DoBeforeScroll;
- ClearBuffers;
- try
- InternalFirst;
- GetNextRecords;
- finally
- FBOF:=True;
- DataEvent(deDatasetChange,0);
- DoAfterScroll;
- end;
- end;
- Procedure TDataset.FreeBookmark(ABookmark: TBookmark);
- begin
- FreeMem(ABookMark,FBookMarkSize);
- end;
- Function TDataset.GetBookmark: TBookmark;
- begin
- if BookmarkAvailable then
- begin
- GetMem (Result,FBookMarkSize);
- GetBookMarkdata(ActiveBuffer,Result);
- end
- else
- Result:=Nil;
- end;
- Function TDataset.GetCurrentRecord(Buffer: PChar): Boolean;
- begin
- Result:=False;
- end;
- Procedure TDataset.GetFieldList(List: TList; const FieldNames: string);
- Function NextName(Var S : String) : String;
- Var
- P : integer;
- begin
- P:=Pos(';',S);
- If (P=0) then
- P:=Length(S)+1;
- Result:=Copy(S,1,P-1);
- system.Delete(S,1,P);
- end;
- var
- F: TField;
- Names,N : String;
- begin
- Names:=FieldNames;
- N:=Nextname(Names);
- while (N<>'') do
- begin
- F:=FieldByName(N);
- If Assigned(List) then
- List.Add(F);
- N:=NextName(Names);
- end;
- end;
- Procedure TDataset.GetFieldNames(List: TStrings);
- begin
- FFieldList.GetFieldNames(List);
- end;
- Procedure TDataset.GotoBookmark(ABookmark: TBookmark);
- begin
- If Assigned(ABookMark) then
- begin
- CheckBrowseMode;
- DoBeforeScroll;
- InternalGotoBookMark(ABookMark);
- Resync([rmExact,rmCenter]);
- DoAfterScroll;
- end;
- end;
- Procedure TDataset.Insert;
- begin
- DoInsertAppend(False);
- end;
- Procedure TDataset.InsertRecord(const Values: array of const);
- begin
- //!! To be implemented
- end;
- Function TDataset.IsEmpty: Boolean;
- begin
- Result:=(Bof and Eof);
- end;
- Function TDataset.IsLinkedTo(DataSource: TDataSource): Boolean;
- begin
- //!! Not tested, I never used nested DS
- if (DataSource = nil) or (DataSource.Dataset = nil) then begin
- Result := False
- end else if DataSource.Dataset = Self then begin
- Result := True;
- end else begin
- Result := DataSource.Dataset.IsLinkedTo(DataSource.Dataset.DataSource);
- end;
- //!! DataSetField not implemented
- end;
- Function TDataset.IsSequenced: Boolean;
- begin
- Result := True;
- end;
- Procedure TDataset.Last;
- begin
- CheckBrowseMode;
- DoBeforeScroll;
- ClearBuffers;
- try
- InternalLast;
- GetPriorRecords;
- if FRecordCount>0 then
- FActiveRecord:=FRecordCount-1
- finally
- FEOF:=true;
- DataEvent(deDataSetChange, 0);
- DoAfterScroll;
- end;
- end;
- Function TDataset.MoveBy(Distance: Longint): Longint;
- Var
- TheResult: Integer;
- Function Scrollforward : Integer;
- begin
- Result:=0;
- {$ifdef dsdebug}
- Writeln('Scrolling forward :',Distance);
- Writeln('Active buffer : ',FActiveRecord);
- Writeln('RecordCount : ',FRecordCount);
- WriteLn('BufferCount : ',FBufferCount);
- {$endif}
- FBOF:=False;
- While (Distance>0) and not FEOF do
- begin
- If FActiveRecord<FRecordCount-1 then
- begin
- Inc(FActiveRecord);
- Dec(Distance);
- Inc(TheResult); //Inc(Result);
- end
- else
- begin
- {$ifdef dsdebug}
- Writeln('Moveby : need next record');
- {$endif}
- If GetNextRecord then
- begin
- Dec(Distance);
- Dec(Result);
- Inc(TheResult); //Inc(Result);
- end
- else
- FEOF:=true;
- end;
- end
- end;
- Function ScrollBackward : Integer;
- begin
- if FIsUniDirectional then DatabaseError(SUniDirectional);
- Result:=0;
- {$ifdef dsdebug}
- Writeln('Scrolling backward:',Abs(Distance));
- Writeln('Active buffer : ',FActiveRecord);
- Writeln('RecordCunt : ',FRecordCount);
- WriteLn('BufferCount : ',FBufferCount);
- {$endif}
- FEOF:=False;
- While (Distance<0) and not FBOF do
- begin
- If FActiveRecord>0 then
- begin
- Dec(FActiveRecord);
- Inc(Distance);
- Dec(TheResult); //Dec(Result);
- end
- else
- begin
- {$ifdef dsdebug}
- Writeln('Moveby : need next record');
- {$endif}
- If GetPriorRecord then
- begin
- Inc(Distance);
- Inc(Result);
- Dec(TheResult); //Dec(Result);
- end
- else
- FBOF:=true;
- end;
- end
- end;
- Var
- Scrolled : Integer;
- begin
- CheckBrowseMode;
- Result:=0; TheResult:=0;
- If ((Distance>0) and FEOF) or
- ((Distance<0) and FBOF) then
- exit;
- DoBeforeScroll;
- Try
- Scrolled := 0;
- If Distance>0 then
- Scrolled:=ScrollForward
- else
- Scrolled:=ScrollBackward;
- finally
- {$ifdef dsdebug}
- WriteLn('ActiveRecord=', FActiveRecord,' FEOF=',FEOF,' FBOF=',FBOF);
- {$Endif}
- // If FRecordCount<>PrevRecordCount then
- if Scrolled = 0 then
- DataEvent(deDatasetChange,0)
- else
- DataEvent(deDatasetScroll,Scrolled);
- DoAfterScroll;
- Result:=TheResult;
- end;
- end;
- Procedure TDataset.Next;
- begin
- MoveBy(1);
- end;
- Procedure TDataset.Open;
- begin
- Active:=True;
- end;
- Procedure TDataset.Post;
- Procedure Checkrequired;
- Var I : longint;
- begin
- For I:=0 to FFieldList.Count-1 do
- With FFieldList[i] do
- // Required fields that are NOT autoinc !! Autoinc cannot be set !!
- if Required and not ReadOnly and
- (FieldKind=fkData) and Not (DataType=ftAutoInc) then
- DatabaseErrorFmt(SNeedField,[DisplayName],Self);
- end;
- begin
- if State in [dsEdit,dsInsert] then
- begin
- DataEvent(deUpdateRecord,0);
- DataEvent(deCheckBrowseMode,0);
- {$ifdef dsdebug}
- writeln ('Post: checking required fields');
- {$endif}
- CheckRequired;
- DoBeforePost;
- If Not TryDoing(@InternalPost,OnPostError) then exit;
- cursorposchanged;
- {$ifdef dsdebug}
- writeln ('Post: Internalpost succeeded');
- {$endif}
- FreeFieldBuffers;
- // First set the state to dsBrowse, then the Resync, to prevent the calling of
- // the deDatasetChange event, while the state is still 'editable', while the db isn't
- SetState(dsBrowse);
- Resync([]);
- {$ifdef dsdebug}
- writeln ('Post: Browse mode set');
- {$endif}
- DoAfterPost;
- end;
- end;
- Procedure TDataset.Prior;
- begin
- MoveBy(-1);
- end;
- Procedure TDataset.Refresh;
- begin
- CheckbrowseMode;
- UpdateCursorPos;
- InternalRefresh;
- SetCurrentRecord(FActiverecord);
- Resync([]);
- end;
- Procedure TDataset.RegisterDataSource(ADatasource : TDataSource);
- begin
- FDatasources.Add(ADataSource);
- RecalcBufListSize;
- end;
- Procedure TDataset.Resync(Mode: TResyncMode);
- var i,count : integer;
- begin
- // See if we can find the requested record.
- {$ifdef dsdebug}
- Writeln ('Resync called');
- {$endif}
- // place the cursor of the underlying dataset to the active record
- // SetCurrentRecord(FActiverecord);
- // Now look if the data on the current cursor of the underlying dataset is still available
- If GetRecord(Fbuffers[0],gmcurrent,False)<>grOk Then
- // If that fails and rmExact is set, then raise an exception
- If rmExact in Mode then
- DatabaseError(SNoSuchRecord,Self)
- // else, if rmexact is not set, try to fetch the next or prior record in the underlying dataset
- else if (GetRecord(Fbuffers[0],gmnext,True)<>grOk) and
- (GetRecord(Fbuffers[0],gmprior,True)<>grOk) then
- begin
- {$ifdef dsdebug}
- Writeln ('Resync: fuzzy resync');
- {$endif}
- // nothing found, invalidate buffer and bail out.
- ClearBuffers;
- DataEvent(deDatasetChange,0);
- exit;
- end;
- FCurrentRecord := 0;
- FEOF := false;
- FBOF := false;
- // If we've arrived here, FBuffer[0] is the current record
- If (rmCenter in Mode) then
- count := (FRecordCount div 2)
- else
- count := FActiveRecord;
- i := 0;
- FRecordcount := 1;
- FActiveRecord := 0;
- // Fill the buffers before the active record
- while (i < count) and GetPriorRecord do
- inc(i);
- FActiveRecord := i;
- // Fill the rest of the buffer
- getnextrecords;
- // If the buffer is not full yet, try to fetch some more prior records
- if FRecordcount < FBuffercount then inc(FActiverecord,getpriorrecords);
- // That's all folks!
- DataEvent(deDatasetChange,0);
- end;
- Procedure TDataset.SetFields(const Values: array of const);
- Var I : longint;
- begin
- For I:=0 to high(Values) do
- Fields[I].AssignValue(Values[I]);
- end;
- Function TDataset.Translate(Src, Dest: PChar; ToOem: Boolean): Integer;
- begin
- //!! To be implemented
- end;
- Function Tdataset.TryDoing (P : TDataOperation; Ev : TDatasetErrorEvent) : Boolean;
- Var Retry : TDataAction;
- begin
- {$ifdef dsdebug}
- Writeln ('Trying to do');
- If P=Nil then writeln ('Procedure to call is nil !!!');
- {$endif dsdebug}
- Result:=True;
- Retry:=daRetry;
- while Retry=daRetry do
- Try
- {$ifdef dsdebug}
- Writeln ('Trying : updatecursorpos');
- {$endif dsdebug}
- UpdateCursorPos;
- {$ifdef dsdebug}
- Writeln ('Trying to do it');
- {$endif dsdebug}
- P;
- exit;
- except
- On E : EDatabaseError do
- begin
- retry:=daFail;
- If Assigned(Ev) then
- Ev(Self,E,Retry);
- Case Retry of
- daFail : Raise;
- daAbort : Result:=False;
- end;
- end;
- else
- Raise;
- end;
- {$ifdef dsdebug}
- Writeln ('Exit Trying to do');
- {$endif dsdebug}
- end;
- Procedure TDataset.UpdateCursorPos;
- begin
- If FRecordCount>0 then
- SetCurrentRecord(FactiveRecord);
- end;
- Procedure TDataset.UpdateRecord;
- begin
- if not (State in dsEditModes) then
- DatabaseError(SNotInEditState, Self);
- DataEvent(deUpdateRecord, 0);
- end;
- Function TDataSet.UpdateStatus: TUpdateStatus;
- begin
- Result:=usUnmodified;
- end;
- Procedure TDataset.RemoveField (Field : TField);
- begin
- //!! To be implemented
- end;
- Function TDataset.Getfieldcount : Longint;
- begin
- Result:=FFieldList.Count;
- end;
- Procedure TDataset.ShiftBuffersBackward;
- var TempBuf : pointer;
- begin
- TempBuf := FBuffers[0];
- move(FBuffers[1],FBuffers[0],(fbuffercount)*sizeof(FBuffers[0]));
- FBuffers[buffercount]:=TempBuf;
- end;
- Procedure TDataset.ShiftBuffersForward;
- var TempBuf : pointer;
- begin
- TempBuf := FBuffers[FBufferCount];
- move(FBuffers[0],FBuffers[1],(fbuffercount)*sizeof(FBuffers[0]));
- FBuffers[0]:=TempBuf;
- end;
- function TDataset.GetFieldValues(Fieldname : string) : string;
- begin
- result := findfield(Fieldname).asstring;
- end;
- procedure TDataset.SetFieldValues(Fieldname : string;value : string);
- begin
- findfield(Fieldname).asstring := value;
- end;
- Function TDataset.Locate(const keyfields: string; const keyvalues: Variant; options: TLocateOptions) : boolean;
- begin
- if fIsUnidirectional then
- DataBaseError(SUniDirectional);
- Result := False;
- end;
- Function TDataset.Lookup(const KeyFields: string; const KeyValues: Variant; const ResultFields: string): Variant;
- begin
- Result := False;
- end;
-
- Procedure TDataset.UnRegisterDataSource(ADatasource : TDatasource);
- begin
- FDataSources.Remove(ADataSource);
- end;
- {
- $Log: dataset.inc,v $
- Revision 1.36 2005/04/13 22:08:16 joost
- - fixed mem-leak in TDataset.SetBufListSize
- Revision 1.35 2005/04/10 22:18:43 joost
- Patch from Alexandrov Alexandru
- - implemented TDataset.BindFields
- - master-detail relation implemented
- - improved variant-support for fields
- - implemented TField.Assign and TField.AssignValue
- Revision 1.34 2005/04/10 18:26:27 joost
- - implemented TDataset.Locate
- Revision 1.33 2005/03/29 10:07:34 michael
- + fix for activerecord, bof false after append.
- Revision 1.32 2005/02/14 17:13:12 peter
- * truncate log
- Revision 1.31 2005/02/07 11:19:27 joost
- - Fixed insertion at buffer-limit
- - Added TDataset.InternalInsert
- - The deDatasetScrollEvent was not always raised
- - Changed resync-order in AppendRecord
- Revision 1.30 2005/01/12 10:27:57 michael
- * Patch from Joost Van der Sluis:
- - implemented ControlsDisabled
- }
|