12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700 |
- {
- $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
- { 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: 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;
- *)
- RecalcBufListSize;
- //SetBufferCount(DefaultBufferCount);
- 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;
- 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:=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}
- If FRecordCount>0 Then SetCurrentRecord(FRecordCount-1);
- 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 - 1;
- 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.SetBufferCount(const AValue: Longint);
- Var
- ShiftCount: Integer;
- begin
- {$ifdef dsdebug}
- Writeln('in SetBufferCount(',AValue,')');
- {$endif}
- If (FBufferCount=AValue) Then
- exit;
- If AValue<FRecordCount Then
- Begin
- If (AValue>0)And(ActiveRecord>AValue-1) Then
- begin
- // ActiveRecord Will be pointing to a deleted record
- // Move Buffers to a safe place and then adjust buffer count
- ShiftCount:=FActiveRecord - Avalue + 1;
- ShiftBuffers(0, ShiftCount);
- FActiveRecord:=AValue-1;
- End;
- FRecordCount:=AValue;
- // Current record Will be pointing to a invalid record
- // if we are not in BOF or EOF state then make current record point
- // to the last record in buffer
- If FCurrentRecord<>-1 Then
- Begin
- FCurrentRecord:=FRecordCount - 1;
- if FCurrentRecord=-1 Then
- InternalFirst;
- End;
- End;
- SetBufListSize(Avalue);
- 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-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 ',FBufferCount,' :',(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
- {$ifdef dsdebug}
- Writeln (' Freeing buffers :',FBufferCount-Value);
- {$endif}
- For I:=Value+1 to FBufferCount do
- FreeRecordBuffer(FBuffers[i]);
- ReAllocMem(FBuffers,(Value+1)*SizeOf(Pchar));
- end;
- 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
- //!! 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;
- 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
- 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
- PrevRecordCount : Integer;
- Scrolled : Integer;
- begin
- CheckBrowseMode;
- Result:=0; TheResult:=0;
- PrevRecordCount:=FRecordCount;
- DoBeforeScroll;
- If ((Distance>0) and FEOF) or
- ((Distance<0) and FBOF) then
- exit;
- Try
- If Distance>0 then
- Scrolled:=ScrollForward
- else
- Scrolled:=ScrollBackward;
- finally
- {$ifdef dsdebug}
- WriteLn('ActiveRecord=', FActiveRecord,' FEOF=',FEOF,' FBOF=',FBOF);
- {$Endif}
- If FRecordCount<>PrevRecordCount then
- DataEvent(deDatasetChange,0)
- else
- DataEvent(deDatasetScroll,Scrolled);
- DoAfterScroll;
- end;
- Result:=TheResult;
- 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
- {$ifdef dsdebug}
- Writeln('Recalculating buffer list size - check cursor');
- {$endif}
- If Not IsCursorOpen Then
- Exit;
- {$ifdef dsdebug}
- Writeln('Recalculating buffer list size');
- {$endif}
- MaxValue := 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>MaxValue then
- MaxValue:=DataLink.BufferCount;
- end;
- {$ifdef dsdebug}
- Writeln('calling Setbuffercount');
- {$endif}
- SetBufferCount(MaxValue); //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.9 2003-10-06 17:04:28 florian
- * small step towards calculated fields
- Revision 1.8 2003/05/06 12:08:52 michael
- + fixed dataset opening buffer issues
- Revision 1.7 2003/02/20 19:25:19 michael
- + Fixes from Jesus Reyes
- Revision 1.6 2002/09/07 15:15:22 peter
- * old logs removed and tabs fixed
- }
|