QCubed Modular ORM Support and Doctrine Integration

Login or register to post comments
12 replies [Last post]
cdhamm's picture
Offline
Joined: 05/09/2008

For those interested, I've done a bit of work integrating Doctrine with Qcubed and allowing the developer to choose their ORM. I haven't done a lot with it yet, but so far Doctrine integrates nicely with all the basic QControls, as well as QDatagrid and QDatarepeater. It's not much more than a proof of concept right now, but I'm hoping those community members interested in this feature will help contribute.

For those who don't know about Doctrine, it's one of the most mature ORM's around, and much better than QQuery. My intention was not to replace QQuery, but to allow the developer options when it comes to selecting an ORM. You can find out more about Doctrine at doctrine-project.com.

The code can be downloaded here

I've included a ReadMe file, as well as a couple example pages. Below is a code snippet from one example.

    public function Form_Create() {
      $this->dtgUser = new QDataGrid($this);
      $colUsername = new QDataGridColumn('Username', '<?= $_ITEM->username; ?>');
      $colUserType = new QDataGridColumn('User Type', '<?= $_ITEM->UserType->name; ?>');
      $this->dtgUser->AddColumn($colUsername);
      $this->dtgUser->AddColumn($colUserType);
      $this->dtgUser->SetDataBinder('dtgUser_Bind');
    }
   
    public function dtgUser_Bind() {
      $this->dtgUser->DataSource = Doctrine_Query::create()->from('User u')->leftJoin('u.UserType ut')->execute();
    }

    protected function btnSubmit_Click($strFormId, $strControlId, $strParameter) {
      $objUser = new User();
      $objUser->username = $this->txtUsername->Text;
      $objUser->user_type_id = $this->lstUserType->SelectedValue;
      $objUser->save();
     
      $this->txtUsername->Text = '';
      $this->dtgUser->Refresh();
    }

alex94040's picture
Offline
Joined: 11/06/2008

cdhamm, thank you very much, this is an extremely interesting contribution.

Can you do us a favor and please create a ticket and patch against QCubed, to allow folks to investigate this and play with it easily? It sounds like a very cool idea.

RKotenko's picture
Offline
Joined: 07/03/2008

Interesting idea. I wonder if this is something that the core of QCubed should support. My feelings is that, if added, this should an available addon.

QCubed is BASED on the idea that the ORM is not created at runtime, that hard-generated object mapping is better than a class that needs to parse out database info each time it is run: http://www.qcodo.com/documentation/article.php/6

And it is one the of the features I like a lot.

Now, I DID just only look at Doctrine in the last five minutes for the first time. :)

So, if it is not a runtime-built ORM, then my bad.

Like I said, it is cool to give choice, but I am not sure if it should be a built in feature or not since it takes away a MAJOR feature of QCubed.

alex94040's picture
Offline
Joined: 11/06/2008

I think our strength is in flexibility. For folks that are accustomed to Doctrine, a small plugin that enables the friendly syntax will go a long way to bring them into our community.

RKotenko's picture
Offline
Joined: 07/03/2008

Yes. A plugin is fine.

But I do not think this should be part of the core. The ORM and codegen are a MAJOR part of QCubed and were a major selling point to me.

If I wanted runtime ActiveRecords, I would have used Cake or something. :)

And yes, QCubed has a flexibility because you are not stuck in the framework; you can "break" out anytime and use regular PHP. But we must not lose the identity of the framework entirely by placing everything in the core. Codegen is a big part of that identity.

Not to mention it being just one more thing we have to support and keep updated.

All that being said, plugin away!

alex94040's picture
Offline
Joined: 11/06/2008

I should have been clearer.

We don't currently have plugin-like functionality on qcu.be. We don't have a forum / issue tracker / anything like that.

I think we should allow this contribution into the core - not as a replacement to QQuery, but as an alternate mechanism to perform SQL queries. Just like QCubed allows me to run a custom SQL statement, why not allow me to run Doctrine queries? It's a nice little abstraction for folks who are used to it - plus, it brings us closer to the ASP.NET LINQ world, opening our doors to more programmers.

If there's lots of demand, we can let it fork into a separate plugin project (when the infrastructure is available) or improve support.

cdhamm's picture
Offline
Joined: 05/09/2008

RKotenko, I appreciate your thoughts on this. fyi, Doctrine actually generates code a lot like QCubed. It is not a runtime examiner like Cake. You visit a codegen page when you update your database schema, and the filestructure is almost eerily similar to QCubed(there is a data classes folder full of classes that extend the generated classes, that are located inside a 'generated' folder).

Now, simply because Doctrine and QCubed are code generators with a lot of similarities, that in itself doesn't justify existence in the core. What I think should definitely be considered for the core, is the idea that QCubed does not force an ORM on the user:

Initially, my goal was to implement Doctrine so that both it and QQuery could be used simultaneously(i.e. you could, if you wanted, have a mix of QQuery functions and Doctrine queries). The issue I ran into is that both QCubed and Doctrine name their classes by converting database tables to Pascal case, so there were two class definitions for every table(for table 'user', QQuery created 'class User', as did Doctrine). Thus, Doctrine cannot be used at the same time as QQuery. This means that for any Doctrine plugin to work(unless this plugin would heavily modify the core), QCubed needs to support the ability to not force QQuery inclusion. At first glance, this might sound like a big deal. It's actually not. Once I get the code into SVN, you'll see the code changes made to the core are probably under 30 lines.

In terms of whether Doctrine itself belongs in the core, I completely agree it does not. In fact, I think it could work really well as a plugin, assuming the changes mentioned above were made.

Ultimately, it would be great if QCubed's ORM system used QQuery as the default, but with a simple installation to the 'includes' directory and a change to configuration.inc, any one of a number of different supported ORMs could be used. I've laid 'some' groundwork for this, modeling it after the way QCubed handles different database engines, but again its still just a proof-of-concept.

As Alex said, the core idea behind this is that a more flexible ORM system would:
a) Give more power to developers to use whichever ORM they are more comfortable with
b) Give people who subscribe to these other ORMs a reason to give QCubed a shot
c) Scare fewer people away who see QQuery for the first time and freak

I'll create a ticket tomorrow and post the link here.

enzo's picture
Offline
Joined: 03/31/2008

Hello cdhamm

I use Doctrine in the past with a project with zend, I'm not a big fan of doctrine but I guess the best approach could you do is:

1. Code your approach.
2. Create a patch
3. Create a sample site, in order to people check your approach before to install in this way could you sell better the idea to this new component will be include in the core.

I'm totally agree we need more need more option to try to become more popular

regards

enzo

cdhamm's picture
Offline
Joined: 05/09/2008

Ticket created here.

I attached the files that were changed to make the ORM system modular. If you want a working qcubed copy with this feature already integrated and examples to experiment with, use the link in my first post.

RKotenko's picture
Offline
Joined: 07/03/2008

cdhamm,

I was trying to configure doctrine just to see what it does. Well, it blew up my server trying to generate. :)

But from what I can gather from the tutorial, it does NOT create files similar to QCubed. It makes a shell class for each table, yes. But the access to fields and loading is done by a base database class; the table class is mostly for user-created function.

This is in contrast with QCubed where each table class has its own Load, , __get and __set and all of the db access.

Of course, since I cannot actually generate anything (can't figure out why it is crashing), perhaps you email me a zip of some generated files? I would greatly appreciate it so I can take a look at Doctrine in action.

cdhamm's picture
Offline
Joined: 05/09/2008

Egad, RKotenko, it crashed your server? That's interesting for an ORM that's considered to be quite stable.

Perhaps my post was misleading. I meant that conceptually, there's a lot of similarities. There are obviously going to be some major differences in their approach. To address one of your questions, getters and setters can be overridden, its just a bit different from QCubed:

class User extends BaseUser
{
    public function setPassword($password)
    {
        return $this->_set('password', md5($password));
    }
}

Now, I probably know about as much about Doctrine as you do at this point...I make no claim to be an expert. When I set about making this patch, I had 0 knowledge of it, other than it was highly regarded in many circles. My current understanding of Doctrine is that it does not do a runtime analysis of the database, and therefore like QCubed, does not incur the performance hits associated with Cake and the like.

Perhaps I should have split this into 2 different posts, since looking over the posts above, this comes off as a conversation about the viability of Doctrine, it's abilities, and whether it belongs in the core(there seems to be universal consensus that it does not). The important thing is, I think we agree that QCubed shouldn't force QQuery on the developer, and that we should allow support of other ORMs using a plugin model.

OOPMan's picture
Offline
Joined: 11/07/2008

RKotenko, if you examine any two given QQuery object classes you will find that roughly 75% of the code within any given file is shared with every other QQuery object class within the system.

This is not a good thing.

Code re-use exists for a reason.

Frankly, I prefer Doctrine to QQuery for conceptual reasons, even though I have not had the chance to actually use Doctrine (Our company works with QCodo primarily).

Simply put, Doctrine has a far cleaner, extensible, modular, OO design than QQuery. This is a good thing.

RKotenko's picture
Offline
Joined: 07/03/2008

I agree with you on the repetative code. And that can be remedied with a rework of the codegen.

I still don't really know how doctrine files are set up because I can't run them so I can't make too much of a comparison. But from what I have read, I think I still like QQuery.

To each their own. :)