Unicode support?

Freature requests from users for ZeosLib's DBOs

Moderators: gto, cipto_kh, EgonHugeist, mdaems

Post Reply
borut
Fresh Boarder
Fresh Boarder
Posts: 1
Joined: 20.11.2005, 12:03

Unicode support?

Post by borut »

ZeosLib supports many DBMS (Firebird, mySQL,...), many development platforms (D7, Lazarus,...) and is free. This is why it is interesting to me in a long term. However, if one wishes to develop a truly global product, one needs a Unicode support. I am used to using the Tnt-Components (TntWare Delphi Unicode Controls) and also UIB-Components (Unified Interbase Controls). My primary DBMS of interest is Firebird.

Is there any Unicode support in ZeosLib at this time? Are there any plans or a road map towards the Unicode support within ZeosLib?

Thanks. Borut
sancho1980
Fresh Boarder
Fresh Boarder
Posts: 3
Joined: 10.07.2006, 08:51

Post by sancho1980 »

hi
i've also had this problem for quite a while with quite every set of open source access controls...
the fact is, you CAN store and read unicode using zeos, only it's a bit tricky:

you can do something like this:

field.asString := UTF8Encode(WideStringVariable);

WideStringVariable := UTF8Decode(field.asString);

if you want to use tnt data access controls to automatically do these conversions for you, you have to change 3 lines in the source code (in TntDB.pas) of the tnt controls as follows:

> function GetWideText(Field: TField): WideString;
> var
> WideField: IWideStringField;
> begin
> if Field.GetInterface(IWideStringField, WideField) then
> Result := WideField.WideText
> else if (Field is TWideStringField{TNT-ALLOW TWideStringField})
> and (not Assigned(Field.OnGetText)) then
> Result := GetAsWideString(Field)
> else
> //Result := Field.Text; original code
> Result := UTF8Decode(Field.Text);
> end;
>
> procedure SetWideText(Field: TField; const Value: WideString);
> var
> WideField: IWideStringField;
> begin
> if Field.GetInterface(IWideStringField, WideField) then
> WideField.WideText := Value
> else if (Field is TWideStringField{TNT-ALLOW TWideStringField})
> and (not Assigned(Field.OnSetText)) then
> SetAsWideString(Field, Value)
> else
> //Field.Text := Value original code
> Field.Text := UTF8Encode(Value);
>
> procedure SetWideText(Field: TField; const Value: WideString);
> var
> WideField: IWideStringField;
> begin
> if Field.GetInterface(IWideStringField, WideField) then
> WideField.WideText := Value
> else if (Field is TWideStringField{TNT-ALLOW TWideStringField})
> and (not Assigned(Field.OnSetText)) then
> SetAsWideString(Field, Value)
> else
> //Field.Text := Value original code
> Field.Text := UTF8Encode(Value);

then reinstall tnt and all should work as expected,

regards,

martin
arnix
Fresh Boarder
Fresh Boarder
Posts: 4
Joined: 20.06.2008, 10:55

Post by arnix »

This is working well with edit boxes and grids but not with memos. Here is my modified code.

Code: Select all

function GetWideDisplayText(Field: TField): WideString;
var
  WideField: IWideStringField;
begin
  if Field.GetInterface(IWideStringField, WideField) then
    Result := WideField.WideDisplayText
  else if (Field is TWideStringField{TNT-ALLOW TWideStringField})
  and (not Assigned(Field.OnGetText)) then
    Result := GetAsWideString(Field)
  else
    //Result := Field.DisplayText{TNT-ALLOW DisplayText};
    Result := UTF8Decode(Field.DisplayText); // arnix
end;

function GetWideText(Field: TField): WideString;
var
  WideField: IWideStringField;
begin
  if Field.GetInterface(IWideStringField, WideField) then
    Result := WideField.WideText
  else if (Field is TWideStringField{TNT-ALLOW TWideStringField})
  and (not Assigned(Field.OnGetText)) then
    Result := GetAsWideString(Field)
  else
    //Result := Field.Text;
    Result := UTF8Decode(Field.Text); // arnix
end;

procedure SetWideText(Field: TField; const Value: WideString);
var
  WideField: IWideStringField;
begin
  if Field.GetInterface(IWideStringField, WideField) then
    WideField.WideText := Value
  else if (Field is TWideStringField{TNT-ALLOW TWideStringField})
  and (not Assigned(Field.OnSetText)) then
    SetAsWideString(Field, Value)
  else
    //Field.Text := Value
    Field.Text := UTF8Encode(Value); // arnix
end;
Do you know how to fix it? In fact, the "GetWideDisplayText" function is not being called with memo fields, so we must modify other function as well which is doing the work for memo fields. But which function(s)? Thank you.
arnix
Fresh Boarder
Fresh Boarder
Posts: 4
Joined: 20.06.2008, 10:55

Post by arnix »

OK, solved it.

Code: Select all

function GetAsWideString(Field: TField): WideString;
{$IFDEF COMPILER_10_UP}
begin
  if (Field.ClassType = TMemoField{TNT-ALLOW TMemoField}) then
//    Result := VarToWideStr(Field.AsVariant) { works for NexusDB BLOB Wide }
    Result := UTF8Decode(Field.AsWideString) // arnix
  else
    Result := Field.AsWideString;
end;
{$ELSE}
var
  WideField: IWideStringField;
begin
  if Field.GetInterface(IWideStringField, WideField) then
    Result := WideField.AsWideString
  else if (Field is TWideStringField{TNT-ALLOW TWideStringField}) then
  begin
    if Field.IsNull then
      // This fixes a bug in TWideStringField.GetAsWideString which does not handle Null at all.
      Result := ''
    else
      Result := TWideStringField{TNT-ALLOW TWideStringField}(Field).Value
  end else if (Field is TMemoField{TNT-ALLOW TMemoField}) then
//    Result := VarToWideStr(Field.AsVariant) { works for NexusDB BLOB Wide }
    Result := UTF8Decode(Field.AsWideString) // arnix
  else
    Result := Field.AsString{TNT-ALLOW AsString};
end;
{$ENDIF}

procedure SetAsWideString(Field: TField; const Value: WideString);
{$IFDEF COMPILER_10_UP}
begin
  if (Field.ClassType = TMemoField{TNT-ALLOW TMemoField}) then
    //Field.AsVariant := Value { works for NexusDB BLOB Wide }
    Field.AsVariant := UTF8Encode(Value) // arnix
  else
    Field.AsWideString := Value;
end;
{$ELSE}
var
  WideField: IWideStringField;
begin
  if Field.GetInterface(IWideStringField, WideField) then
    WideField.AsWideString := Value
  else if (Field is TWideStringField{TNT-ALLOW TWideStringField}) then
    TWideStringField{TNT-ALLOW TWideStringField}(Field).Value := Value
  else if (Field is TMemoField{TNT-ALLOW TMemoField}) then
    //Field.AsVariant := Value { works for NexusDB BLOB Wide }
    Field.AsVariant := UTF8Encode(Value) // arnix
  else
    Field.AsString{TNT-ALLOW AsString} := Value;
end;
{$ENDIF}
User avatar
EgonHugeist
Zeos Project Manager
Zeos Project Manager
Posts: 1936
Joined: 31.03.2011, 22:38

Post by EgonHugeist »

I made a patch in the testing-egonhugeist branch. To have Unicode support with D7-D2007 uncomment the {.DEFINE WITH_UTF8_CONTROLS} and use UTF8 as ClientCodePage-Property of TZConnection.

Now Zeos assings all string fields as TStringField and returns utf8 strings. So you don't need to encode the Strings from WideStrings.

If you switch PreprepareSQL := True; you don't have to change your custom and need to use AnsiToUtf8 for direct statements.

But you need UTF8 controls like TNT or several SourceForge-Projects who can display the data right.

Best regards
Best regards, Michael

You want to help? http://zeoslib.sourceforge.net/viewtopic.php?f=4&t=3671
You found a (possible) bug? Use the new bugtracker dude! http://sourceforge.net/p/zeoslib/tickets/

Image
Post Reply