1

My Delphi application using PostgreSQL database (with UniDac components). Data are stored in UTF8 in database. To read international characters, I use this handler:

procedure TdmMain.OnGetText(Sender: TField; var Text: String;
  DisplayText: Boolean);
begin
  Text := Utf8decode (Sender.AsString);
end;

But, how possible to store data, back to DB? I created another handler, OnSetText, with Sender.AsString := Utf8Encode (Text); but it is not working.

How it is possible to do that? Thanks.

Arioch 'The
  • 15,799
  • 35
  • 62
Andrey
  • 2,659
  • 4
  • 29
  • 54
  • what is delphi version ? database tag is redundant but delphi version tag is much more informative here. Put it please. – Arioch 'The Jul 22 '13 at 12:06
  • 1
    such a handler is totally broken design. databse access components should take care of that. You should find answer to 3 questions: how t osignal pgsql that given table was created using utf-8? how to signal (via connection string or options) to pgsql client lib that you aplicatio nwant utf-8 as connection encoding ? how to signal UniDAc lib that the connection would use UTF-8 – Arioch 'The Jul 22 '13 at 12:08
  • xe2 is unicode-aware. So - three questions. like http://www.connectionstrings.com/postgresql/ – Arioch 'The Jul 22 '13 at 12:10
  • what about searchign for "unicode" in manuals http://www.devart.com/unidac/docs/pgsqlprov_article.htm ? Footer [7] http://www.devart.com/unidac/docs/ ? http://forums.devart.com/viewforum.php?f=28 – Arioch 'The Jul 22 '13 at 12:12
  • I made everything like manual. UseUnicode=TRUE; Charset=UTF8. I should do something else? – Andrey Jul 22 '13 at 12:20
  • there is no info in your question what and how you done except for `Utf8decode` - make question has all the relevant information. Also since charSet is not mentioned in documentation, i'd avoid specifying it unless absolutely necessary – Arioch 'The Jul 22 '13 at 12:29
  • and i think you should at least try to ask ur question in official forum linked above – Arioch 'The Jul 22 '13 at 12:30
  • also give a try to http://docwiki.embarcadero.com/Libraries/XE4/en/Data.DB.TField.AsWideString http://docwiki.embarcadero.com/Libraries/XE4/en/Data.DB.TWideStringField and ftWideString http://docwiki.embarcadero.com/Libraries/XE4/en/Data.DB.TFieldType – Arioch 'The Jul 22 '13 at 12:33

2 Answers2

2

When reading and editing data, you don't need to recode utf-8 text by yourself (for example, in the OnGetText event). It is enough to set the UseUnicode option in the TUniConnection.SpecificOptions property to True, for example, as follows:

UniConnection1.SpecificOptions.Values['PostgreSQL.UseUnicode'] := 'True';

and UniDAC will do this automatically.

http://www.devart.com/unidac/docs/pgsqlprov_article.htm

Devart
  • 119,203
  • 23
  • 166
  • 186
  • Can redundant specifications of generic `Charset=UTF8` change semantic of `ftAnsiString` and `TField.AsString` then ? or was topicstarter's fault in specifying general `UseUnicode` instead of server-specific `PostgreSQL.UseUnicode` ? – Arioch 'The Jul 22 '13 at 14:56
1

Although this questions is old, and I agree that translation should occur automatically, sometimes it simply does not work. My workaround is to define a TStringField descendant, in a package:

unit MyField;
.
.
.
Type 

TMyStringField = class(TStringField)
  protected
    procedure SetAsString(const Value: string); override;
    Function GetAsString : String; Override;
  end;

  function TMyStringField.GetAsString: String;
  begin
    Result := inherited Utf8ToAnsi (GetAsString)
  end;

  procedure TMyStringField.SetAsString(const Value: string);
  begin
    inherited SetAsString(AnsiToUtf8(Value))
  end;

Don't forget to register this field:

Procedure Register;
begin
  RegisterFields([TMyStringField]);
end;

From help:

Call RegisterFields to allow custom descendants of TField to appear in the field type drop down of the new field dialog box.

The FieldClasses parameter is an array of TField descendants.In C++, the FieldClasses_Size is the index of the last class in the array (one less than the number of class types).

This approach has the disadvantage that you must add the fields by hand, or replace TStringField to TMyStringField

alvaroc
  • 433
  • 5
  • 14