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;
  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)]));

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.

Sunday, June 11, 2017

True Unit tests in Bold ?

I think you all heard about unit testing. Maybe some of you even practise it?

I recently bought Dependency Injection book by Nick Hodges. It is about to have loose coupled classes. And this is a precondition for true unit-test where each class is tested independently.

This make me thinking. How would that be possible in Bold? An important part in Dependency Injection is interfaces but the model don't support that now. Ex class TPerson have a link to TAdress. There may also be a method like TAdress.AddPerson(aPerson: TPerson).

To test AddPerson with a unit-test one interface is needed IPerson. The signature need to be changed to TAdress.AddPerson(aPerson: IPerson). Now the interface can be used instead. The same is true for any relations between classes. If there is a single link TPerson.homeAdress: TAdress that should be changed to TPerson.homeAdress: IAdress.

Our main Application Attracs have a huge model. Over 400 classes. So to change this some kind of automation is needed. I thought about to scan businessclasses.pas with a program and generate a new file businessclasses_Interfacedef.pas to differentiate with the original businessclasses_interface.pas.

The new file would contain interfaces to classes in businessclasses_interface.pas like IPerson, IAdress etc. The public methods in each class should be added manually as you cannot indtroduce a lot of interfaces in am application in one step. Easier to divide it in smaller steps. So the generation of file businessclasses_Interfacedef.pas preserve existing methods. New interfaces has no methods.

Next step would be to change application code to use interfaces.

Instead of

vPerson.homeAddress as TAddress;


vPerson.homeAddress as IAddress;

And I think this is the main issue, a lot of changes is required.
But it can at least be done in smaller steps, class by class.

And the rewards is possibility to use true unit-testing. Test all methods in a class. As interfaces is used in relations and parameters fake instances can be used.

Comments are welcome because all this is completely untested. I just brainstorm here :)

Tuesday, March 7, 2017

Saturday, January 7, 2017

Help me to make Bold open source project!

About 4 years ago I started this petition to make Bold open source. 
Right now there is 278 supporters.

What is Bold
It is an ORM framework founded by a Swedish company Boldsoft that later was bought by Borland around 2002. The idea with Bold is that the UML model is the core of an Bold application. It is in the model you store the logic classes and relations. This is then automatically translated to a SQL script to be applied to the database and class definitions. 

Bold do the translations of rows in database to objects in memory in both directions.

For example to read the name of a table called Person

myName := Person.Name;

To update the name:

person.Name := 'Bob';

So this is much more intuitive that writing SQL and less error prone.
It has also a lot more to offer like:

  • OCL that is a side effect free (readonly) query language invented by IBM.
  • Derived members to calculate links and values automatically when needed.
  • The algorithm can be implemented in OCL or in Delphi code.
  • As no direct SQL is used switch database is often painless. Bold framework use only basic SQL for DB communication.
  • GUI is automatically updated. Bold components that show values is automatically updated whenever value in database is changed. This is even true in a multiuser environment. One user can make a change, one second later all other clients is updated with new value. Bold do all the work behind with the service (OSS Object Synchronization Service).
  • For those that have bought Devexpress VCL components there is a separate repository that adapt the components for Bold. Result is a much modern look & feel and Bolds features.

More information about Bold in wikipedia or just ask me.

Latest official release of Bold was in Delphi 7 Architect.
There is also an unofficial version for D2006 (and D2007 as they are binary compatible).
But after this Borland, CodeGear and Embarcadero have been quiet about Bold.
And this left many customers behind that hope for updates. I think many developers left Delphi because of this. 

The future ?
But Bold has been actively developed for those that have the source. My company is an example of that. We have fixed both bugs, optimized it and add more features. We love the idea of Bold as open source. But Embarcadero owns the IP, so we must have their explicit permission before we publish anything. Bold has shown the strength in our case as it is been used in production since 2003.

I restarted the dialog with Embarcadero again about Bold as open source. 

What can you do ?
So what we want to know is this:

  1. What are the interests for Bold now ?
  2. So if Bold was opensource, compatible with Delphi Berlin and actively developed, what are the chances you upgrade to latest Delphi ? Would you buy several licenses ?
  3. Does it matters if Bold is true open source developed independently. Or is it better to have same state as VCL ? Then the source is maintained by Embarcadero and shipped with the Delphi installation.

Please answer if you have the slightest interests to use Bold in the future for your applications with all those amazing features I listed above.
You make no promises. We just want to investigate the interests.

Comments, questions is encouraged!

Wednesday, September 16, 2015

Boldified component suite from Devexpress

It have been a while since I wrote something. Now I have the pleasure to announce that Daniel Mauric released his boldified DevExpress components as open source. They are stored at

Attracs have used some of the components for several years in production. But of course no warranty that it works perfect .

I want to point out that the grid is very useful component to have boldified. it combine the advantage of the original Boldgrid with a moden look & feel of the Devexpress grid. And a lot of features of course.
This is how to set it up:

  • Add a TcxGrid component on the form.
  • Select the TcxGridLevel with Right mouse button and choose Create View/Bold Table.
  • Delete the default TcxGridDBTableView component.
  • Decide a name for the grid for example Users. Rename the TcxGrid to grdUsers, TcxGridLevel to lvUsers, TcxGridBoldTableView to tvUsers.
  • Set property tvUsers.OptionsView.ColumnAutoWidth to True unless there are many columns so each column became very thin.
  • Add a BoldListHandle to the form and set the OCL expression for that.
  • Connect the grids Bold Table view DataController.BoldHandle to the BoldListHandle above.
  • Add columns and set OCL expressions for the column at DataBinding.BoldProperties.Expression property.
  • Inspect the columns so each column got a reasonable name. It should begin with col.
  • In general avoid things like formatdatetime, round, orderby etc in the columns OCL expression.
    Note When dealing with dates, floats, integers as string sorting is not working good anymore. It only works if the grid know the actual datatype. Things like default sorting and formatting can be done in the grid instead. Also avoid this kind of OCL if islocalAdmin then 'X' else '' endif. In this case isLocalAdmin is enough and let the grid display is as a boolean checkbox. Note:  See Boolean string representation for a column when the grid is used for editing.
  • If the grid is readonly then set property OptionsData.Editing to False of the view. If only some of the columns are readonly then set views OptionsData.Editing to True and then decide at the columns Options.editing property.
  • The views OptionsSelection.CellSelect can be set to False of you want to select only a whole row.
All controls implement IBoldValidateableComponent which means they can be validated at design time Bold menu/Validate Current Form.

And you must of course have  installed the original VCL DevExpress components to make use of this. Currently we use version 14.2.3. Version 15 have dropped support for Delphi 2007 and this is the latest version that Bold support. So we have to stay here until we add Unicode support to Bold and upgrade Delphi.

An example of boldified DevExpress grid

Saturday, May 30, 2015

New features in Attracs Bold

It is very easy to believe that Bold for Delphi is dead and the best action is to leave Delphi and just port your existing applications to some other platforms like C#.

I would like to inform that Attracs version of Bold is very actively developed.
Beside all small bug fixes and changes this is some bigger improvements.
Thanks to our skilled consultants that made it possible.

You do not need to call DefaultSubscribe in derived code. Bold handle that automatically resulting in cleaner code.

No hash lookup for datatypes
Internally Bold now call hash lookups for datatypes. This is fast but when done frequently the time will add up. Attracs version use hardcoded datatypes instead as this changes very seldom or never. Together with some other optimization Bold can now handle about twice as many objects per second.

Developer Express grid and editors is boldaware
Not much to say about that. Much nicer components than the original in Bold

Caching of OCL result
Boldaware components evaluate OCL expressions when size of component is changed. For grids this is done for all cells. Using a cache is more effective.

Spanfetch avoid lazyfetch
In Bold it is very easy to trigger a lazy fetch of data. This means that one SQL statement is generated each time data is needed. This can be merged to one final SQL per table that is more effective. So this means a parsing of OCL and calculate the most effective SQL from that. Now there is even support for OCL variables but still a bit unstable. A very powerful and complicated addition to Bold.

When you have a many Bold-handles on a form it is easy to make a mess. Viewmodel is a new component that collect the handles in a nice treeview. It have also some other features so very little code is required on forms. In some cases no code at all. Less code also means less chances for bugs.

This is the latest feature. Usually we log to a plain text-file. But that means a lot of information is lost. Because then we need to parse raw text to get information like performance, frequency of events, exceptions etc. Log to a database is better because it is more structured. Data is saved on the proper place.
This also means we can log more as it is easy to find data with SQL and diskspace is cheap. We log all user actions to a database by intercept events also from timers etc. We can also log all modifications of objects. The log can contain time, user, value etc. Hopefully this means much better chance to reproduce those random bugs in live environment.