Additional
dbCAP
AnyDAC
ThinDAC
NCOCI8
Topic: AD2.0.4 IB/FB Driver bug
AD2.0.4 IB/FB Driver bug
Posted: 2007/10/15 05:53
 
Hi!

I found bug in new IB/FB driver (AD 2.0.4):
It gets AV while changing the Connection property for TADTransaction
when there are another active transactions attached to that TADConnection.

  ADConnection1.Connected:=true; ADTransaction1.StartTransaction; ADTransaction2.Connection:=ADConnection1;  //AV



Also I have some issue (IB/FB related)

Currently I use FIB+ to access my FB2.0 DB.
It has TpFIBQuery component (in IBX - TIBSQL) - non TDataSet.
And this component can be used to fetch multi-row selects,
also to execute procedures, inserts, updates and so on.

IMHO. It's advantage - it uses single call and retrieve system for "selectebles"
and "executables".
In FB many "executables" can return values:
- execute procedure ....
- insert/update/merge ...
returning ...
Also EXECUTE BLOCK - which can be excuted or selected depending on it's body.
So methods Execute, Next, Eof, FieldByName are comfortable in these cases.
In AnyDAC there is an analogue of TpFIBQuery - TADCommand.
But I didn't found how to retrieve by it executed query output.
When opening "executable" query it catchs "resync error"
It wolud be nice to have functionality like TpFIBQuery.

And some sugestions:
1. The connection editor for TADConnection closes by the ENTER key.
Having ObjInspector like params editor (where ENTER simply "posts" change)
I think it would by nice that it closed by Ctrl+ENTER.
2. May be it is time to change year in AboutBox (IDE)

PS. I have made my project's branch using AnyDAC FB/IB driver (neighbouring FIB+). I use my own wrapers, so I think it would need virtualy no code change in mest cases. I hope so
Re:AD2.0.4 IB/FB Driver bug
Posted: 2007/10/17 03:57
 
Hello

It gets AV
Fixed.
It's advantage - it uses single call and retrieve system for "selectebles"
and "executables".

AnyDAC has the same functionality, just it is not presented in TADCommand. Now I made it accessible through TADcommand too. See method OpenOrExecute.
But I didn't found how to retrieve by it executed query output.
AnyDAC has different approach to fetch data from command. That is the basic idea:

 var   oTabTADDatSTable; ... // open command ADCommand1.Open; // create and define DatS table oTab := ADCommand1.Define; try   // fetch all dataset   ADCommand1.Fetch(oTabTrue);   // walk through rows   for := 0 to oTab.Rows.Count do     oTab.Rows[i].GetData('ID'); finally   oTab.Free; end;


If you will look into AnyDAC dataset internals, then you will see that they are doing similar things.
1. The connection editor ... it closed by Ctrl+ENTER
Done.
2. May be it is time to change year in AboutBox (IDE)
Done.

Regards,
Dmitry
Re:AD2.0.4 IB/FB Driver bug
Posted: 2007/10/17 04:52
 
Hi, Dmitry


AnyDAC has the same functionality, just it is not presented in TADCommand. Now I made it accessible through TADcommand too. See method OpenOrExecute.


OK. Does this mean that I can use common approach for rerieving retuned values from executed and selected queries (e.g. the executed query retuns may look like a single row select fetch).
For EXECUTE BLOCK it is hard to guess what it would look like.
Any way, I use wrappers for TAD... (also for TpFIB...), so I would like any executables results retrive system with correct CommandKind.

Thank you.
Regards.
Re:AD2.0.4 IB/FB Driver bug
Posted: 2007/10/17 05:21
 
Does this mean that I can use common approach for rerieving retuned values from executed and selected queries
Yes, you can. If there will be issues, then report them and I will fix.
Re:AD2.0.4 IB/FB Driver bug
Posted: 2007/10/19 05:27
 
Hi, Dmitry.

I have downloaded AD2.0.5

But the issue about retriving executed query returns is still not resolved.

Also TADCommand.Define needs at least one param, so the code you have
posted is not correct

  ... // create and define DatS table oTab := ADCommand1.Define; ...


(May be you have talked about TADQuery...)

So it IMHO may look like

  ... // create  oTab:=TADDatSTable.Create; // define DatS table oTab := ADCommand1.Define(oTab); ...



Anyway:
[code sql]
CREATE OR ALTER PROCEDURE PROC1
RETURNS (
TXT VARCHAR(255))
AS
begin
text = '123';
end


Trying to execute it with

  execute procedure proc1


IBExpert (it uses self modified FIB+):
------ Procedure executing results: ------
TXT = 123

FIB+ (6.45)

  pFIBQuery1.ExecQuery; ShowMessage(pFIBQuery1.FieldByName('TXT').AsString);


Shows 123

AD2.0.5

  ADCommand1.Execute; //how to get result?


if I try to fetch it:
'[AnyDAC][Comp][Clnt]-509. Command must be in active state'.
Also if I use

  ADCommand1.Open//or OpenOrExecute


Fetching gets
'[AnyDAC][Phys][IB]request synchronization error'.

So how to obtain results?

Firebird supports some other "executable" statements where user may expect results. For example
[code sql]
insert into TABLE1(ID, TXT)
values(gen_id(gen_table1_id, 1), '1111')
returning ID

and the others

I think Open would be rather strange name for executing it.
Creating TADDatSTable, fetching and destroying for geting single value
looks too complicated, doesn't it?

May be it would be better to return these values like OUT params?
Or create separate property smth like Returns: TADParams to avoid mixing
really OUT/INOUT params?

Also a little question:
I use TADMemTable and in some cases I may need to share single TADDatSTable for two TADMemTables.
It works fine using AttachTable method (only small issue while deleting row
wnen ControlsEnabled=true).
So on, I wanted to use notification to inform about changes between two holders. After having some investigation of the AnyDAC, I decided to create
descendant of TADDatSTable overriding Notification method.
But it there is small problem: in some cases AnyDAC uses ClassType instead of IS. In my case the show stopper was

  function TADDatSRow.GetTableTADDatSTable; begin   if FOwner.ClassType TADDatSTable then     Result := TADDatSTable(FOwner)   else     Result := TADDatSTable(FOwner.FOwner);   ASSERT((Result <> nil) and (Result is TADDatSTable)); end;


Is any reason of using ClassType? Making little test I discovered that ClassType is about 3 times slower than IS operator.

Thank you, I like the AnyDAC's architecture.
Regards, SSW.
Re:AD2.0.4 IB/FB Driver bug
Posted: 2007/10/20 04:20
 
Hello

About retriving results. I found issues and resolved them. Now following code samples work well:


   ADCommand1.Params.Add('TXT'ftString10ptOutput);   ADCommand1.Execute();   ShowMessage(ADCommand1.Params[0].AsString);




   oTab := ADCommand1.Define;   ADCommand1.Open;   ADCommand1.Fetch(oTabTrue);   ShowMessage(oTab.Rows[0].DumRow(True));   oTab.Free;




   if ADCommand1.OpenOrExecute then begin     oTab := ADCommand1.Define;     ADCommand1.Fetch(oTabTrue);     ShowMessage(oTab.Rows[0].DumRow(True));     oTab.Free;   end;



Command must be in active state
Open or OpenOrExecute must be called before Fetch.
request synchronization error
Fixed.
May be it would be better to return these values like OUT params?
It was implement - see first sample. Just you should add output parameters by hands. Later I will try to create output parameters inside of Execute call.
Is any reason of using ClassType? Making little test I discovered that ClassType is about 3 times slower than IS operator.
Hmm ... I had completely oposite experience in Delphi 7. ClassType = xxx is faster than IS operator. What is your Delphi version ?

Regards,
Dmitry
Re:AD2.0.4 IB/FB Driver bug
Posted: 2007/10/22 03:57
 
Hi, Dmitry


Hmm ... I had completely oposite experience in Delphi 7. ClassType = xxx is faster than IS operator. What is your Delphi version ?


Sorry, you are right and I was wrong.
My little test wasn't correct (I forgot about compiler magic when using Self keyword ).

So, as I understood it was changed beacuse of performance issues.
Any way, I can change it by myself.
(May be the only thing is to change ASSERT)

Thank you!

Regards, SSW.