[fpc-devel]Some questions about tdataset and a small patch

Michael.VanCanneyt at Wisa.be Michael.VanCanneyt at Wisa.be
Sun Aug 1 15:03:14 CEST 2004

On Sun, 1 Aug 2004, Joost van der Sluis wrote:

> Hi,
> I want to discuss something before i make all sort of changes...
> Now TDataset uses a buffer of default 10 records. If you go to the 11th
> record, the first record is removed from memory. If you go to the first
> record, all buffers are cleared, and then they are read again from the
> first record. All this is done by tdataset.
> This works good for tdbf but it gives some problems with SQL-based
> descendants, especially those for DB-servers that don't support
> bidirectional cursors. (like Firebird)
> If you fetch records from a table using a sql-query, you'll get all the
> records, beginning with the first one, then the second one etcetera. But
> you can't go back. If you've just fetched the 1000 record, and you need
> record 999, you have to start all over again, beginning with record number
> one.
> This gives some problems if you're buffer is holding the records
> 1000-1010. If you scroll back from record 999 to 1 the use of bandwith
> will be huge.
> The solution is to hold all records into memory once they are
> fetched. At first sight you will say that that cost an huge amount of
> memory, but i doesn't. Because if you used the SQL server right, you only
> ask for the records you need by using a 'where' statement.
> I see three solutions:
> 1: Make the tdataset descendents so that they do the fetch from the first
> record if you want the prior record. Which is the worst solution, I hope
> you all agree with that. (It's the current solution, though. Only it don't
> work)

The TDataset descendent should handle it optimally. IBX fetches and stores
results 'as you go', using an incremental scheme. If you go back, it just
returns in the data already in memory. 

> 2: Leave the creation and maintenance of the buffer to the tdataset
> descendants, in stead of tdataset itself. So that every tdataset
> descendent can use it's own buffer-system. (This solution is the one i was
> trying, and it can be done. Some small changes to tdbf are needed,
> though. And all other descendents have to been looked at too.)

This is not possible, as grids needs to handle more than just the current
buffer. It needs a consistent interface. The current method ensures this.
There is also compatibility to be considered.

> 3: Add a property to TDataset, which changes the behaviour of the buffers,
> so that they are 'infinitive'. All fetched records are kept in memory. The
> descendents that need this can set this property in their
> create-functions. Delphi has something like this, if you set the
> buffercount to -1.

Delphi does this only for TClientDataset, never for an ordinary dataset.
TClientDataset is something we should have, but then we need lots more
functionality as well.

> I think i'm going to try to implement option three. But what do you all
> think about this issue?

I think the best thing is a hybrid approach between TDataset and what IBX
does. I suggest you make a TDataset descendent which does all the buffer
handling as you wish (Call it e.g. TBufDataset).

To do this, some methods/fields of TDataset will need changing:
methods/fields should be made protected/virtual etc.
We can discuss these changes in TDataset methods as needed, I'll be glad to

This approach has 2 advantages:
- People who want to use the new TBufDataset functionality can do so by
  descending from this component instead of TDataset.
- At the same time, the old TDataset methods should be kept for compatbility 
  with existing components...

> Further i've fixed a bug that made it impossible to show an integer field
> in a tdbedit.
> fields.inc: tlongintfield.gettext now uses getvalue
> so that the typecasting is used correctly.
> diff is attached.

Applied, thank you.


More information about the fpc-devel mailing list