#434 Hieroglyphs with TDBSynEdit with Oracle Unicode CLOB

open
nobody
Unicode (53)
5
2014-08-16
2012-02-29
Uwe Schuster
No

When using TDBSynEdit with an Oracle Unicode Session and a CLOB field then you get "spaces" between the chars when loading the content and get hieroglyphs stored.

A XE2 sample project (requires Oracle and Devart ODAC) and a patch for SynDBEdit.pas can be found in the attached ZIP file.

Steps (requires Oracle and I used Devart ODAC):
- create a new Oracle table including a CLOB field and insert some text like "This is a test" into the CLOB field with a simple INSERT statement in your favorite query tool
- create a new VCL app
- add TDBSynEdit, TOraSession, TOraQuery and so on that the TDBSynEdit shows the CLOB field
- start the app

expected: TDBSynEdit shows "This is a test"
actual: TDBSynEdit shows "This is a test"

- close the app
- enable TOraSession.UseUnicode
- start the app

expected: TDBSynEdit shows "This is a test"
actual: TDBSynEdit shows "T h i s i s a t e s t"

- enter "Foo" into the memo
- save and refresh the record

expected: TDBSynEdit shows "Foo"
expected: TDBSynEdit shows an upside down question mark (I am using a non-Unicode DB)

The problem is that the field is accessed as stream in TCustomDBSynEdit.LoadMemo and TCustomDBSynEdit.UpdateData. The (required) encoding of the stream depends on the session mode and that is something that TDBSynEdit cannot know about. In order to fix the problem I have modified the code of both mentioned methods to handle the field type ftOraClob with AsString. The patch for this against the latest SVN is
(it is also in the attached ZIP file)

Index: SynDBEdit.pas

--- SynDBEdit.pas (revision 69)
+++ SynDBEdit.pas (working copy)
@@ -355,6 +355,14 @@
{$ENDIF}
begin
try
+{$IFDEF SYN_COMPILER_12_UP}
+ { In Unicode Delphi AsString should be used for an Oracle CLOB field, because the
+ encoding of the stream depends on the mode of the DB session }
+ if FDataLink.Field.DataType = ftOraClob then
+ Text := FDataLink.Field.AsString
+ else
+ begin
+{$ENDIF}
{$IFDEF SYN_COMPILER_3_UP}
BlobStream := FDataLink.DataSet.CreateBlobStream(FDataLink.Field, bmRead);
{$ELSE}
@@ -365,6 +373,9 @@
Lines.LoadFromStream(BlobStream{$IFDEF UNICODE}, TEncoding.Default{$ENDIF});
Lines.EndUpdate;
BlobStream.Free;
+{$IFDEF SYN_COMPILER_12_UP}
+ end;
+{$ENDIF}
Modified := False;
ClearUndo;
except
@@ -427,7 +438,9 @@
{$ENDIF}
begin
{$IFDEF SYN_COMPILER_3_UP}
- if FDataLink.Field.IsBlob then
+ { In Unicode Delphi AsString should be used for an Oracle CLOB field, because the required
+ encoding for the stream depends on the mode of the DB session }
+ if FDataLink.Field.IsBlob {$IFDEF SYN_COMPILER_12_UP}and (FDataLink.Field.DataType <> ftOraClob){$ENDIF} then
begin
BlobStream := FDataLink.DataSet.CreateBlobStream(FDataLink.Field, bmWrite);
Lines.SaveToStream(BlobStream);

Discussion

  • Uwe Schuster
    Uwe Schuster
    2012-02-29

    Patch and XE2 Sample code