SmartQuery as Provider for ClientDataset can't write CLOB with UNICODE content in DLL

Discussion of open issues, suggestions and bugs regarding ODAC (Oracle Data Access Components) for Delphi, C++Builder, Lazarus (and FPC)
Post Reply
s_grosskr
Posts: 26
Joined: Fri 31 Aug 2007 13:14

SmartQuery as Provider for ClientDataset can't write CLOB with UNICODE content in DLL

Post by s_grosskr » Wed 25 Nov 2015 11:23

Hi dear ODAC Support Team,

I have another problem with a ODAC-Dataset as a provider dataset for a ClientDataset, when updating a CLOB field inside a DLL.
I'm referring to my further problem "SmartQuery as Provider for ClientDataset can't read CLOB with UNICODE content" (http://forums.devart.com/viewtopic.php?f=5&t=32133 ).
Here I had problems reading Unicode-Data from a CLOB field.
I modified my sample app from topic 32133 to illustrate the new problem and sent it to you (@alex_p).

Summary:
When I update a CLOB-Field within a DLL with a ClientDataset, the update writes the byte representation of the UTF-16-string into the field.

Prerequisites and description:
- We are working on an ORACLE database with unicode character set (AL32UTF8).
- In the OracleSession I set

Code: Select all

OraSession.Options.UseUnicode         := True;
OraSession.Options.UnicodeEnvironment := True;
- I add a DBType-Rule to force ODAC to handle CLOB-Fields correctly (see your solution for topic 32133 http://forums.devart.com/viewtopic.php?f=5&t=32133):

Code: Select all

OraSession.DataTypeMap.AddDBTypeRule( OraClob, ftWideMemo);
- I have a ClientDataset, bound to a TLocalConnection.
- The ClientDataset has a Provider, which has a TSmartQuery as provider dataset.
- I have a DLL, where I have a TLocalConnection, ClientDataset, Provider and TSmartQuery as provider dataset.
- Important: I use AssignConnect as the method proposed by you to share Connections between exe and DLL. We use this approach
for years now and never had any problems with it.
see https://www.devart.com/odac/docs/?devar ... ssion).htm

When I update a CLOB Field with the ClientDataset within the DLL, the update writes the byte representation of the string into the field.
When I do the same update within the exe, everything is fine (Test with Button "Update in Exe").
Updating the field in the DLL with a straight ODAC-Dataset is ok too (Test with Button "Update in DLL (ODAC)")

One further note: when I don't use AssignConnect, but Assign server/username/password to the DLL-Connection (in fact I open a second
connection), then things work as expected.
But this has the coast of an additional ORACLE-Session, which is not suitable for us and for our customers.
It looks like AssignConnect eliminates the effect of the AddDBTypeRule( OraClob, ftWideMemo) command.

I work with Delphi XE2 Update 4, ODAC Version is (now) 9.6.19

Thanks in advance for your help.
With regards
Stefan "ostijo" Grosskreutz

s_grosskr
Posts: 26
Joined: Fri 31 Aug 2007 13:14

Re: SmartQuery as Provider for ClientDataset can't write CLOB with UNICODE content in DLL

Post by s_grosskr » Wed 25 Nov 2015 13:10

Hi again,

I did some research in your source code ;-) and I think this could be a solution for my problem.
Maybe you can consider this when you examine this case.
This statement (copying FDataMap to FIConnection) is the same as in TCustomDAConnection.DoConnect.

With regards
Stefan "ostijo" Grosskreutz

Code: Select all

procedure TCustomDAConnection.AssignConnect(Source: TCustomDAConnection);
begin
  if Source <> Self then begin
   ...
      // line 21 in routine TCustomDAConnection.AssignConnect
      // FIX for problem "SmartQuery as Provider for ClientDataset can't write CLOB with UNICODE content in DLL"
      // http://forums.devart.com/viewtopic.php?f=5&t=32824
      if (FIConnection <> nil) then begin
        FDataTypeMap.WriteTo(FIConnection.DataTypeMap);
      end;
      // END FIX
... 

end;

AlexP
Devart Team
Posts: 5530
Joined: Tue 10 Aug 2010 11:35

Re: SmartQuery as Provider for ClientDataset can't write CLOB with UNICODE content in DLL

Post by AlexP » Thu 26 Nov 2015 10:27

Hello,

Thank you, but it is not quite a correct fix. The following is a correct one:

Code: Select all

if (FIConnection <> nil) and (Source.FIConnection <> nil) then begin
  DataTypeMap.Assign(Source.DataTypeMap);
  ...

s_grosskr
Posts: 26
Joined: Fri 31 Aug 2007 13:14

Re: SmartQuery as Provider for ClientDataset can't write CLOB with UNICODE content in DLL

Post by s_grosskr » Fri 27 Nov 2015 08:32

Hi Alex,

have you tried my testproject? Did you see the error too, so can you confirm at least, that there is a problem?

I tried your vesion of the fix and get an exception (EConvertError, SAssignError) inside the DLL:
TDAConnectionMapRules can not be assigned to TDAConnectionMapRules at this line:

Code: Select all

procedure TCustomDAConnection.AssignConnect(Source: TCustomDAConnection);
...
  DataTypeMap.Assign(Source.DataTypeMap);
Don't you get this error as well, when you call the DLL with your fix included?
I hardly can believe, that this code runs on your side (inside the DLL!!).
Or are there differences between the Delphi Versions? Remember that I use Delphi XE2 with Update 4.

Nevertheless I think, this would not solve the problem. You would transfer the DataTypeMap from the "exe"-Session to the DLL-Session. This is not necessary, as I do this myself when I create TMyConnection.
The point is, that TOraSession.DataTypeMap ( FDataTypeMap ) is not transferred to the "inner" object FIConnection ( FIConnection.DataTypeMap ).
This is done in TCustomDAConnection.DoConnect, but is missing in CustomDAConnection.AssignConnect.

Maybe you can have another look at his, please, as your suggested solution does not run on my side.

With regards
Stefan "ostijo" Grosskreutz

AlexP
Devart Team
Posts: 5530
Joined: Tue 10 Aug 2010 11:35

Re: SmartQuery as Provider for ClientDataset can't write CLOB with UNICODE content in DLL

Post by AlexP » Thu 03 Dec 2015 13:11

Thank you for the information. We have fixed this issue. The fix will be included to the next ODAC version.

Post Reply