TZStringField = class (TWideStringField)
private
buf : PByte;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
class procedure CheckTypeSize(Value: Integer); override;
function GetAsString: string; override;
function GetAsVariant: Variant; override;
function GetValue(var Value: string): Boolean;
procedure SetAsString(const Value: string); override;
property Value: UnicodeString read GetAsWideString write SetAsWideString;
end;
{ TZStringField }
class procedure TZStringField.CheckTypeSize(Value: Integer);
begin
if (Value < 0) then
DatabaseError(SInvalidFieldSize);
end;
constructor TZStringField.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
end;
destructor TZStringField.Destroy;
begin
if Assigned(Buf) then
FreeMem(Buf);
inherited;
end;
function TZStringField.GetAsString: string;
begin
if not GetValue(Result) then
Result := '';
end;
function TZStringField.GetAsVariant: Variant;
var
S: string;
begin
if GetValue(S) then
Result := S
else
Result := Null;
end;
function TZStringField.GetValue(var Value: string): Boolean;
begin
if not Assigned(Buf) then
GetMem(Buf, (Size + 1) * SizeOf(PChar));
Result := GetData(Buf);
if Result then
Value := String(PChar(Buf))
end;
procedure TZStringField.SetAsString(const Value: string);
begin
SetData(Pointer(Value), False);
end;
2) override function TZAbstractRODataset.GetFieldClass
{$IFDEF ZEOS_FULL_UNICODE}
function TZAbstractRODataset.GetFieldClass(FieldType: TFieldType): TFieldClass;
begin
if (FieldType in [ftString,ftFixedChar,ftWideString]) then
result := TZStringField
else
result := inherited ;
end;
{$ENDIF}
TZSQLiteResultSet = class(TZAbstractResultSet)
...
...
public
{$IFDEF ZEOS_FULL_UNICODE}
function GetUnicodeString(ColumnIndex: Integer): WideString; override;
{$ENDIF}
{$IFDEF ZEOS_FULL_UNICODE}
function TZSQLiteResultSet.GetUnicodeString(ColumnIndex: Integer): WideString;
var
Buffer: PAnsiChar;
begin
Buffer := GetPChar(ColumnIndex);
if Buffer <> nil then
Result := UTF8ToUnicodeString(StrPas(Buffer))
else
Result := '';
end;
{$ENDIF}
Do I understand well this is a D2009 shortcoming?
Or does D2009 provide a new field_type for unicode-strings?
In that case we shouldn't add our own field type but make sure zeoslib decides to use the D2009 replacement for the (Anis) TStringfield. Isn't it better to use TWideStringField? That one uses a Unicodestring as Value?
1) Use one common TZStringField for Unicode and Ansi strings (like IBX)
or
2) User can select what he want , if he has data with unicode he should inform ZEOS about it , and now zeos use internal UNICODE , if we want ANSI zeos internal use ANSI
In my opinion first way is better, we stop thinking about difference STRING / UNICODE STRING, but i can make patch with both
In my opinion internal ZEOS should use Unocode to storage internal data
(in d2009) because it is default string format in delphi 2009
Index: ZDatasetUtils.pas
===================================================================
--- ZDatasetUtils.pas (revision 535)
+++ ZDatasetUtils.pas (working copy)
@@ -301,7 +301,7 @@
stFloat, stDouble, stBigDecimal:
Result := ftFloat;
stString:
- Result := ftString;
+ Result := {$IFDEF ZEOS_FULL_UNICODE}ftWideString{$ELSE}ftString{$ENDIF};
stBytes:
Result := ftBytes;
stDate:
But I need you to check what extra changes are needed to get this working. (Test suite shows me only changing this causes more errors on string fields)
Could you please have a look at it?
In a later stadium we can talk about adding TZXXXFieldTypes. For the moment Zeoslib only contained TDataset descendants. I'm not sure how adding TField descendants would affect the use of zeoslib datasets in general.
Result := {$IFDEF DELPHI12_UP}ftWideString{$ELSE}ftString{$ENDIF};
, which no longer offers the choice to the user.
I have code with persistent fields, which now gives an error (ftWideString <> ftString). Shouldn't we be building something that can make the user choose which one to default to.
Does this currently mean I have to replace all my TStringField declarations as TWideStringField??
I don't think so. But I have no real Delphi 2009 experience. So just test and prove I'm right or wrong. As far as I understand the new situations is comparable to the default D2009 field type choice. But if you have an existing application with TStringFields it seems to me like the behaviour would still be the same as before. I think the code you mention above only applies when defining new fields using the IDE or at runtime when opening the query.