Page 1 of 1

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

Posted: Wed 25 Nov 2015 11:23
by s_grosskr
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

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

Posted: Wed 25 Nov 2015 13:10
by s_grosskr
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;

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

Posted: Thu 26 Nov 2015 10:27
by AlexP
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);
  ...

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

Posted: Fri 27 Nov 2015 08:32
by s_grosskr
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

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

Posted: Thu 03 Dec 2015 13:11
by AlexP
Thank you for the information. We have fixed this issue. The fix will be included to the next ODAC version.