Jump to content

Access Validation when calling UniMainModule via FDEventAlerter .onAlert


M.Ammar

Recommended Posts

hi 

I am using FDEventAlerter to detect any changes made to a query by another user in order to refresh the other users' Query,

No 1: Everything is working fine except if I try to access any information from the uniMainMidule (Query, Record.. anything ) from within the OnAlert Event 

procedure TfraListView.FDEventAlerter1Alert(ASender: TFDCustomEventAlerter;
   const AEventName: string; const AArgument: Variant);
var
   i                : Integer;
   sArgs            : string;
begin
   {other code}
  // working Example
    sArgs := 'test';
    FDQuery1.refresh; // refresh on form Query Wroking 

  // Error Examples
   UniMainModule.UserRecord.UserID := 1; // access validation
   UniMainModule.FDQuery1.refresh;       // access validation
end;

if I try to access the same information in UniMainModule from any other procedure no Access Validation Erro, I can work around the error by using local variables and queries but it is strange

No 2:  after refreshing the local query via this procedure, the uniDBGrid attached is not refreshed unless scrolling by mouse or keyboard, this doesn't happen on the VCL test I made.

best regards

Link to comment
Share on other sites

Problem is EventAlerter has a thread. its conflict with unigui's thread so not good idea use any EventAlerter.

maybe my message give idea on this link

http://forums.unigui.com/index.php?/topic/12043-how-to-send-a-text-message-from-servermodule-to-all-mainform-sessions/&do=findComment&comment=64328

 

  • Like 1
Link to comment
Share on other sites

On 3/8/2019 at 12:36 PM, Freeman35 said:

Problem is EventAlerter has a thread. its conflict with unigui's thread so not good idea use any EventAlerter.

maybe my message give idea on this link

http://forums.unigui.com/index.php?/topic/12043-how-to-send-a-text-message-from-servermodule-to-all-mainform-sessions/&do=findComment&comment=64328

 

thank you for the reply, if it is not a good idea to use it, do you have any other suggestions to an alternative way to update client query if data were changed on the server side this will happen 3 times daily,  

also, If I found no other solution and had to use one EventAlerter on the main form, what negative effect on the application.

thanks and best regards 

Link to comment
Share on other sites

Try this :

1. Create an integer Field  F on your Table.

2. Any update / insert  in this Table will increment this field and updat it in the same record.

3. Put a Timer (10 sec) wich get a cheksum like : select sum(F) from Table

(This is a Fast query, so don't worry about system performances).

Then compare this chekSum :

If S1 <> S2 then refresh automatically your dbGrid.

Regards.

  • Like 1
Link to comment
Share on other sites

Try this :

1. Create an integer Field  F on your Table.

2. Any update / insert  in this Table will increment this field and updat it in the same record.

3. Put a Timer (10 sec) wich get a cheksum like : select sum(F) from Table

(This is a Fast query, so don't worry about system performances).

Then compare this chekSum :

If S1 <> S2 then refresh automatically your dbGrid.

Regards.

 

 

Edit :

METHODE 2

If you have a big data with many users and you don't want to torture your RDBM, then you can listen to the incomming query.

Try this :

1. Put a global boolean variable  on server module. Let's say  bAlert1:boolean;

2. In mainModule track any query wich contains word "update myTable"  or  "insert into myTable"   or   "Delete from myTable"  

Then  serverModule.bAlert1:=True

3. Put in your form or Frame an uniTimer wich get serverModule.bAlert1

If True then

Begin

bAlert1:= false

Refresh your dbgrid.

End;

This is more light then methode 1

Regards

  • Like 1
Link to comment
Share on other sites

Abaksoft thank you for both replies,

I think that your 1st idea is better in my case because I have Multi-company and multi branches application, I need to refresh only in the case of data related to this branch is edited, I will create checksum int in the related branch record and increase it whenever I need users for this branch to refresh, then use timer to check for this record only

thanks and best regards

 

Link to comment
Share on other sites

On 3/10/2019 at 9:32 AM, M.Ammar said:

thank you for the reply, if it is not a good idea to use it, do you have any other suggestions to an alternative way to update client query if data were changed on the server side this will happen 3 times daily,  

also, If I found no other solution and had to use one EventAlerter on the main form, what negative effect on the application.

thanks and best regards 

I was write on that link.

EventAlerter check only one db. And it has a thread. How to use this EventAlerter ? for firebird, use "postevent" manual or in trigger. I'm use manual, via sql command in tquery. on aftercommit event of transaction.

in Unigui, remove "EventAlerter" because you have a sessionlist. this mean you have all clients list. You can accsess to all mainform, or others form. for me easy way is access to just mainform. I wrote, Add a property to mainform on your app. If you set this property, set.... procedure is triggered. So, get forms list, this will be same session then same idea, add property to other form and add set.... procedure.

You don't need timer. This my suggession works like a EventAlerter. JUST in same application, but multi session. And need get all sessions list in hyperserver :)

Link to comment
Share on other sites

thank you for reply,

I am sorry to say that I have read your comments several times but I failed to understand it, it seems that English is the 2nd Language for me and you.:)

I did take your first advice and removed EventAlerter from the application.

- "for firebird, use "postevent"":  my database is MS SQL, not Firebird.

- "You can access to all mainform": you mean access from where Server Module, if so how server module detects changes in the database without timer? 

how I detect changes on the table without a timer to check for changes, which is currently working for me. (Abaksoft 1st idea)

forgive me I am a newbie in this  

regards

  • Like 1
Link to comment
Share on other sites

No problem :) But, sorry,  english never & ever be my any language.  https://www.youtube.com/watch?v=m70qoPgB1ms

- "for firebird, use "postevent"":  my database is MS SQL, not Firebird.  no metter :)

- "You can access to all mainform": you mean access from where Server Module,

You have to learn unigui how is work. you have a session list. (look in demos) "uniGUI\uniGUI\Demos\Desktop\Session List\"

-if so how server module detects changes in the database without timer? 

This is about OOP programing
 

type
  T_FRM = class(TUniForm)
.....
procedure Set_On_FB_Event(const FB_Event: Integer);
...
  published
    property On_FB_Event: Integer write Set_On_FB_Event;
........
procedure T_FRM.Set_On_FB_Event(const FB_Event: Integer);
begin
// your code here
end;

When use T_FRM.On_FB_Event:= ...;  Set_On_FB_Event will triggered. So, you don't need timer.

And when need trigger  easy way is, Tquery.AfterPost & Tquery.AfterDelete.  For example: ServerModelue has a "procedure Sent_Event_to_All_Sessions(This_Table_ID: Integer);" In This procedure, get all session, then one by one get all form's of session's  and set T_FRM.On_FB_Event:= This_Table_ID;

I hope translate this time :)

  • Like 1
Link to comment
Share on other sites

  • 2 years later...
On 3/11/2019 at 7:57 AM, Abaksoft said:

3. Put in your form or Frame an uniTimer wich get serverModule.bAlert1

If True then

Begin

bAlert1:= false

Refresh your dbgrid.

End;

Just would like to advise:

There is a problem here :

The boolean global variable bAlert1 is shared for all session. It must not be reset by a session.

• One solution here is to increment a global variable and compare it with a local variable (instead if using a boolean).

• The best solution, is to store this variable in a table ( as server farm technology is comming soon).

• The Best of the best solution, is to use triggers DB, wich incremncrement a generator ID (Sequence in FireBird)  combined with an unitimer.

see :

http://forums.unigui.com/index.php?/topic/14772-how-can-i-receive-database-table-updates-periodically/&do=findComment&comment=81897

 

Link to comment
Share on other sites

39 minutes ago, Abaksoft said:

The boolean global variable bAlert1 is shared for all session. It must not be reset by a session.

Hello, can you explain why?

In my needs I use this logic:

I have a procedure in uniMainModule

one global variable in uniServerModule,

the procedure will start running in an active session if the global variable is not True. After executing the procedure in the session, the variable is set to False  so that another session can execute it.

Link to comment
Share on other sites

5 hours ago, irigsoft said:

Hello, can you explain why?

In my needs I use this logic:

I have a procedure in uniMainModule

one global variable in uniServerModule,

the procedure will start running in an active session if the global variable is not True. After executing the procedure in the session, the variable is set to False  so that another session can execute it.

This is a other story :)

There is no problem in your logic. You can use your global variable, on ServerModule,  if you don't need in the futur multiple servers (server farm).

What i have notice is about refreshing a grid. So if my bAlert1 is reset to false (because my session has done its refreshing), another user could'nt refresh its grid. That why i suggested to increment a global variable on serverModule.

Link to comment
Share on other sites

41 minutes ago, Abaksoft said:

So if my bAlert1 is reset to false (because my session has done its refreshing), another user could'nt refresh its grid. That why i suggested to increment a global variable on serverModule.

OK I understand problem with global Boolean in this case.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...