<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head>
<body bgcolor="#ffffff" text="#000000">
<pre>Hi,
I found this it fpc-pascal mailing list archive (I do not read this mailing list, so I do not catch this discussion)
Because I think it is worth to continue, I move it into fpc-devel
><i> ... I feel the definition
</i>><i> of SetFieldData/GetFieldData without a length/size parameter
</i>><i> and strings passed as pchar is causing all kind of problems:
</i>I agree<i>
</i>><i> 1) TStringField.SetAsString copies the string to a buffer
</i>><i> with size dsMaxStringSize so that datasets that don't figure
</i>><i> out the original length of the string can simply copy the
</i>><i> full Field.TDatasize (TBufDataset, TDbf, TMemDataset,...).
</i>Yes<i>
</i>><i> TWideStringField.SetAsString didn't which caused the crash
</i>><i> when the string is shorter than Field.Size.
</i>><i> TCustomSqliteDataset uses a StrNew(PChar(Buffer)); to get the
</i>><i> length of the string but fails sometimes (see 4).
</i>><i> 2) dsMaxStringSize isn't enforced for TStringField. Defining
</i>><i> a Field.size > dsMaxStringSize causes a crash in
</i>><i> TStringField.SetAsString. I haven't raised an issue on this, yet.
</i>
Yes, it is also reported by fcl-db test suite, see: <a class="moz-txt-link-freetext" href="http://bugs.freepascal.org/view.php?id=19940">http://bugs.freepascal.org/view.php?id=19940</a>
><i> 3) some of the speed advantage of memory based datasets is
</i>><i> offset by moving full Field.Tdatasize bytes in both set and
</i>><i> get fielddata
</i>
><i> 4) pascal strings can contain #0 characters in the string.
</i>><i> When converting to pchar part of these strings is lost.
</i>><i>
</i>Very good point. See also comments in <a class="moz-txt-link-freetext" href="http://bugs.freepascal.org/view.php?id=19930">http://bugs.freepascal.org/view.php?id=19930</a>
<i>
</i>><i> What I propose is:
</i>><i> 1 to create overloaded versions of SetFieldData and
</i>><i> GetFieldData that include a length parameter, to change
</i>><i> TStringField.SetAsString and TWideStringField.SetAsWideString
</i>><i> to use these versions
</i>Or also create procedure TField.SetData(Buffer: Pointer; DataSize : integer=0);
which will do some checks like existing TField.SetData(Buffer: Pointer; NativeFormat : Boolean)
and call new FDataSet.SetFieldData(Self, Buffer, NativeFormat, DataSize);
This new TDataSet.SetFieldData will by default call existing "old" SetFieldData:
procedure TDataSet.SetFieldData(Field: TField; Buffer: Pointer; NativeFormat: Boolean; DataSize:integer);
begin
SetFieldData(Field, Buffer, NativeFormat);
end;
So backward compatibilty will be retained.
TDataSet descendants, which will want, they will override this new SetFieldData method and will take advantage of them.
(in our case TBufDataSet will be adopted )
<i>
Êand to migrate the different datasets
</i>><i> to use these new versions. This way existing (user) code
</i>><i> using SetFieldData/GetFieldData will still work (and the user
</i>><i> still being responsible for buffer overruns...) and datasets
</i>><i> can correctly save and retrieve strings while improving performance.
</i>><i> 2 change the bufdataset internal storage for ftstring and
</i>><i> ftwidestring fields to include the string length so that
</i>><i> stored strings can be retrieved in full when containing #0
</i>><i> characters and without having to copy systematically datasize
</i>><i> bytes.
</i>
Yes, so ftString will be stored like ftvarBinary, which has first two bytes length and followed by "binary string"
><i> However this will introduce an incompatible binary
</i>><i> format for TFpcBinaryDatapacketReader. Having a second
</i>><i> FpcBinaryIdent would allow for both formats to co-habitate.
</i>><i>
</i>><i> If need be the discussion can be moved to fpc-devel.
</i>Yes ;-)))<i>
</i>And another theme not related to this subjects are Autoincrement fields, which are ATM read-only for all access
(BTW see also <a class="moz-txt-link-freetext" href="http://bugs.freepascal.org/view.php?id=17624">http://bugs.freepascal.org/view.php?id=17624</a> )
Here I have idea introduce at some level (TDataSet or TBufDataSet) virtual function (for example GetNextAutoIncValue),
which will be called just after append...post (may be in InternalPost if State=dsInsert)
And descendants like TSQLQuery will be able override this method and provide their own mechanism for retrieving auto-generated values from SQL databases.
Like MySQL: select last_insert_rowid(), PostgreSQL: select lastval(), MSSQL: select @@identity, etc.
For other solution (introduce new property RefreshSQL ) read: <a class="moz-txt-link-freetext" href="http://bugs.freepascal.org/view.php?id=16076">http://bugs.freepascal.org/view.php?id=16076</a>
ATM auto-increment fields are practicaly useless.
Ofcourse this are only very raw ideas ...
TIA
-Laco.
</pre>
</body>
</html>