Saturday, February 24, 2018

Validation of data

Sometimes when I analyze data in database I discover bugs.
For example if a class/table TripEvent contains 2 date attributes ArriveDate and CompleteDate.
Of course ArriveDate is always before CompleteDate. But for some reason the order is wrong in database. There is logic in code that decide the dates but I have no idea how it can happen.

I can add validation of data before it is persisted to database. The method TBoldObject.PrepareUpdate is virtual and is called just before the object is persisted. This is a good place to validate data. The business rule:

ArriveDate <= CompleteDate

ArriveDate should always be less or equal to CompleteDate.
What happens if this rule is violated it is up to us to decide.
In this case I want an exception  so no data is saved to database. This is done by a rollback in the global exceptionhandler. I use Assert as this is a convenient way to validate data. Just check that Assertions is enabled in compiler settings.

procedure TTripEvent.PrepareUpdate;
begin
  inherited;
  if not (M_ArriveDate.IsNull or M_CompleteDate.IsNull) then
    Assert(ArriveDate <= CompleteDate,
      Format('Validation failed as ArriveDate %s > CompleteDate %s', [DateTimeToStr(ArriveDate)DateTimeToStr(CompleteDate)]));
end;

Before validation there must be a nullcheck as there is no point compare null values.
Now if validation failed an exception is raised and that is logged with callstack.
I can now see where in the source it is called and easier fix it.