Page 1 of 3

AfterFetch handler being called too early / usage of NonBlocking mode / run code when loading of all records is finished

Posted: Wed 20 Jan 2016 09:50
by pcz
Hello

I got some questions about proper usage of NonBlocking query mode :roll:


1. Which event shoud I use to do things that should be done after all data is "ready" (Executing = false?)
For example calling GotoBookmark / Locate
What is the best way to wait for query to execute / fetch all data?


2. [this problem does not exist since 9.7.25 fix] Similar problem
I'd like to
- remember last active record
- refresh dataset (with NonBlocking mode)
- restore same active record as before
Should I use GotoBookmark / Locate or there is some more clever way?

What is the proper way of use GotoBookmark / Locate in NonBlocking mode?
Or are there any restrictions to follow in NonBlocking mode?



Regards
P.C.

Re: Proper use of NonBlocking query mode

Posted: Thu 21 Jan 2016 11:51
by AlexP
Hello,

You can use the FetchingAll property to check if all the records were retrieved.
For the time being, until all the records are fetched, you can't call RefreshAll. If all the records are fetched, you can use both methods to navigate to a record.

Re: Proper use of NonBlocking query mode

Posted: Fri 22 Jan 2016 08:56
by pcz
Ok
What about events?
There is no event that signalizes moment when Fetching / FetchingAll property changes?

So what should I do?...
Create a timer and check FetchingAll property periodically?... :roll:

Re: Proper use of NonBlocking query mode

Posted: Fri 22 Jan 2016 09:52
by AlexP
There is an AfterFetch event, that is triggered after another data "portion" is retrieved.

Re: Proper use of NonBlocking query mode

Posted: Fri 22 Jan 2016 11:03
by pcz
Oh...
So it's possible to write

Code: Select all

procedure TSchedulerSettingsProcess.OraQuery1AfterFetch(DataSet: TCustomDADataSet);
begin
  if not DataSet.Fetching then
    ShowMessage('Tadaaa!');
end;
and "ShowMessage" executes exactly in the moment when all of the data is ready, yes?

And I can use GotoBookmark / Locate since then? :D

Re: Proper use of NonBlocking query mode

Posted: Mon 25 Jan 2016 09:40
by AlexP
Yes, in your code, a message will be returned only after all records are retrieved.
Yes. After retrieving all rows, you will be able to use these methods.

Re: Proper use of NonBlocking query mode

Posted: Tue 26 Jan 2016 08:58
by pcz
"But wait! There is more!" :|
One more stupid problem...
I use DevExpress grid pack and I just need to recalculate all columns width after TOraQuery finishes retrieving data

Code: Select all

procedure TFormBlahBlah.OraQuery1AfterFetch(DataSet: TCustomDADataSet);
begin
  if not DataSet.Fetching then
    DoStuffWithColumns;   // this happens too early to properly do that (no idea why)
end;
So... I'm experimenting with other events... But I'm not sure if I do it right way... :roll:

Code: Select all

procedure TFormBlahBlah.OraQuery1AfterExecute(Sender: TObject; Result: Boolean);
begin
  if not DataSet.Fetching then   // do I need this line???
    DoStuffWithColumns;   // it seems to work
end;

1. Is there any big difference between AfterFetch / AfterExecute event in NonBlocking mode?
What about calling BreakExec? Does it block calling both of these events?

2. Is the execution order of AfterFetch / AfterExecute always constant?
I mean - does AfterExecute happens always after AfterFetch?

3. What is the difference between Fetching and Fetched property?
Then don't seem to be "synchronised"

Re: Proper use of NonBlocking query mode

Posted: Tue 26 Jan 2016 10:38
by AlexP
1, 2) Before the server starts to return data, the query must be executed on the server. After the query is executed, the AfterExecute event is triggered. Then we request data from the server. After data is returned, the AfterFetch event is triggered. I.e., the AfterExecute event always occurs before the AfterFetch event.

3) The Fetching property is set just on starting data fetching, and the Fetched property - only after data fetching is finished or canceled.

Re: Proper use of NonBlocking query mode

Posted: Tue 26 Jan 2016 11:58
by pcz
AfterExecute event always occurs before the AfterFetch event.
Not in my code :) (ODAC 9.6.2.1 professional / XE7 / compilation & testing @ Win XP SP3 x86)
Ok - maybe it's some random stuff - and according to You I should not to do this in such way

So... I need to know the moment that <TOraQuery>.Fetched changes to True and trigger things then
But there is no event related?

Code: Select all

procedure TFormBlahBlah.OraQuery1AfterFetch(DataSet: TCustomDADataSet);
begin
  if DataSet.Fetched then   // (not DataSet.Fetching) can be True here, but DataSet.Fetched NEVER does
    DoStuffWithColumns;   // the problem is that this line never executes
end;
Doing this in such a primitive way

Code: Select all

procedure TFormBlahBlah.OraQuery1AfterFetch(DataSet: TCustomDADataSet);
begin
  if not DataSet.Fetching then
  begin
    Timer1.Interval := 10;
    Timer1.Enabled := True;
  end;
end;

procedure TFormBlahBlah.Timer1Timer(Sender: TObject);
begin
  if OraQuery1.Fetched then
  begin
    Timer1.Enabled := False;
    DoStuffWithColumns;
  end;
end;
is absurd (but it's working)

Re: Proper usage of NonBlocking query mode / fire code when all records are fetched

Posted: Fri 29 Jan 2016 07:20
by pcz
Any idea?... :(

Re: Proper usage of NonBlocking query mode / fire code when all records are fetched

Posted: Fri 29 Jan 2016 13:05
by AlexP
The Fetched property is set after the last AfterFetch event occurrence.

Re: Proper usage of NonBlocking query mode / fire code when all records are fetched

Posted: Fri 29 Jan 2016 14:26
by pcz
The Fetched property is set after the last AfterFetch event occurrence.
Yes, but exact timing depends on some cases...:

Code: Select all

procedure TForm1.OraQuery1AfterFetch(DataSet: TCustomDADataSet);
begin
  if not DataSet.Fetching then
  begin
    ShowMessage('This line executes in Blocking & NonBlocking mode');
    ShowMessage('### LAST FETCH ###');
    GridDBTableView.ApplyBestFit;   // PROBLEM HERE - happens both in Blocking and NonBlocking mode...
  end;
  if DataSet.Fetched then
    ShowMessage('This line executes olny in Blocking mode or after calling GridDBTableView.BeginUpdate');
end;
I use DevExpress Quantum Grid with TOraQuery - and I can't figure out which of them have problem / bug

At first glance it looks for me that last OnAfterFetch happens to early to react
And there is no other event...
It would be nice to have event like "OnFetched"...? (and it would be the best solution)
It looks that detecting moment when TOraQuery finished fetching of records is hard to achieve with OnAfterFetch event
so I'm unable to use features of DevExpress grids while using NonBlocking mode :( :( :(

Re: Proper use of NonBlocking query mode

Posted: Fri 29 Jan 2016 15:01
by pcz
AlexP wrote:1, 2) Before the server starts to return data, the query must be executed on the server. After the query is executed, the AfterExecute event is triggered. Then we request data from the server. After data is returned, the AfterFetch event is triggered. I.e., the AfterExecute event always occurs before the AfterFetch event.
It's true only when TOraQuery.FetchAll = False;
When switchcing TOraQuery.FetchAll to True the order of these events is opposite

Why is the TOraDataSet.FetchAll Property affecting order of AfterExecute / AfterFetch events at all?...

Re: Proper usage of NonBlocking query mode / fire code when all records are fetched

Posted: Tue 02 Feb 2016 09:41
by pcz
Funny fact
After calling GridDBTableView.BeginUpdate and setting FetchAll to True this code starts working

Code: Select all

GridDBTableView.BeginUpdate;
OraQuery1.FetchAll := True;
OraQuery1.Open;
...
procedure TForm1.OraQuery1AfterFetch(DataSet: TCustomDADataSet);
begin
  if DataSet.Fetched then
    ShowMessage('This line executes only after GridDBTableView.BeginUpdate...');
end;

Re: Proper usage of NonBlocking query mode / fire code when all records are fetched

Posted: Tue 02 Feb 2016 11:09
by pcz
Looks like there is some friction between TOraQuery and default behaviour of DevExpress TcxGridDBTableView...

Code: Select all

GridDBTableView.BeginUpdate;
OraQuery1.FetchAll := True;
OraQuery1.Open;
...
procedure TForm1.OraQuery1AfterFetch(DataSet: TCustomDADataSet);
begin
  if not DataSet.Fetching then
  begin
    GridDBTableView.EndUpdate;
    GridDBTableView.ApplyBestFit;
  end;
end;
It seems like grid have been not properly informed that data is ready without calling BeginUpdate / EndUpdate...
I have no idea whether problem is in grid class itself or TOraQuery...

Regards
P.C.