program testOldValue;

{$mode objfpc}{$H+}

uses
  {$IFDEF UNIX}{$IFDEF UseCThreads}
  cthreads,
  {$ENDIF}{$ENDIF}
  Classes, SysUtils, CustApp,
  db, sqlite3conn, sqldb, variants;

type

  { TtestOldValue }

  TtestOldValue = class(TCustomApplication)
  protected
    procedure DoRun; override;
  public
    constructor Create(TheOwner: TComponent); override;
    destructor Destroy; override;
    procedure WriteHelp; virtual;
  private
    Forder: integer;
    procedure Show(Msg: string; Field: TField);
    procedure QfieldValidate(Sender: TField);
    procedure QfieldChange(Sender: TField);
    procedure QBeforePost(DataSet: TDataSet);
    procedure QAfterPost(DataSet: TDataSet);
  end;

{ SQLite3Test }

procedure TtestOldValue.DoRun;
var
  ErrorMsg: String;

  Conn: TSQLite3Connection;
  Tran: TSQLTransaction;
  s: string;

  Q: TSQLQuery;

begin
  // quick check parameters
  ErrorMsg:=CheckOptions('h','help');
  if ErrorMsg<>'' then begin
    ShowException(Exception.Create(ErrorMsg));
    Terminate;
    Exit;
  end;

  // parse parameters
  if HasOption('h','help') then begin
    WriteHelp;
    Terminate;
    Exit;
  end;

  Conn:=TSQlite3Connection.Create(Self);
  Conn.DatabaseName:='test.db';

  Tran:=TSQLTransaction.Create(Self);
  Tran.DataBase:=Conn;

  Conn.Open;

  Conn.ExecuteDirect('CREATE TEMPORARY TABLE t (int_field INTEGER PRIMARY KEY, str_field varchar(1))');
  Conn.ExecuteDirect('INSERT INTO t VALUES(1, ''O'')');

  Q:=TSQLQuery.Create(Self);
  Q.Name:='SQLQuery1';
  Q.DataBase:=Conn;
  Q.Transaction:=Tran;
  Q.BeforePost:=@QBeforePost;
  Q.AfterPost:=@QAfterPost;
  Q.SQL.Text:='SELECT * FROM t';
  Q.Open;

  Q.Fields[1].OnValidate:=@QfieldValidate;
  Q.Fields[1].OnChange  :=@QfieldChange;

  Forder:=1;
{Q.AppendRecord([1,'O']);
  Show('Before ApplyUpdates', Q.Fields[1]);
  Q.ApplyUpdates;
  Show('After ApplyUpdates', Q.Fields[1]);
  Tran.CommitRetaining;
}
  Forder:=1;
  Q.Edit;
  Q.Fields[1].Value:='N';
  Q.Post;
  Show('Before ApplyUpdates', Q.Fields[1]);
  Q.ApplyUpdates;
  Show('After ApplyUpdates', Q.Fields[1]);
  Tran.CommitRetaining;

  Q.Close;

  Tran.Commit;
  Conn.Close;

  Q.Free;
  Tran.Free;
  Conn.Free;
  readln;

  // stop program loop
  Terminate;
end;

constructor TtestOldValue.Create(TheOwner: TComponent);
begin
  inherited Create(TheOwner);
  StopOnException:=true;
end;

destructor TtestOldValue.Destroy;
begin
  inherited Destroy;
end;

procedure TtestOldValue.WriteHelp;
begin
  { add your help code here }
  writeln('Usage: ',ExeName,' -h');
end;

procedure TtestOldValue.Show(Msg: string; Field: TField);
  function VarToStr2(v:variant):string;
  begin
    if VarIsNull(v) then Result:='null'
    else Result:=VarToStr(v);
  end;
begin
  writeln( format('%d. %s: OldValue=%s; Value=%s; NewValue=%s',
                 [Forder, Msg, VarToStr2(Field.OldValue), VarToStr2(Field.Value), VarToStr2(Field.NewValue)])
         );
{  writeln( format('%d. %s: DataSet=%s; Field=%s; OldValue=%s; Value=%s; NewValue=%s',
                 [Forder, Msg, Field.DataSet.Name, Field.FieldName, VarToStr(Field.OldValue), VarToStr(Field.Value), VarToStr(Field.NewValue)])
         );
}
  inc(Forder);
end;

procedure TtestOldValue.QfieldValidate(Sender: TField);
begin
  Show('Field.OnValidate', Sender);
end;

procedure TtestOldValue.QfieldChange(Sender: TField);
begin
  Show('Field.OnChange', Sender);
end;

procedure TtestOldValue.QBeforePost(DataSet: TDataSet);
begin
  Show('BeforePost', DataSet.Fields[1]);
end;

procedure TtestOldValue.QAfterPost(DataSet: TDataSet);
begin
  Show('AfterPost', DataSet.Fields[1]);
end;

var
  Application: TtestOldValue;

{$R *.res}

begin
  Application:=TtestOldValue.Create(nil);
  Application.Run;
  Application.Free;
end.

