unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls, DB, FIBDataSet, pFIBDataSet, FIBDatabase, pFIBDatabase,
  ExtCtrls, StdCtrls, Grids, DBGrids, pFIBProps, DBCtrls, IdUDPServer,
  IdBaseComponent, IdComponent, IdUDPBase, IdUDPClient, IdSocketHandle;

type
  TForm1 = class(TForm)
    StatusBar1: TStatusBar;
    db: TpFIBDatabase;
    tr: TpFIBTransaction;
    dt: TpFIBDataSet;
    ds: TDataSource;
    Panel1: TPanel;
    Label2: TLabel;
    DBGrid1: TDBGrid;
    IdUDPClnt: TIdUDPClient;
    IdUDPSrv: TIdUDPServer;
    Memo1: TMemo;
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    procedure Button1Click(Sender: TObject);
    procedure IdUDPSrvUDPRead(Sender: TObject; AData: TStream;
      ABinding: TIdSocketHandle);
    procedure dtAfterDelete(DataSet: TDataSet);
    procedure dtBeforePost(DataSet: TDataSet);
    procedure dtAfterPost(DataSet: TDataSet);
    procedure dtBeforeDelete(DataSet: TDataSet);
  private
    FID: Integer;
    FAction: Integer; //0-insert, 1-update, 2-delete
    function GetNotifyStr: string;
    procedure SendNotify(NotifyStr: string);
    procedure RecvNotify(NotifyStr: string);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

uses uCommon;

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  Memo1.Text := GetExampleNotes;
  Caption := 'FIBPlus Example - ' + Application.Title;
  db.DBName := 'localhost:' + ExtractFileDir(Application.ExeName) + '\db\employee.fdb';
  db.Connected := True;

  dt.SelectSQL.Text := 'SELECT * FROM EMPLOYEE';
  dt.AutoUpdateOptions.AutoReWriteSqls := True;
  dt.AutoUpdateOptions.CanChangeSQLs   := True;
  dt.AutoUpdateOptions.UpdateOnlyModifiedFields := True;
  dt.AutoUpdateOptions.UpdateTableName := 'EMPLOYEE';
  dt.AutoUpdateOptions.KeyFields       := 'EMP_NO';
  dt.AutoUpdateOptions.GeneratorName   := 'EMP_NO_GEN';
  dt.AutoUpdateOptions.WhenGetGenID    := wgBeforePost;

  dt.Open;

  try
  IdUDPClnt.Active := True;
  IdUDPSrv.Active := True;
  except
  end;

//  RecvNotify('EMPLOYEE;1023;1');
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  if not db.Connected then Exit;
  db.CloseDataSets;
  db.Close;
end;

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  CanClose := MessageDlg('This will end your ' + QuotedStr(Caption) + ' session. Proceed?',
    mtConfirmation, [mbOk, mbCancel], 0) = mrOk;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  if dt.CanModify then showMessage('can modify');
end;

procedure TForm1.IdUDPSrvUDPRead(Sender: TObject; AData: TStream;
  ABinding: TIdSocketHandle);
var
  ss: TStringList;
  S: String;
begin
  ss := TStringList.Create;
  ss.LoadFromStream(AData);
  RecvNotify(ss.Text);
  ss.Free;
end;

procedure TForm1.RecvNotify(NotifyStr: string);
var
  TblName, ActName: string;
  ID: Integer;
  OP: Integer;
  procedure ParseNotifyStr;
  var p: integer;
  begin
    p  := pos(';', NotifyStr);
    TblName := Copy(NotifyStr,1, p - 1);
    Delete(NotifyStr, 1, p);
    p  := pos(';', NotifyStr);
    ID := StrToInt(Copy(NotifyStr,1, p - 1));
    Delete(NotifyStr, 1, p);
    OP := StrToInt(Copy(NotifyStr, 1, Length(NotifyStr)-2));
    case OP of
      0: ActName := 'Insert';
      1: ActName := 'Update';
      2: ActName := 'Delete';
    end;
  end;
begin
  ParseNotifyStr;
  ShowMessageFmt('TableName: %s'#10'Action: %s'#10'ID: %d',
   [TblName, ActName, ID]);
end;

procedure TForm1.SendNotify(NotifyStr: string);
begin
  IdUDPClnt.Broadcast(NotifyStr, 2100);
end;

procedure TForm1.dtBeforePost(DataSet: TDataSet);
begin
  if DataSet.State = dsEdit
  then FAction := 1
  else FAction := 2;
end;

procedure TForm1.dtBeforeDelete(DataSet: TDataSet);
begin
  FID := dt.FBN(dt.AutoUpdateOptions.KeyFields).AsInteger;
  FAction := 2;
end;

procedure TForm1.dtAfterPost(DataSet: TDataSet);
begin
  FID := dt.FBN(dt.AutoUpdateOptions.KeyFields).AsInteger;
  SendNotify(GetNotifyStr);
end;

procedure TForm1.dtAfterDelete(DataSet: TDataSet);
begin
  SendNotify(GetNotifyStr);
end;

function TForm1.GetNotifyStr: string;
begin
  Result :=
    dt.AutoUpdateOptions.UpdateTableName +
    ';' + IntToStr(FID) + ';' + IntToStr(FAction);
end;

end.
