BorlandTalk.com Forum Index BorlandTalk.com
Borland discussion newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

delphi 7 clearing the params of client data sets

 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi Databases (Multi-Tier)
View previous topic :: View next topic  
Author Message
user@domain.invalid
Guest





PostPosted: Thu Mar 03, 2005 8:45 pm    Post subject: delphi 7 clearing the params of client data sets Reply with quote



I have a client dataset with a parameter :
cdsOne : TClientDataSet => Param1 => paramtype = ptInput, field type ftInteger.

In the appserver, I have a TIbQuery with the same param, and a data set provider.

Back in the client, I have a method :

RequeryTheCds(aParam : Integer) ;
begin
with cdsOne do
begin
Active := False ;
Params.ParamByName('Param1').AsInteger := aParam ;
Active := True ;
end ;
end ;

If I compile this code with delphi 6 it works ok all the time.
If I compile this code with delphi 7 it only works when the parameter
passed into the function ReQueryTheCds(aParam) is different from the one
passed immediately before : ie, if I try to query twice for the same
parameter, the second time the parameter gets converted to a null.

I've followed the code in the client :
In dbclient.pas, to the method
TCustomClientDataSet.OpenCursor. this method calls
function PackageParams(...) : OleVariant ;
Inside PackageParams, when it works with the params as TParams[i],
the value is ok. Once it is assigned to the Result I lose track.
Result is a Var Array of Variant. I do not know how to look inside
it. Tried watches and evaluate/modify, but can't see how to do it.



In the server, I hooked to the before open of the query, to
check the value of the input parameter.
The first time it works ok( ie, shows 457 )
The second time I open the cds in the client( with the same parameter of 457 ),
the input parameter shows a value of 0.

Everything works ok if I keep changing the value of the parameter for the client
dataset.
One way to make it work is :


RequeryTheCds(aParam : Integer) ;
begin
with cdsOne do
begin
// Added code to make it work
if Params.ParamByName('Param1').AsInteger = aParam then
begin
Active := False ;
Params.ParamByName('Param1').AsInteger := -34546;
Active := True ;
end ;
// end of added code

Active := False ;
Params.ParamByName('Param1').AsInteger := aParam ;
Active := True ;
end ;
end ;

As you can see, it is not a solution to be happy with.

Does anybody know of the reason for this problem ?
I've tried changing midas.dll to a previous version( the one shipped with delphi 6 ),
but it still didn't work. The only way to make it work properly is compiling with
delphi 6.

TIA


Back to top
user@domain.invalid
Guest





PostPosted: Thu Mar 03, 2005 9:48 pm    Post subject: Re: delphi 7 clearing the params of client data sets Reply with quote



Dan Palley wrote:
<snip>
Quote:
user (AT) domain (DOT) invalid> wrote in message
news:4227775d (AT) newsgroups (DOT) borland.com...

function TFixedClientDataSet.DoGetRecords(Count: Integer; out RecsOut:
Integer;
Options: Integer; const CommandText: WideString; Params: OleVariant):
OleVariant;
var
OwnerData: OleVariant;
begin
DoBeforeGetRecords(OwnerData);
Result := AppServer.AS_GetRecords(ProviderName, Count, RecsOut, Options,
CommandText, Params, OwnerData);
// Comment out the following line to fix params being cleared
// UnPackParams(Params, Self.Params);
DoAfterGetRecords(OwnerData);
end;

Dan



Thanks for your help, Dan.

I tried doing what you did, but rather than creating my own client dataset I
commented out the call to UnPackParams from the TCustomClientDataSet class
(in dbClient.pas ). It does not seem to work.
You said your problem was different. I believe that mine might be happening
on or before the call to AppServer.AS_GetRecords. Unless the problem is when
unpacking params in the prior call to get records. I'm really lost here.

Any further ideas will be greatly appreciated,

TIA

Back to top
user@domain.invalid
Guest





PostPosted: Thu Mar 03, 2005 11:07 pm    Post subject: Re: delphi 7 clearing the params of client data sets Reply with quote



This issue (Bug) appears to be the same as QC #8128 - the problem is this appears to be fixed in
Delphi 2005. we are using Delphi 7.

[email]user (AT) domain (DOT) inva[/email]lid wrote:
Quote:
Dan Palley wrote:
snip

[email]user (AT) domain (DOT) inva[/email]lid> wrote in message
news:4227775d (AT) newsgroups (DOT) borland.com...

function TFixedClientDataSet.DoGetRecords(Count: Integer; out RecsOut:
Integer;
Options: Integer; const CommandText: WideString; Params: OleVariant):
OleVariant;
var
OwnerData: OleVariant;
begin
DoBeforeGetRecords(OwnerData);
Result := AppServer.AS_GetRecords(ProviderName, Count, RecsOut,
Options,
CommandText, Params, OwnerData);
// Comment out the following line to fix params being cleared
// UnPackParams(Params, Self.Params);
DoAfterGetRecords(OwnerData);
end;

Dan




Thanks for your help, Dan.

I tried doing what you did, but rather than creating my own client
dataset I
commented out the call to UnPackParams from the TCustomClientDataSet class
(in dbClient.pas ). It does not seem to work.
You said your problem was different. I believe that mine might be
happening
on or before the call to AppServer.AS_GetRecords. Unless the problem is
when
unpacking params in the prior call to get records. I'm really lost here.

Any further ideas will be greatly appreciated,

TIA

Back to top
Kostas Terzides
Guest





PostPosted: Thu Mar 03, 2005 11:15 pm    Post subject: Re: delphi 7 clearing the params of client data sets Reply with quote

I am sure that there is some kind of internal bug (in midas.dll
probably) that doesn't allow OleVariants that are arrays of Variants to
behave well. Your case is consistent with others posted here and from my
personal experience when I tried to use DataRequest/ OnDataRequest
having as parameter a OleVariant array of variants. I know that the
safer way to commnuicate OleVariants between a client and server
application is VarArray of VarBytes (it is said in Delphi Help), but in
case of PackageParams they must have forgotten it. Here I am going to
try to give a workaround that worked for me adjusted for your case. It
will not be trivial though and I have no easy way of testing it. Please
reply as to whether it solved your problem.Do the following:


1)Download CodeCentral number:19613

2)Add VariantStream.pas to DbClient.pas uses clause

3)Add in DBClient.pas these two procedures:


procedure VarToVarByte(var OV:OleVariant);
var
VarStream: TVariantStream;
DataOut: TMemoryStream;
P: Pointer;
S:LongString;
begin
S:= '';
VarStream := TVariantStream.Create;
DataOut := TMemoryStream.Create;
try
VarStream.WriteVariant(OV, DataOut);
SetLength(S, DataOut.Size);
P := DataOut.Memory;
Move(P^,S[1],Length(S));
finally
DataOut.Free;
VarStream.Free;
end;
OV:=StringToVariantArray(S);
end;


procedure VarFromVarByte(var OV:OleVariant);
var
VarStream: TVariantStream;
DataOut: TMemoryStream;
P: Pointer;
Flags: TVarFlags;
S:String;
begin
S:=VariantArrayToString(OV);
if Length(S) > 0 then
begin
VarStream := TVariantStream.Create;
DataOut := TMemoryStream.Create;
try
DataOut.SetSize(Length(S));
P := DataOut.Memory;
Move(S[1],P^,DataOut.Size);
OV := VarStream.ReadVariant(Flags, DataOut);
finally
DataOut.Free;
VarStream.Free;
end;
end
else
OV := Null;
end;




4)Change the following DBClient functions as follows:


function PackageParams(Params: TParams; Types: TParamTypes =
AllParamTypes): OleVariant;
var
I, Idx, Count: Integer;
begin
Result := NULL;
Count := 0;
for I := 0 to Params.Count - 1 do
if Params[I].ParamType in Types then Inc(Count);
if Count > 0 then
begin
Idx := 0;
Result := VarArrayCreate([0, Count - 1], varVariant);
for I := 0 to Params.Count - 1 do
with Params[I] do
if ParamType in Types then
begin
if VarIsCustom(Value) then
Result[Idx] := VarArrayOf([Name, VarToStr(Value),
Ord(DataType), Ord(ParamType),
Size, Precision, NumericScale])
else
Result[Idx] := VarArrayOf([Name, Value, Ord(DataType),
Ord(ParamType),
Size, Precision, NumericScale]);
Inc(Idx);
end;
VarToVarByte(result);// Added by KT
end;
end;



procedure UnpackParams(const Source: OleVariant; Dest: TParams);
var
TempParams: TParams;
HighBound, i: Integer;
begin
VarFromVarByte(Source);// Added by KT
if not VarIsNull(Source) and VarIsArray(Source) and
VarIsArray(Source[0]) then
begin
TempParams := TParams.Create;
try
for i := 0 to VarArrayHighBound(Source, 1) do
begin
HighBound := VarArrayHighBound(Source[i], 1);
with TParam(TempParams.Add) do
begin
Name := Source[i][0];
if HighBound > 1 then
DataType := TFieldType(Source[i][2]);
if HighBound > 2 then
ParamType := TParamType(Source[i][3]);
if HighBound > 3 then
Size := Source[i][4];
if HighBound > 4 then
Precision := Source[i][5];
if HighBound > 5 then
NumericScale := Source[i][6];
Value := Source[i][1]; // Value must be set last
end;
end;
Dest.Assign(TempParams);
finally
TempParams.Free;
end;
end;
end;
Back to top
Kostas Terzides
Guest





PostPosted: Thu Mar 03, 2005 11:19 pm    Post subject: Re: delphi 7 clearing the params of client data sets Reply with quote

If it is a bug in midas.dll try downloading 2005 version of file found
on http://www.distribucon.com. I' ve downloaded it a few days ago and
used it in my application and there doesn't seem to be any kind of
conflict. I prefer to stick to my safer approach though of converting
variants to arrays of VarByte
Back to top
Dan Palley
Guest





PostPosted: Thu Mar 03, 2005 11:36 pm    Post subject: Re: delphi 7 clearing the params of client data sets Reply with quote

You said the problem occurs the 2nd time you try to run the query, which is
exactly what my problem was.

Quote:
if I try to query twice for the same parameter, the second time the
parameter gets converted to a null.


What's happening is the params on the CDS are being updated with the params
coming back from the server (via the unpackparams call), so the params are
present the first time you call CDS.Open, but they're gone for subsequent
attempts. This change in D7 and beyond appears to be the result of changes
that were made in the IBX component to make it work better with Datasnap.

I would try my original suggestion and create a tclientdataset descendant
instead of modifying the original dbclient unit. It's possible your change
did not get compiled into your app.

If that still doesn't work, perhaps you can upload a small sample app that
demonstrates the problem.

Dan

<user (AT) domain (DOT) invalid> wrote

Quote:
Dan Palley wrote:
snip
[email]user (AT) domain (DOT) inva[/email]lid> wrote in message
news:4227775d (AT) newsgroups (DOT) borland.com...

function TFixedClientDataSet.DoGetRecords(Count: Integer; out RecsOut:
Integer;
Options: Integer; const CommandText: WideString; Params: OleVariant):
OleVariant;
var
OwnerData: OleVariant;
begin
DoBeforeGetRecords(OwnerData);
Result := AppServer.AS_GetRecords(ProviderName, Count, RecsOut,
Options,
CommandText, Params, OwnerData);
// Comment out the following line to fix params being cleared
// UnPackParams(Params, Self.Params);
DoAfterGetRecords(OwnerData);
end;

Dan

Thanks for your help, Dan.

I tried doing what you did, but rather than creating my own client dataset
I
commented out the call to UnPackParams from the TCustomClientDataSet class
(in dbClient.pas ). It does not seem to work.
You said your problem was different. I believe that mine might be
happening
on or before the call to AppServer.AS_GetRecords. Unless the problem is
when
unpacking params in the prior call to get records. I'm really lost here.



Back to top
user@domain.invalid
Guest





PostPosted: Fri Mar 04, 2005 12:27 am    Post subject: Solved : Re: delphi 7 clearing the params of client data set Reply with quote

Thanks very much to everyone for their help.
The problem was solved by applying Borland's
Public beta: Delphi 7.1 Update - Database supplemental.

It brings updates to dbclient.pas, dbctrls.pas, and provider.pas, also
midas.dll, dsnap70.bpl, and vcldb70.bpl.

Once again, thanks everyone for your help.
Back to top
Craig Stuntz [TeamB]
Guest





PostPosted: Fri Mar 04, 2005 1:13 pm    Post subject: Re: delphi 7 clearing the params of client data sets Reply with quote

Dan Palley wrote:

Quote:
I ran into the same problem after moving from D6 to D9. I've entered
a QC entry for it (#10773) although my original problem was slightly
different.

If you can update this report I'll open it.

--
Craig Stuntz [TeamB] . Vertex Systems Corp. . Columbus, OH
Delphi/InterBase Weblog : http://blogs.teamb.com/craigstuntz
Please read and follow Borland's rules for the user of their
news server: http://info.borland.com/newsgroups/guide.html

Back to top
Display posts from previous:   
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi Databases (Multi-Tier) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.