Thema: Delphi TFDEventAlerter HowTo

Einzelnen Beitrag anzeigen

Benutzerbild von haentschman
haentschman

Registriert seit: 24. Okt 2006
Ort: Seifhennersdorf / Sachsen
4.932 Beiträge
 
Delphi 10.1 Berlin Professional
 
#9

AW: TFDEventAlerter HowTo

  Alt 3. Jun 2021, 07:27
Hallöle...
Zitat:
Mir wäre das viel lieber, als alle paar Sekunden auf neue oder geänderte Daten zu prüfen.
Das ganze war mir zu unsicher. Ich habe mich fürs "Polling" entschieden...

1. EventTypes
Delphi-Quellcode:
TRefreshDataType = (rdtComplete)
...
2. In der Datenbank eine Tabelle:
Code:
create table _Events
(
  ID int IDENTITY(1,1) NOT NULL,
  EventType int NOT NULL,
  EventName nvarchar(30) NOT NULL,
  EventCurrentGUID uniqueidentifier NOT NULL,
  CONSTRAINT Events_pk PRIMARY KEY CLUSTERED (ID ASC)
)
create index ixEventType on _Events (EventType)
GO

/* Events */
insert into _Events (EventType, EventName, EventCurrentGUID) values (0, 'Complete', NEWID())
GO

/* Trigger*/
create trigger TR_Complete on Complete for insert, update, delete as
begin
  update _Events set EventCurrentGUID = NEWID() where EventType = 0
end
GO
3. Ein Thread der das ganze überwacht (Auszug)
Delphi-Quellcode:
procedure TDatabaseEventThread.Execute;
var
  Qry: TFDQuery;

  procedure LoadEvents;
  begin
    Qry.Open;

    while not Qry.Eof do
    begin
      FGUIDDict.Add(Qry.FieldByName('EventType').AsInteger, TGuidField(Qry.FieldByName('EventCurrentGUID')).AsGUID);
      Qry.Next;
    end;
  end;

  procedure CheckEvents;
  var
    PairCurrent: TPair<Integer, TGUID>;
  begin
    FGUIDDictCurrent.Clear;
    Qry.Close;
    Qry.Open;

    while not Qry.Eof do
    begin
      FGUIDDictCurrent.Add(Qry.FieldByName('EventType').AsInteger, TGuidField(Qry.FieldByName('EventCurrentGUID')).AsGUID);
      Qry.Next;
    end;

    for PairCurrent in FGUIDDictCurrent do
    begin
      if FGUIDDict.ContainsKey(PairCurrent.Key) then // sicher ist sicher
      begin
        if not (FGUIDDict.Items[PairCurrent.Key] = PairCurrent.Value) then
        begin
          FGUIDDict.Items[PairCurrent.Key] := PairCurrent.Value; // zurückschreiben
          FLastEvent := TRefreshDataType(PairCurrent.Key); // DataType für Synchronisierung
          SyncOnDataChange;
        end;
      end;
    end;
  end;

begin
  inherited;
  Qry := FDatabase.CreateQuery;
  try
    Qry.SQL.Text := FDatabase.GetSQLByName('DB_EVENTS');

    LoadEvents;

    while not Self.Terminated do
    begin
      if FDatabase.IsEventDataChangeActive then
      begin
        CheckEvents;
      end;
      Sleep(1000);
    end;
  finally
    Qry.Free;
  end;
end;
Wenn ein Event eintritt, verteile ich das über eine Message an die Forms und die gibt das an die entsprechende Formlogik weiter. Die Formlogik kennt die Events auf die sie reagieren soll und aktualisiert ggf. die Datenmenge der Form.

...fertsch.

Geändert von haentschman ( 3. Jun 2021 um 07:46 Uhr)
  Mit Zitat antworten Zitat