3 – senCille MVC: ORM Generator & Tests.

What is ORM?

Object-relational mapping (ORM) is a mechanism that makes it possible to address, access and manipulate objects without having to consider how those objects relate to their data sources. ORM lets programmers maintain a consistent view of objects over time, even as the sources that deliver them change.

Each ORM object hides and encapsulates changes in the data source, so that when the data source changes, only the ORM needs to be changed to sync up. The applications that use the ORM are then insulated from additional change efforts.

You can read about ORM objects in many places on the Internet. ORM is not a Pattern, it’s actually a technique of managing database rows through an application. Because of this, we can combine ORM with MVC giving our architecture to a new level of abstraction.

The advantages of ORM usage

The main advantage of the use of ORM is the new level of abstraction from the Database representation of the objects. Many times we have an object that represented in a Database is composed of many entities with relationships, as an example an invoice with entities for the header and footer information, and the entity that contains the lines, related with the header by a “one to many relationship”. With ORM we can create an Object that abstracts this relationship and obtain from the database an object called TInvoiceOrm, which has a property Lines, consistent in a generic List of Items of type TInvoiceLineOrm.

We can solicit from a model layer, MyInvoice := FModel.GetInvoice(101); that returns an instance of type TInvoiceOrm that contains the lines encapsulated inside. We can call MyInvoice.Add(Line); and after, call a method Calculate. At last we can, for example, call FModel.SaveInvoice(MyInvoice); or FModel.UpdateInvoice(MyInvoice); or ignore all the changes making MyInvoice.Free;

As we are going to see in the next entries, there are a lot of additional advantages. The use of ORM with MVC provides us with the Magic part of this architecture. In my projects, I associate in a View, an ORM Object with each TreeViewItem. When the user Drags and Drops a TTreeViewItem between forms he is, literally, dragging and Object with all its properties…not a reference!  But this is part of the View. Now we are speaking about ORM.

Bitbucket

 

https://bitbucket.org/juanc_cilleruelo/sencillemvc

Remember that the Branch described in this entry is called scORM.

RepoORM

Repository

The ORM Generator

We introduce in this branch of code, the first tool. This is an external program that generates the ORM Classes that we need in our program.  As we can make this program’s classes independent of the Database used, ORMGenerator is based on the information contained in the TDataSets inside application DataModules.  Because of this, its important to generate the TFields of each Dataset at design time.

To accomplish this part, we have created in this episode all the Datamodules that we think are going to be required by the Application.

First version of Northwind application.

Northwind first

We now have the base version of the framework, and a Datamodule for each program module, and at last one ORM class for each one. We can organize these into different folders and construct the seed of our Northwind application.

The application at this point compiles and, if you run it, only shows a main form with no functionality. But in the next post we are going to see how all the pieces fit with the Model Layer.

The Tests!!!!

To complete our implementation of an architecture based on MVC pattern, we want to improve the construct process to accomplish a better final result. What could help produce a better result? I think that code without errors that demonstrates itself that all the functionalities have been proven and then protects these functionalities over the changes made over time.  This will produce better and trusted code!

To accomplish all these tasks, we count on help from Automated Unit Tests. These tests are part of our development process, and shall be maintained with the whole of our code. This tests can be executed every time we need to demonstrate that all the functionalities are implemented. If a functionality changes, we should change the tests conveniently as required.

Test first

Which parts of the code shall be covered by these types of Tests? My recommendation is clear: Each public method of each Controller and each Model shall have at least one Test.

These types of tests are going to be presented on the next post of this series. Here we present the tests that we will do for this first stage of the application.

If you check the project ORMTest, you can see three tests units:

SmokeTest_DM: contains a set of smoke tests over all Datamodules. Open each DataSet, insert a new item and post it. Edit an existing Item, which will be the current Item, and post it. Finally delete this item. With these tests, we assure a good connection to database for each Dataset, as well as the existence of the TFields at design time, etc.

SmokeTest_ORM: These are a group of very basic tests over each ORM Class in the application. These are similar to the DM tests, but oriented to the ORM Classes.

Test_CategoryORM: This is an almost complete battery of tests over the TCategoryORM class. In these tests, we try to demonstrate that each functionality of this class is created and runs correctly. (I recommend reviewing the code to understand all the tests, and at the same time, the functionality of each).

Why we don’t make a battery of tests like this last, over each ORMClass? Because it’s an automatically generated code!  If one of this classes works well, we can assure in the 99.99% of the time, that all the auto-generated classes are going to run with the same correctness.

That’s all at this moment!!!

Next entry of this series: The Model Layer.

 

Juan Carlos Cilleruelo

Randy Sill (Editor/Collaborator)

 

2 – senCille MVC: The Database & Stub.

The senCille MVC framework will start with a desktop application and the first thing we need is a Database with a lot of relationships and well know data.  After a little searching the internet, we found a script to create the well know Northwind Database.

Northwind has been part of MS-SQL Server since the very first versions. Currently, this sample database is not deployed with the product, but you can download it from Microsoft’s help site.

Next image is in a database diagram in A4 size which and can be downloaded, with the right button, as you know and printed if needed for reference.

Northwind

As said, this database was initially developed for MS-SQL Server. We are going to deploy a little Stub program to create the database and deploy it to the correct location, and after that, fill it with a good set of Data for our samples. But, as we don’t want limit the use of the application to MS-SQL Server, our first version is going to be for the Firebird embedded edition.

You can download a copy of the repository, (get a clone in git language), from the next repository.

Bitbucket

https://bitbucket.org/juanc_cilleruelo/sencillemvc

Remember that the Branch described in this post is called scStub.

If you select master, you will see the projects latest version, not in the version described here.

folder structure

The folder structure is simple. We have four folders. The Bin folder is the destination of the compiled project. When we build and deploy the project, we only use content from this folder. Inside the Bin folder, another bin folder holds all the necessary files to run FireBird Embedded databases. Including the required FireBird content is a courtesy to make this project easier to use and not require separate downloading and configuration.

The dcus folder is a throw away for all precompiled units. We want to maintain it in a separate folder to minimize complexity in the bin folder, but it is important.

The scFramework is the folder which will to hold the files of the framework. All the files in this folder will be common to all the projects we create. The name all of source files will be part of the namespace senCille.

Finally, the scStub folder is the first application project and is to be dedicated to managing of the Data.  We want to have a good base of examples that can be initialized at any time, and before of each unit test execution. This application creates the Database with the example Data used by the programs. This program shall be maintained along with rest of code. This foundation will help assure us the framework and programs are achieving  their targets.

Inside scStub, the program code is not very complicated. It includes a good example of the use of Delegates in Delphi (events), that if you understand, will be a good introduction to the manner of reaching Event handlers of each component of our Views through a Controller.

scFramework folderThis folder holds the first four files of our framework.

DBController is one of the base fundamental classes in our framework. Its simplicity should not confuse us. This class is used to connect with the physical database. In next version of the project we are going to modify it to allow connection to other types of databases, like MS-SQL Server, Oracle, Interbase, etc. For now, it will connect only with Firebird Embedded.

DBController encapsulates the connection to the database. Every time we create a Controller we are going to assign this DBController to it. When the Controller creates its corresponding Model class, it will use this object to establish the connection. This will allow us to assure that we only have one active connection all the time (very important in mobile apps working with IBLite or IBTogo databases), but this will assure too that, if we change the database of the project, this won’t have an impact on the controllers, because the DBController hides the physical Details of the connection.

In this first project, scStub, you can see a basic use of DBController.

SQLConnect.pas contains a nice helper class that will allow us to create Querys on the fly in our program. These queries are clean and in many cases independent of the Connection. In theory, the use of this class shall be restricted to the Model Layer.

Tools.pas is a library to place all the little tools that this framework will need. I think that this is an elegant form of mandating all the code inside classes.

Finally, DBRows.pas is the parent class of all the Row classes of our applications. This is not part of this first project, but is available to get a gimps of the framework to come.

When the Model communicates with the Controller and vice-versa, or when a Controller communicates with other Controllers, there are a lot of circumstances in which we need to pass the data of a Row in the Database. TDBRow descendant classes are the representation of a  DBRow in this situation.

But, this is part of a future post.

In the next post we will see how to create these classes.

 

Juan Carlos Cilleruelo

Randy Sill (Editor/Collaborator)

1 – senCille Desktop MVC (Delphi FMX FireDAC)

The objective:

The objective of this blog is to collaborate and develop a framework for Delphi based on the MVC Pattern – Model-View-Controller.

MVC AsenCille MVC is the name of this framework.

We’d like to make some promises at this moment. If the next sentences describe what you are searching, continue reading this blog. Oh and please, subscribe!

  1. The framework is going to be complete. No third party libraries or modules are going to be needed.
  2. The three layer separation is going to be complete. This is to say, you will be able to create the Model of each module and use it without the need of any Controller or View. If you create a Controller and it needs a Model, this will be part of the Controller’s initialization method. You don’t have to worry about the model creation. In the same way with the View, if a Controller needs a View to communicate with the humans, it will be created by itself.
  3. You are going to be able of change all the views of the program, as an example, for Mobile views you will not need to change the code of the models. The code of the controllers will need changed only for new components that need to be managed.
  4. You can change your database modifying only the Model Layer. This is a very important aspect of this framework.

What’s MVC.

You can read about MVC theory across a lot of sites on the internet, such as wikipedia: MVC in Wikipedia

If it exists an academic or pragmatic manner of implementing an MVC framework, it’s not what we are going to develop here. Our first Objective is take the fundamentals of MVC and implement it into our framework, but without the complexity of the purism. We of course want to provoke discussion and want to know how you or your team can improve the resultant framework. We are going to take into account all ideas, and if these innovations are good ones, we want to incorporate it to this framework.

What we consider the principles of MVC are:

  • A user interacts with the View.
  • The Controller handles the user input, and transfers the information to the model.
  • The Model receives the information and updates it’s state.
  • The View checks the state of the Model and responds accordingly.
  • The View waits for another interaction from the user.

Alternative paths for this interaction are:

  • The Controller creates a model for a lap of time, to accomplish his work, and after destroys it.
  • The Controller needs information or process from other controller, creates it, executes the correspondent methods and destroys it.
  • A Controller with, for example, a Master-Detail relationship needs two views and should be managed naturally.
  • A variation of the previous. The Controller needs a momentary view to show a message or question the user about anything (modal windows). The Controller can create another controller and wait for the result of one of his methods or can create and manage directly the new window.

The language selected for the development of this framework is Embarcadero Delphi #10Seattle. If you know about MVC, we need three layers to complete the design. We don’t know if the order of the letters is important or not, but our three layers are going to stay configured for the communication between them as V-C-M. The View or upper layer of the framework is developed with the Firemonkey (FMX) library of components. This is to allow the creation of modern applications that can be deployed on iOS, Android, Mac OS X, and Windows with only the changes in the design imposed by the user interface. The Controller layer is to be developed with Delphi. The bottom layer, the Model, is too developed with Delphi and contains an extra sub-layer. Each Model can have a DataModule. This does not mean that the system has four layers because the pair of files in a DataModule are part of the Model Layer of each application Module. In our next posts, we are going to see this in depth.

We want to complete the framework with a group of tools, that help the final developer in the construction tasks. This is not part of MVC, but I think that all the effort of implement MVC in a project will show its value when you see The Magic of the abilities that it will allow.

In the next post we are going to make public, the repository of the project and the tool to create the first version of the database for the samples.

 

Juan Carlos Cilleruelo

Randy Sill (Editor/Collaborator)