Previous: Code Generation - the backbone of QCubedUp: Getting Started Index | Next: Understanding the Generated Code - Form and Panel Drafts?


Ah, the generated ORM. The generated ORM files created by QCubed are easily enough to make QCubed worth it even they were the only thing QCubed did. And the fantastic thing about QCubed is that if you wanted to act like that was the case, you could. You could ENTIRELY ignore the other generated files and the visual control aspects and strictly use the ORM files to connect to your database; the framework's flexibility gives that option. Of course, in reviewing the rest of QCubed and seeing all it has to offer, you will probably decide against such an endeavor, but it may give some comfort to know the option is there. You are never locked into using oly QCubed for your project because you can choose the pieces you like and discard the others. Options and choice are good.

It is possible that you are sitting there asking, What is ORM? Well, look it up, slacker. Just kidding. I will tell you. Like many self-taught web developers, before I was introduced to QCubed and frameworks in general, I didn't know what ORM was either.

ORM stands for Object Relational Model. Essentially, the ORM is a map between the database you choose and the objects you will use in QCubed. In our case, the database is MySQL, but as I have said, you can choose other databases. The ORM allows us all to use the same objects independently of our chosen database. We can all use the same access methods, creating cross-language harmony and furthering our progress towards celestial alignment and a world utopia. Well, maybe not all of that, but the concept is still pretty neat.

Now, let us move on to QCubed's ORM. Unlike some other frameworks, Qcubed creates a file for each table for its ORM. There are some other frameworks that do a similar thing, but there are also quite a few that choose to create individual table access dynamically. That is, these frameworks have a general database access class that, at runtime, extends itself for the needed tables. QCubed takes a different route. Instead of runtime creation, the code generation process of QCubed creates files with the classes for each table. As you may surmise, this leads to less overhead during runtime because QCubed will not have to perform database analysis and class creation. Other frameworks alleviate this with caching, but they still possess overhead that QCubed does not.

Generated database classes also give you the advantage of being able to see how the database is accessed. Instead of a layer of abstraction, you can see the access code directly. Moreover, you can extend it with methods of your own.

So now that I have finished my salesman pitch, let's get into the meat of this QCubed ORM stuff. In order to do that, we will look at one table class: person.

You may recall that the person table had three fields. Three is the number of fields there shall be. If you count four, you have gone too far and five is right out. One and two are too few, so the number shall be three. Those three fields are called id, name, and age. Now, if you are sitting there (or standing, if you like to use the computer that way) and wonder what this person table is that I am writing about, you may want to go back to the previous section and take a gander. Go ahead. But don't think I am going to wait. This is text so I really don't have to.

Now then, aside from these three fields, you may recall that two other tables reference the person id. There is the telephone table that uses a person id as a foreign key and a person-hobby association table which has both a hobby name and a person id as foreign keys. Keep that in mind for now, because the QCubed ORM does some nifty stuff with those relationships. For now though, let's start with the very basics: loading. As you create your various applications, you will undoubtedly be wanting to load data. If not, you probably don't need this framework. So I will assume you do. After all, you are reading this, right? Here is a basic way to load all the people in the person table.

$objPersonArray = Person::LoadAll();

That should be pretty easy to understand. The above statement is loading all the records of the person table into an array of Person objects. As a sidebar, take note of the way I wrote the variable name. This conforms to QCubed coding standards. For your own code, it is not a requirement, but it is definitely recommended. Not only does it encourage readability but it keeps a uniform look between your code and the QCubed code. For further reading, check out the wiki entry: QCubed Coding Standard. Keep in mind that it is currently still in draft form and is subject to change. But, if you look at the source code for the framework, you will find most, if not all of it, being used.

Now, lets take a look at other ways to load person data. First, let's load by an id.

$objPerson = Person::Load(1);     //loading the person with id of 1

Simple, right? Since id is a primary key of person, the basic load method will find the person record with the id given. There is also another method that does the same thing called LoadById. The reason this method is here is because since id is also an index (a primary key is a type of index), QCubed makes a method to load using it. This works with any index. In fact, age is an indexed column. And being that, it gets its own load method. Lucky field!

$objPersonArray = Person::LoadArrayByAge(25);

The method above loads all the people who are 25. Unlike the primary key, the age index is just your standard index; it does not have to be unique. That means that QCubed has to load all the records that apply. Of course, you can define an index to be unique. If age were indeed unique, the method would be LoadByAge since it could only find one possible record.

This index stuff is a nice segue nicely into the next load method. Remember how the hobby table is associated with the person table in person_hobby_assn? Well, since the table has the suffix of assn QCubed provides special method here as well that will allow you to get all people who have a particular hobby.

$objPersonArray = Person::LoadArrayByHobby('skydiving');

So, built right into the ORM code generation is a multitude of ways to get the data you need. It uses indexes and relationships inherent in your database to create some very useful loading methods. But wait! There's more!

Because person is associated with hobby and telephone, you have have access to those records using person. You can load the arrays of hobbies and phone numbers quite easily

$objPerson = Person::Load(1);
$objHobbyArray = $objPerson->GetHobbyArray();
$objTelephoneArray = $objPerson->GetTelephoneArray();

The first thing you will notice is that we are no longer using static methods. Instead, we are loading a user and then calling the methods needed using this user object. If we did not, the methods would not know which user's data to retrieve. Still very simple though. And in those three lines, you now have an array of this user's hobbies and all their related phone number.

You have noticed that I have not spent any time on property access and saving. And I am not going to be spending much time at all. This may be a let down since you probably wanted a lot of detail on something you will probably use quite frequently. But take a look and I think you will understand my choice. Here are how you access database fields, update them and save (there is also a delete method called...Delete()).

$objPerson = Person::Load(1);
$objPerson->Name = 'Tom';
$objPerson->Save();

Maybe now you can see why I am not going crazy with the explanation. It is easy. Load a person, reference a field using the name of said field, set it to something, call the save method. Done. Database updated. Time for coffee. The only thing I will point out is that you take notice of captilization. In the database, the field name is lower case. But here is it capitalize. QCubed will do this with all words in a field name. If your field name is favorite soup it will be referenced as FavoriteSoup. Keep that in mind, because proper case is important for field references in QCubed.

There are plenty of other methods that come with the ORM of a table in QCubed. There are counting methods, methods to associate a hobby or a telephone number to a person, and other functions you may be interested in. As this is just an introduction, I will leave you to peruse the code for the classes on your own. You can find them in includes/data_classes/generated within your project directory. I recommend using an IDE that will show you methods of a class as you type. It is an easy way to view all the possible methods without having to wade through code right away. Eclipse and Zend Studio (which is eclipsed-based) are two which do this.

I will leave you a reinforcement of the flexibility of QCubed. Sure, you say, QCubed provides me with all these lovely data classes, but what if what they have is STILL not enough? Never fear, young programmer! There is an answer. Since QCubed is open source, you can, if you like, change the very nature of the code generation to suit your needs. Alternatively, you can always add your own methods to a class. As you see above, I directed you to the generated directory. This is because the classes here have the bulk of the ORM methods. But in the parent directory, you will see the actual corresponding classes that you call when you need to access a table (Person instead of PersonGen). It is these files that you should modify. Unlike the code is the generated folder, these files WILL NOT be overwritten if you run the code generation again.

Say you decide that you are often interested in skydivers. So much so that you are tired of typing LoadArrayByHobby('skydiver'). Inside of Person.class.php, you could create a method called LoadSkydivers that is basically a wrapper for the LoadArrayByHobby method. And now this new method can be used in your application, saving your tender fingers from too much repetitive typing. And since you placed it in the Person class and not the PersonGen class, if you ever regenerate the code, the method will still be there. And the regeneration will still cause the Person class to reflect all the changes you made to the database.

Hopefully, this introduction has shown you the power and ease-of-use of QCubed's ORM. If not, then I have failed at my task and I hang my head in shame and despair But if you are still with me, go ahead and take a look at the next section about the rest of the generated code.


Previous: Code Generation - the backbone of QCubedUp: Getting Started Index | Next: Understanding the Generated Code - Form and Panel Drafts?