Subject Re: [IBO] Syncronizing transactions
Author hans@hoogstraat.ca
Hope the following is of some use to someone ...

This little data synchronization setup is easily maintained
and expanded. Due to it's on demand nature, it has a minimum
impact on the server and client software. DML caching has
many more options, but this is all I needed for an Airport
Arrival/Departure time like test.

Best Regards
Hans

================================
Add a little Table to the server
================================

CREATE TABLE TABLES_UPDATE (
RELATION_NAME CHAR( 31 ) NOT NULL
, DATETIME_UPDATED TIMESTAMP
, COUNT_UPDATED DECIMAL ( 18, 0 )
, PRIMARY KEY (RELATION_NAME)
)

====================================================
Add a little server procedure to maintain this table
====================================================
CREATE PROCEDURE TABLE_UPDATE( RELATION_NAME CHAR( 31 ) )
AS
BEGIN

/* Check if Table entry Present */

IF (NOT EXISTS (SELECT COUNT_UPDATED FROM TABLES_UPDATE
WHERE RELATION_NAME = :RELATION_NAME)) THEN

/* Not present, Create first Entry */

INSERT INTO TABLES_UPDATE
(RELATION_NAME,DATETIME_UPDATED,COUNT_UPDATED)
VALUES
(:RELATION_NAME,CURRENT_TIMESTAMP,1);
ELSE

/* Update Entry for Sync Requests */

BEGIN
UPDATE TABLES_UPDATE SET DATETIME_UPDATED = CURRENT_TIMESTAMP,
COUNT_UPDATED = COUNT_UPDATED+1
WHERE RELATION_NAME = :RELATION_NAME;
END

END

=====================================================
Now, for each Table to be part of the synchronization
add the EXECUTE PROCEDURE TABLE_UPDATE ('TABLE1');
statement to it's 'After Insert', 'After Update'
and 'After Delete' triger, like :
=====================================================

CREATE TRIGGER TABLE1_AFTER_INSERT FOR TABLE1
AFTER INSERT ... AFTER UPDATE ... AFTER DELETE
AS
BEGIN
... your statements ..
EXECUTE PROCEDURE TABLE_UPDATE ('TABLE1');
END

==========================
Add the Delphi client site
==========================
var
ResyncSecs : Double; // No of Secs to Resync when Idle

ResyncTime : TDateTime;

Application.OnIdle := MyIdleHandler;

=======================================================
When the Client is in Idle state for x No of secs, the
Idle handler will check and refresh Tables of interest.
This little example just checks for 'TABLE1' only
=======================================================

// Idle Handler ===========================================

procedure TFNotesMain.MyIdleHandler(Sender: TObject; var Done: Boolean);
var
IdleBookMark : String;

begin

// about every ResyncSecs secs

with DM do
if Now - ResyncTime > ResyncSecs / (24.0*3600.0) then
begin
ResyncTime := Now;

// Make sure Table is in Browse mode

if IBTable1.Active and (IBTable1.State = dsBrowse) then
begin

// Get latest update count for this table via an IBOQuery or
IB_Query

IBTables_Update.Close;
IBTables_Update.SQL.Text := 'SELECT COUNT_UPDATED FROM TABLES_UPDATE
WHERE RELATION_NAME=TABLE1';
IBTables_Update.Prepare;
IBTables_Update.Open;

// Check if it macthes our update count held in our Tag

if not IBTables_Update.IsEmpty then
if IBTable1.Tag <> IBTables_UpdateCount_Updated.value then
begin

// Update took place, Refresh

IBTable1.Tag := IBTables_UpdateCount_Updated.value;

try
IdleBookMark := IBTable1.BookMark; // Hold our location
IBTable1.Refresh; // if this Table is
IBTable1.BookMark := IdleBookMark; // used in a Grid
except
end;

end;
end;
end;
end;