Hi *,
I have 2 questions, which I divide into 2 emails.

1st is about TField.OldValue and Delphi compatibility. Please look at small attached program (for SQLite3).

In Delphi (with TClientDataSet and dbExpress) outputs:
1. Field.OnValidate: OldValue=N; Value=N; NewValue=N
2. Field.OnChange: OldValue=O; Value=N; NewValue=N
3. BeforePost: OldValue=O; Value=N; NewValue=N
4. AfterPost: OldValue=O; Value=N; NewValue=N
5. Before ApplyUpdates: OldValue=O; Value=N; NewValue=N
6. After ApplyUpdates: OldValue=N; Value=N; NewValue=N

In FPC:
1. Field.OnValidate: OldValue=N; Value=N; NewValue=N
2. Field.OnChange: OldValue=null; Value=N; NewValue=N
3. BeforePost: OldValue=null; Value=N; NewValue=N
4. AfterPost: OldValue=O; Value=N; NewValue=N
5. Before ApplyUpdates: OldValue=O; Value=N; NewValue=N
6. After ApplyUpdates: OldValue=null; Value=N; NewValue=N

As you can see, there are differences in 2,3,6, where in FPC OldValue is NULL but in Delphi is it "old value". Dou you think, that it is bug ? (at least it makes impossible compare OldValue and Value in BeforePost event handler and take some action when some field changes)

TIA
L.
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.

_______________________________________________
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply via email to