TIBEVENT doesn't fire all events

Following previous thread I created a test project with 2 forms, each with its own TIBEvent with same events : 'ER_SEZIO', 'SEZIO'.
Table has this trigger :
CREATE TRIGGER SEZIO_AU_PEVT FOR SEZIO
ACTIVE AFTER UPDATE POSITION 0
AS
begin
 if (not (new.csoc = old.csoc)) then  post_event old.csoc||'_SEZIO';
 post_event new.csoc||'_SEZIO';
 post_event 'SEZIO';
end

When I do update to table Event fires, and in one form both events are detected, in the other only 'SEZIO' is detected and 'ER_SEZIO' is missed.

Adalberto Baldini
0
Adalberto
4/25/2015 9:30:50 AM
embarcadero.delphi.interbase 331 articles. 1 followers. Follow

10 Replies
512 Views

Similar Articles

[PageSpeed] 30

Adalberto Baldini wrote:
> Following previous thread I created a test project with 2 forms, each with its own TIBEvent with same events : 'ER_SEZIO', 'SEZIO'.
> Table has this trigger :
> CREATE TRIGGER SEZIO_AU_PEVT FOR SEZIO
> ACTIVE AFTER UPDATE POSITION 0
> AS
> begin
>  if (not (new.csoc = old.csoc)) then  post_event old.csoc||'_SEZIO';
>  post_event new.csoc||'_SEZIO';
>  post_event 'SEZIO';
> end
> 
> When I do update to table Event fires, and in one form both events are detected, in the other only 'SEZIO' is detected and 'ER_SEZIO' is missed.
> 
> Adalberto Baldini

I can't reproduce this.

I tested this with RAD XE7 against both IB XE3 and XE7.
Also tested RAD XE8 against IB XE3 and XE7.  All the evetns fired and were there 
like expected.

The simple stored procedure to fire it looks like

CREATE PROCEDURE "TEST_POST"
(
   "EV1" VARCHAR(20),
   "EV2" VARCHAR(20)
)
AS
begin
   post_event ev1;
   post_event ev2;
   post_event ev1;
end

The SQL to fire it looked like

execute procedure test_post('ER_SEZIO', 'SEZIO')

The events were autoRegistered with the IBEvent looking like

   object ev1: TIBEvents
     AutoRegister = True
     Database = db1
     Events.Strings = (
       'SEZIO'
       'TEST'
       'ER_SEZIO')
     Registered = False
     OnEventAlert = ev1EventAlert
     Left = 432
     Top = 24
   end

Note I tried the events in multiple orders to make sure there was no issue with 
that and had 3 events registered in case that could be the issue with the one 
not firing separating the two that do.

The code to display them looked like

procedure TForm13.ev1EventAlert(Sender: TObject; EventName: string;
   EventCount: Integer; var CancelAlerts: Boolean);
begin
   mmo1.Lines.Add(EventName + ' - ' + EventCount.ToString);
end;

In all cases the results were

ER_SEZIO - 2
SEZIO - 1

-- 
Jeff Overcash (TeamB)
       (Please do not email me directly unless  asked. Thank You)
And so I patrol in the valley of the shadow of the tricolor
I must fear evil. For I am but mortal and mortals can only die.
Asking questions, pleading answers from the nameless
faceless watchers that stalk the carpeted  corridors of Whitehall.
              (Fish)
0
Jeff
4/27/2015 7:21:12 PM
Could you duplicate the form  in same project, open both,  and see if in both forms events fire in same way ?
0
Adalberto
4/28/2015 7:21:04 AM
Do you miss TEST event ?
0
Adalberto
4/28/2015 7:29:07 AM
> {quote:title=Adalberto Baldini wrote:}{quote}
> Do you miss TEST event ?

Please ignore it !!!!!
0
Adalberto
4/28/2015 11:13:10 AM
I prepared a video showing my test, where can I send it ?
Adalberto Baldini
0
Adalberto
5/4/2015 8:03:59 AM
You can attach files on a message in the Attachment forum

https://forums.embarcadero.com/forum.jspa?forumID=2
0
Robert
5/4/2015 11:16:56 AM
Adalberto Baldini wrote:
> Could you duplicate the form  in same project, open both,  and see if in both forms events fire in same way ?

your app in attachments did not demonstrate this for me.

I tested it with RAD XE6, XE7, XE8 (which unfortunately for me is basically the 
same code base for IBX as I did a lot of hte XE8 work in Xe6/7 for various reasons).

Your code was missing the dpr.  So I did this.  I created a new SDI app.  Saved 
it.  Closed down that project, copied over your files over it.  Opened it. 
Addded your frmMain unit.  Set it as hte main form and the SDIMAIN form to not 
be auto created.  I also added IBX to the unit scope names.

Ran it.  Got the forms as you seemed to have intended.  Hit the button and saw 
both of the events fire everywhere.

Going way back to XE5 I finally reproduced this.  There are many changes between 
Xe5 and XE6, but mostly those were around a fix to the actual API call itself 
that only showed on win64 apps.  The signature was mis-documented for years, but 
the size of the structure was correct even mis-documented for win32, but wrong 
for win64 which is why no one noticed it until Win64 support was released.

Try just these two changes in IBEvents.pas, statically link into your app and 
see if that gets it working.

{code}
procedure TIBEvents.RegisterEvents;
var
   i: Integer;
   s: String;
   b : TBytes;
begin
   if csDesigning in ComponentState then
     exit;
   try
     if not Assigned(FDatabase) then
       IBError(ibxeDatabaseNameMissing, []);
     if not FDatabase.Connected then
       IBError(ibxeDatabaseClosed, []);
     // We need the strings to be permanent AnsiStrings in TBytes form
     FEvents.Clear;
     for s in FUniEvents do
     begin
       b := TEncoding.ANSI.GetBytes(s);
       SetLength(b, Length(b) + 1);
       FEvents.Add(b);
     end;
     if (FThreads.Count = 0) then
     begin
       if (FEvents.Count > 0) then
       begin
         for i := 0 to ((FEvents.Count - 1) div IB_MAX_EVENT_BLOCK) do
           FThreads.Add(TIBEventThread.Create(Self, i, ThreadEnded));
       end;
     end
     else
       IBError(ibxeEventAlreadyRegistered, []);
   finally
     FRegistered := FThreads.Count <> 0;
   end;
end;
{code}

{code}
procedure TIBEventThread.ProcessEvents;
var
   i: Integer;
begin
   Parent.Database.GDSLibrary.isc_event_counts(@FStatus, EventBufferLen, 
EventBuffer, ResultBuffer);
   if Assigned(Parent.FOnEventAlert) and (not FirstTime) then
   begin
     FCancelAlerts := false;
     for i := 0 to (EventCount - 1) do
     begin
       if (FStatus[i] <> 0) then
       begin
         WhichEvent := i;
         CountForEvent := FStatus[WhichEvent];
         Synchronize(DoEvent)
       end;
     end;
   end;
   FirstTime := false;
end;
{code}

Please always mention if you are not on the current version what version you are 
on.  It wastes my time to look at things in the wrong version and therefore 
lengthens any time it takes to get you an answer.

-- 
Jeff Overcash (TeamB)
       (Please do not email me directly unless  asked. Thank You)
And so I patrol in the valley of the shadow of the tricolor
I must fear evil. For I am but mortal and mortals can only die.
Asking questions, pleading answers from the nameless
faceless watchers that stalk the carpeted  corridors of Whitehall.
              (Fish)
0
Jeff
5/11/2015 6:16:23 PM
Hi, I was looking update in attachement and I apologize I asked you about test.

I am at Embarcadero® Delphi® XE5 Version 19.0.14356.6604 and with your code, in ProcessEvents I get error : FStatus  undeclared identifier

My version uses StatusVector instead of @FStatus 

BUT  modifying only RegisterEvents it works. Thanks.

Adalberto Baldini
0
Adalberto
5/13/2015 5:55:10 AM
with yr suggestion :
for s in FUniEvents do
    begin
      b := TEncoding.ANSI.GetBytes(s);
      // new line from Jeff Overcash
      SetLength(b, Length(b) + 1);
      FEvents.Add(b);
    end;

I get as IBEvent.name =  'ED_SEZIO'#0

is it possible delete  #0 in someway or I need to modify IBEventAlert in all my programs with :
SetLength(EventName, Length(EventName) - 1);

Regards
Adalberto Baldini
0
Adalberto
5/13/2015 9:32:28 AM
I added a new post to thread
0
Adalberto
5/13/2015 9:32:59 AM
Reply: