123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611 |
- {
- $Id$
- 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;
- Procedure TDataset.ActivateBuffers;
- begin
- FBOF:=False;
- FEOF:=False;
- FRecordCount:=1;
- FActiveRecord:=0;
- end;
- Procedure TDataset.UpdateFieldDefs;
- begin
- //!! To be implemented
- end;
- Procedure TDataset.BindFields(Binding: Boolean);
- Var I : longint;
- 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;
- }
- 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
- //!! To be implemented
- 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: Longint);
- Var
- i : longint;
- begin
- // Do some bookkeeping;
- case Event of
- deFieldChange :
- begin
- if TField(Info).FieldKind in [fkData,fkInternalCalc] then
- SetModified(True);
- 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;
- // Distribute event to datasets;
- 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
- FBufferCount:=0;
- FDefaultFields:=FieldCount=0;
- DoBeforeOpen;
- Try
- {$ifdef dsdebug}
- Writeln ('Calling internal open');
- {$endif}
- InternalOpen;
- FBOF:=True;
- {$ifdef dsdebug}
- Writeln ('Setting state to browse');
- {$endif}
- SetState(dsBrowse);
- {$ifdef dsdebug}
- Writeln ('Setting buffer size');
- {$endif}
- SetBufListSize(DefaultBufferCount);
- {$ifdef dsdebug}
- Writeln ('Getting next records');
- {$endif}
- GetNextRecords;
- DoAfterOpen;
- DoAfterScroll;
- except
- SetState(dsInactive);
- DoInternalClose;
- raise;
- end;
- end;
- Function TDataset.RequiredBuffers : longint;
- {
- If later some datasource requires more buffers (grids etc)
- then it should be taken into account here...
- }
- begin
- Result:=0;
- end;
- Procedure TDataset.DoInternalClose;
- begin
- FreeFieldBuffers;
- ClearBuffers;
- 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:=True;
- end;
- Procedure TDataset.GetChildren(Proc: TGetChildProc; Root: TComponent);
- begin
- //!! To be implemented
- 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;
- ftSmallint: Result := TSmallIntField;
- ftInteger: Result := TLongintField;
- ftWord: Result := TWordField;
- ftBoolean: Result := TBooleanField;
- ftFloat: Result := TFloatField;
- 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;
- end;
- end;
- Function TDataset.GetIsIndexField(Field: TField): Boolean;
- begin
- //!! To be implemented
- end;
- Function TDataset.GetNextRecord: Boolean;
- Var Shifted : Boolean;
- begin
- {$ifdef dsdebug}
- Writeln ('Getting next record. Internal RecordCount : ',FRecordCount);
- {$endif}
- Shifted:=FRecordCount=FBufferCount;
- If Shifted then
- begin
- ShiftBuffers(0,1);
- Dec(FRecordCount);
- end;
- {$ifdef dsdebug}
- Writeln ('Getting data into buffer : ',FRecordCount);
- {$endif}
- Result:=GetRecord(FBuffers[FRecordCount],gmNext,True)=grOK;
- If Result then
- begin
- If FRecordCount=0 then
- ActivateBuffers
- else
- If FRecordCount<FBufferCount then
- Inc(FRecordCount);
- FCurrentRecord:=FRecordCount;
- end
- else
- begin
- if shifted then
- begin
- ShiftBuffers(0,-1);
- inc(FRecordCount);
- end;
- CursorPosChanged;
- end;
- {$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;
- Var Shifted : boolean;
- begin
- {$ifdef dsdebug}
- Writeln ('Getting previous record');
- {$endif}
- Shifted:=FRecordCount>0;
- If Shifted Then
- begin
- SetCurrentRecord(0);
- ShiftBuffers(0,-1);
- end;
- Result:=GetRecord(FBuffers[0],gmPrior,True)=grOK;
- If Result then
- begin
- If FRecordCount=0 then
- ActivateBuffers
- else
- begin
- If FrecordCount<FBufferCount then
- Inc(FRecordCount);
- end;
- FCurrentRecord:=0;
- end
- else
- begin
- If Shifted then
- begin
- ShiftBuffers(0,1);
- end;
- CursorPosChanged;
- end;
- 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
- //!! To be implemented
- end;
- Function TDataset.GetRecordCount: Longint;
- begin
- //!! To be implemented
- 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.Loaded;
- 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;
- Procedure TDataset.RestoreState(const Value: TDataSetState);
- begin
- //!! To be implemented
- end;
- Procedure TDataset.SetActive (Value : Boolean);
- begin
- If Value<>Factive then
- If Value then
- DoInternalOpen
- else
- DoInternalClose;
- FActive:=Value;
- end;
- Procedure TDataset.SetBookmarkStr(const Value: TBookmarkStr);
- begin
- GotoBookMark(Pointer(Value))
- end;
- Procedure TDataset.SetBufListSize(Value: Longint);
- Var I : longint;
- begin
- If Value=FBufferCount Then exit;
- I:=RequiredBuffers; // Save 1 call.
- If Value<I Then
- Value:=I;
- 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-FBufferCount)*SizeOf(PChar));
- {$endif}
- FillChar(FBuffers[FBufferCount],(Value+1-FBufferCount)*SizeOF(Pchar),#0);
- {$ifdef dsdebug}
- Writeln ('Filled memory :');
- {$endif}
- Try
- {$ifdef dsdebug}
- Writeln ('Assigning buffers :',(Value+1)*SizeOf(PChar));
- {$endif}
- For I:=FBufferCount to Value do
- FBuffers[i]:=AllocRecordBuffer;
- {$ifdef dsdebug}
- Writeln ('Assigned buffers :',(Value+1)*SizeOf(PChar));
- {$endif}
- except
- I:=FBufferCount;
- While (I<=Value) and (FBuffers[i]<>Nil) do
- begin
- FreeRecordBuffer(FBuffers[i]);
- Inc(i);
- end;
- raise;
- end;
- end
- else
- begin
- For I:=Value+1 to FBufferCount do
- FreeRecordBuffer(FBuffers[i]);
- ReAllocMem(FBuffers,Value*SizeOf(Pchar));
- end;
- FBufferCount:=Value;
- 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
- //!! To be implemented
- end;
- Procedure TDataset.SetFiltered(Value: Boolean);
- begin
- //!! To be implemented
- end;
- Procedure TDataset.SetFound(const Value: Boolean);
- begin
- //!! To be implemented
- end;
- Procedure TDataset.SetModified(Value: Boolean);
- begin
- //!! To be implemented
- 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.SetTempState(const Value: TDataSetState): TDataSetState;
- begin
- //!! To be implemented
- end;
- Function TDataset.TempBuffer: PChar;
- begin
- //!! To be implemented
- end;
- Procedure TDataset.UpdateIndexDefs;
- begin
- //!! To be implemented
- end;
- Function TDataset.ControlsDisabled: Boolean;
- begin
- //!! To be implemented
- end;
- Function TDataset.ActiveBuffer: PChar;
- begin
- {$ifdef dsdebug}
- // Writeln ('Active buffer requested. Returning:',ActiveRecord);
- {$endif}
- Result:=FBuffers[ActiveRecord];
- end;
- Procedure TDataset.Append;
- begin
- DoInsertAppend(True);
- 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;
- SetState(dsBrowse);
- Resync([]);
- DoAfterCancel;
- end;
- end;
- Procedure TDataset.CheckBrowseMode;
- begin
- CheckActive;
- DataEvent(deCheckBrowseMode,0);
- If State In [dsedit,dsinsert] then
- begin
- UpdateRecord;
- If Modified then
- Post
- else
- Cancel;
- 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
- //!! To be implemented
- 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);
- Var Buffer : PChar;
- BookBeforeInsert : TBookmarkStr;
- begin
- If Not CanModify then
- DatabaseError(SDatasetReadOnly,Self);
- CheckBrowseMode;
- DoBeforeInsert;
- DoBeforeScroll;
- If Not DoAppend then
- begin
- {$ifdef dsdebug}
- Writeln ('going to insert mode');
- {$endif}
- // need to scroll up al buffers after current one,
- // but copy current bookmark to insert buffer.
- BookBeforeInsert:=Bookmark;
- ShiftBuffers(1,FActiveRecord);
- // Active buffer is now edit buffer. Initialize.
- InitRecord(ActiveBuffer);
- // Put bookmark in edit buffer.
- if FRecordCount=0 then
- SetBookmarkFlag(ActiveBuffer,bfBOF)
- else
- SetBookMarkData(ActiveBuffer,Pointer(BookBeforeInsert));
- // update buffer count.
- If FRecordCount<FBufferCount then
- Inc(FRecordCount);
- end
- else
- // Tricky, need to get last record and scroll down.
- begin
- {$ifdef dsdebug}
- Writeln ('going to append mode');
- {$endif}
- Buffer:=FBuffers[0];
- InitRecord(Buffer);
- // just mark buffer as last. GetPreviousrecords will do an internallast
- // Because of this...
- SetBookMarkFlag(Buffer,bfEOF);
- FRecordCount:=1;
- {$ifdef dsdebug}
- Writeln ('getting prior records');
- {$endif}
- GetPriorRecords;
- // update active record.
- FactiveRecord:=FRecordCount-1;
- end;
- SetState(dsInsert);
- try
- DoOnNewRecord;
- except
- UpdateCursorPos;
- 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
- Insert;
- 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);
- begin
- 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.IsSequenced: Boolean;
- begin
- //!! To be implemented
- end;
- Procedure TDataset.Last;
- begin
- CheckBrowseMode;
- DoBeforeScroll;
- ClearBuffers;
- try
- InternalLast;
- GetPriorRecords;
- FActiveRecord:=FRecordCount-1;
- finally
- FEOF:=true;
- DataEvent(deDataSetChange, 0);
- DoAfterScroll;
- end;
- end;
- Function TDataset.MoveBy(Distance: Longint): Longint;
- Function Scrollforward : Integer;
- begin
- Result:=0;
- {$ifdef dsdebug}
- Writeln('Scrolling forward :',Distance);
- Writeln('Active buffer : ',FActiveRecord);
- Writeln('RecordCunt : ',FRecordCount);
- {$endif}
- While (Distance>0) and not FEOF do
- begin
- If FActiveRecord<FRecordCount-1 then
- begin
- Inc(FActiveRecord);
- Dec(Distance);
- Inc(Result);
- end
- else
- begin
- {$ifdef dsdebug}
- Writeln('Moveby : need next record');
- {$endif}
- If GetNextRecord then
- begin
- Dec(Distance);
- Inc(result);
- end
- else
- FEOF:=true;
- end;
- end
- end;
- Function ScrollBackward : Integer;
- begin
- Result:=0;
- {$ifdef dsdebug}
- Writeln('Scrolling backward:',Abs(Distance));
- Writeln('Active buffer : ',FActiveRecord);
- Writeln('RecordCunt : ',FRecordCount);
- {$endif}
- While (Distance<0) and not FBOF do
- begin
- If FActiveRecord>0 then
- begin
- Dec(FActiveRecord);
- Inc(Distance);
- Dec(Result);
- end
- else
- begin
- {$ifdef dsdebug}
- Writeln('Moveby : need next record');
- {$endif}
- If GetPriorRecord then
- begin
- Inc(Distance);
- Dec(Result);
- end
- else
- FBOF:=true;
- end;
- end
- end;
- Var
- PrevRecordCount : Integer;
- Scrolled : Integer;
- begin
- CheckBrowseMode;
- Result:=0;
- PrevRecordCount:=0;
- DoBeforeScroll;
- If ((Distance>0) and FEOF) or
- ((Distance<0) and FBOF) then
- exit;
- Try
- If Distance>0 then
- Scrolled:=ScrollForward
- else
- Scrolled:=ScrollBackward;
- finally
- If FRecordCount<>PrevRecordCount then
- DataEvent(deDatasetChange,0)
- else
- DataEvent(deDatasetScroll,Scrolled);
- DoAfterScroll;
- 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(deCheckBrowseMode,0);
- {$ifdef dsdebug}
- writeln ('Post: checking required fields');
- {$endif}
- CheckRequired;
- DoBeforePost;
- If Not TryDoing(@InternalPost,OnPostError) then exit;
- {$ifdef dsdebug}
- writeln ('Post: Internalpost succeeded');
- {$endif}
- FreeFieldBuffers;
- {$ifdef dsdebug}
- writeln ('Post: Freeing field buffers');
- {$endif}
- SetState(dsBrowse);
- {$ifdef dsdebug}
- writeln ('Post: Browse mode set');
- {$endif}
- Resync([]);
- DoAfterPost;
- end;
- end;
- Procedure TDataset.Prior;
- begin
- MoveBy(-1);
- end;
- Procedure TDataset.Refresh;
- begin
- CheckbrowseMode;
- UpdateCursorPos;
- InternalRefresh;
- Resync([]);
- end;
- procedure TDataSet.RecalcBufListSize;
- var
- i, j, MaxValue: Integer;
- DataLink: TDataLink;
- begin
- MaxValue := 0;
- 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 > MaxValue then
- MaxValue := DataLink.BufferCount;
- end;
- SetBufListSize(MaxValue);
- end;
- Procedure TDataset.RegisterDataSource(ADatasource : TDataSource);
- begin
- FDatasources.Add(ADataSource);
- RecalcBufListSize;
- end;
- Procedure TDataset.Resync(Mode: TResyncMode);
- Var Count,ShiftCount : Longint;
- begin
- // See if we can find the requested record.
- If rmExact in Mode then
- begin
- { throw an exception if not found.
- Normally the descendant should do this if DoCheck is true. }
- If GetRecord(Fbuffers[FRecordCount-1],gmcurrent,True)<>grOk Then
- DatabaseError(SNoSuchRecord,Self);
- end
- else
- { Can we find a record in the neighbourhood ?
- Use Shortcut evaluation for this, or we'll have some funny results. }
- If (GetRecord(Fbuffers[FRecordCount-1],gmcurrent,True)<>grOk) and
- (GetRecord(Fbuffers[FRecordCount-1],gmprior,True)<>grOk) and
- (GetRecord(Fbuffers[FRecordCount-1],gmprior,True)<>grOk) then
- begin
- // nothing found, invalidate buffer and bail out.
- ClearBuffers;
- DataEvent(deDatasetChange,0);
- Exit;
- end;
- If (rmCenter in Mode) then
- ShiftCount:=FbufferCount div 2
- else
- // keep current position.
- ShiftCount:=FActiveRecord;
- // Reposition on 0
- ShiftBuffers(0,FRecordCount-1);
- ActivateBuffers;
- try
- Count:=0;
- {$ifdef dsdebug}
- Writeln ('Getting previous',ShiftCount,' records');
- {$endif}
- While (Count<ShiftCount) and GetPriorRecord do Inc(Count);
- FActiveRecord:=Count;
- // fill rest of buffers, adjust ActiveBuffer.
- SetCurrentRecord(FRecordCount-1);
- GetNextRecords;
- Inc(FActiveRecord,GetPriorRecords);
- finally
- // Notify Everyone
- DataEvent(deDatasetChange,0);
- end;
- end;
- Procedure TDataset.SetFields(const Values: array of const);
- Var I : longint;
- begin
- For I:=0 to high(Values) do
- Case Values[I].vtype of
- vtInteger : FieldByNumber(i).AsLongInt:=Values[I].VInteger;
- // needs Completion..
- end;
- end;
- Procedure TDataset.Translate(Src, Dest: PChar; ToOem: Boolean);
- 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;
- Procedure TDataset.RemoveField (Field : TField);
- begin
- //!! To be implemented
- end;
- Function TDataset.Getfieldcount : Longint;
- begin
- Result:=FFieldList.Count;
- end;
- Procedure TDataset.ShiftBuffers (Offset, Distance : longint);
- Var Temp : Pointer;
- MoveSize : Longint;
- Procedure ShiftBuffersUp;
- begin
- {$ifdef DSDEBUG}
- writeln ('Shifting buffers up from ',OffSet,' with distance :',Distance);
- writeln ('Moving ',(FBufferCount-Distance), ' Buffers at ',Distance);
- {$endif}
- Move(FBuffers[Offset],Temp^,MoveSize);
- Move(FBuffers[Offset+Distance],FBuffers[Offset],(FBufferCount-Distance-Offset)*SizeOf(Pchar));
- Move(Temp^,FBuffers[FBufferCount-Distance-Offset],MoveSize);
- end;
- Procedure ShiftBuffersDown;
- begin
- // Distance is NEGATIVE
- {$ifdef DSDEBUG}
- writeln ('Shifting buffers down with distance :',Abs(Distance));
- writeln ('Moving ',Movesize div 4,' Buffers at ',FBufferCount+Distance);
- {$endif}
- Move(FBuffers[FbufferCount+Distance],Temp^ ,MoveSize);
- Move(FBuffers[0],FBuffers[Abs(Distance)],(FBufferCount+Distance)*SizeOf(Pchar));
- Move(Temp^ ,FBuffers[0],MoveSize);
- end;
- begin
- If Abs(Distance)>=BufferCount then Exit;
- try
- MoveSize:=SizeOf(Pchar)*Abs(Distance);
- GetMem(Temp,MoveSize);
- If Distance<0 Then
- ShiftBuffersDown
- else If Distance>0 then
- ShiftBuffersUp;
- Finally
- FreeMem(temp);
- end;
- end;
- Procedure TDataset.UnRegisterDataSource(ADatasource : TDatasource);
- begin
- FDataSources.Remove(ADataSource);
- end;
- {
- $Log$
- Revision 1.6 2002-09-07 15:15:22 peter
- * old logs removed and tabs fixed
- }
|