I’ve had a request for quite some time to provide an example of an eager load using hcOPF. Quite frankly it was never a high priority for me, because I could never see myself using it. That said, I like to think that hcOPF is a sufficiently flexible framework that it makes it easy for developers to do what they normally require, but still makes it possible for them to do unusual things.
One of the reasons why I like using an OPF (hcOPF in particular) is that it removes the tedious job of writing SQL CRUD (Create, Read, Update & Delete) operations. hcOPF currently generates all the SQL for CRUD operations dynamically using the MetaData the developer defines. I never worry about how to persist an object to the database any more, and to not use this functionality kind of defeats the purpose of using the framework. Nevertheless, I recognize that there are times in which a developer would rather call a stored procedure to load and save objects rather than leave the SQL generation up to the framework. Perhaps for security reasons, or in order to leverage some RDBMS feature such as MARS.
In any event, I decided to take up the challenge and write a unit test to demonstrate how to use a single SQL statement to load a result set and construct multiple objects from it. I will leave saving objects using stored procs for a future article. The code is located in the hcEagerLoad unit in the UnitTests folder.
The test is a descendant of ThcDBTestCase, which is based on the database test classes authored by Giacomo Degliesposti, who presented his test classes at DataRage and was kind enough to send me a copy of his source. Many thanks, as it helped get me started writing tests against a database which although slower than mocking it, is pretty much a necessity for a database centric framework.
ThcDBTestCase handles all the connectivity to the database for hcOPF and provides some handy methods for running database scripts. Any descendant just has to create any database records they will use for testing, and then create the corresponding objects in the Setup method. After crafting the actual test, the TearDown method simply has to free any objects created in the SetUp method.
Here, the actual TestEagerLoad method uses a single SQL statement to fetch all People with any associated Addresses. Using two nested loops, it Inserts new Person and Address objects into their respective lists, populating the object attributes from the query. Then the code informs hcOPF that the objects actually exist in the database using the ThcObject.ObjectExistsInStore method. This resets all the original values populated from the database when the object is initially read, with the current values, so the framework will build the correct SQL and populate the parameters properly for any modifications made to the objects from that point forward.
Note how hcOPF uses a similar construct to TFields in being able to access each attribute by it’s name (AttributeByName() method), but that it’s also possible to define the objects with indexed properties that access the underlying attributes directly using type specific getters and setters, or by using custom getters and setters. Either way, you can write anAddress.City or Person.LastName with full code insight.
Every new client project that I work on, just underlines the benefits of an OPF to me. Less SQL executed against the database, no business logic scattered throughout forms, and most importantly the ability to withstand change without the same kind of breakage (especially if you write unit tests). That’s just MHO, what’s yours?