I'm interested in some of the design behind Rails ActiveRecord, Doctrine for PHP (and similar ORMs).

  • How does an ORM manage to accomplish features like chained accessors and how deep are they typically expected to work?
  • How does an ORM construct queries internally?
  • How does an ORM manage the queries while sustaining the arbitrary nature of all that is expected of it?

Obviously this is an academic question, but all natures of answers are welcome!

(My language of choice is OO PHP5.3!)

Comments

Don't anthropomorphise computers. They don't like it.

Written by finnw

Accepted Answer

Chained method calls are orthogonal to the ORM question, they're used all over the place in OOP. A chain-able method simply returns a reference to the current object, allowing the return value to be called. In PHP

class A {
	public function b() {
		...
		return $this;
	}

	public function c($param) {
		...
		return $this;
	}		
}


$foo = new A();
$foo->b()->c('one');
// chaining is equivilant to
// $foo = $foo->b();
// $foo = $foo->c();

As for how queries are constructed, there are two methods. In ActiveRecord like ORMs there's code that examines the Database's meta-data. Most databases has some kind of SQL or SQL like commands to view this meta-data. (MySQL's DESCRIBE TABLE, Oracle's USER_TAB_COLUMNS table, etc.)

Some ORMs have you describe your database tables in a neutral language such as YAML. Others might infer a database structure from the way you've created your Object models (I want to say Django does this, but it's been a while since I looked at it). Finally there's a hybrid approach, where either of the previous two techniques are used, but a separate tool is provided to automatically generate the YAML/etc. or class files.

One the names and data-types of a table are known, it's pretty easy to pragmatically write a SQL query that returns all the rows, or a specific set of rows that meet a certain criteria.

As for your last question,

How does an ORM manage the queries while sustaining the arbitrary nature of all that is expected of it?

I'd argue the answer is "not very well". Once you move beyond the one-table, one-object metaphor, each ORM has a different approach an philosophy as to how SQL queries should be used to model objects. In the abstract though, it's just as simple as adding new methods that construct queries based on the assumptions of the ORM (i.e. Zend_Db_Table's "findManyToManyRowset" method)

Written by Alan Storm
This page was build to provide you fast access to the question and the direct accepted answer.
The content is written by members of the stackoverflow.com community.
It is licensed under cc-wiki