Commit 6b03c4c2 authored by zYne's avatar zYne

some docs for CTI

parent 10d1ff97
......@@ -337,11 +337,12 @@ Now if we access for example the friends of John Beer it would return one user '
++ Inheritance
+++ One table, many classes
When it comes to handling inheritance Doctrine is very smart. In the following example we have one database table called {{entity}}. Users and groups are both entities and they share the same database table. The only thing we have to make is 3 records ({{Entity}}, {{Group}} and {{User}}).
Doctrine supports 4 types of inheritance strategies which can be mixed together.
Doctrine is smart enough to know that the inheritance type here is one-table-many-classes.
+++ Simple inheritance
Simple inheritance is the simpliest inheritance. In simple inheritance all the child classes share the same columns as the parent.
<code type="php">
class Entity extends Doctrine_Record
......@@ -362,10 +363,100 @@ class Group extends Entity
{ }
</code>
+++ Class table inheritance
Class table inheritance is the basic inheritance type, yet its internally the most complex one. Class table inheritance allows the child classes to have additional columns compared with the parent.
Internally the parent and the child classes are stored in separate tables, with parent and children containing only their own distinct columns and the shared primary key column(s).
Consider the following class definition.
<code type="php">
class Entity extends Doctrine_Record
{
public function setTableDefinition()
{
$this->hasColumn('name', 'string', 100);
}
}
class User extends Entity
{
public function setTableDefinition()
{
$this->hasColumn('age', 'integer', 2);
$this->hasColumn('password', 'string', 16);
}
}
</code>
When class 'User' is being exported into mysql database Doctrine would issue the following queries:
<code>
CREATE TABLE entity (id INT NOT NULL AUTO_INCREMENT, name VARCHAR(100), PRIMARY KEY(id))
CREATE TABLE user (id INT NOT NULL, age INT, password VARCHAR(16), PRIMARY KEY(id))
</code>
Notice how only the parent has the auto-incremented id column. When no primary keys are set for the entire inheritance tree this is the default strategy Doctrine uses. When setting the primary keys manually all classes in the inheritance tree should share the same primary key definition, with the exception of autoinc/sequential primary key. In class table inheritance only the tree root can contain autoinc/sequential pk .
Whenever you fetch data with DQL from a class that uses class table inheritance, Doctrine is smart enough to produce the necessary joins. Lets say we want to fetch all users with their name starting with letter A.
<code type="php">
$q = new Doctrine_Query();
$users = $q->from('User u')->where("u.name LIKE 'A%'")->execute();
</code>
Now Doctrine would issue the following query:
<code>
SELECT ... FROM user u LEFT JOIN entity e ON u.id = e.id WHERE u.name LIKE 'A%'
</code>
Doctrine also knows how to perform other operations as multi-table operations. Creating and saving a new user will actually execute two INSERT statements as seen above. Notice how Doctrine is smart enough to attach the newly created entity id for the user record.
<code type="php">
$user = new User();
$user->age = 13;
$user->password = 'secret';
$user->name = 'someone';
$user->save();
</code>
Executes:
<code>
INSERT INTO entity (name) VALUES ('someone')
INSERT INTO user (id, age, password) VALUES (1, 13, 'secret')
</code>
The updates and deletes are also performed to span accross multiple tables. Consider the following example:
<code type="php">
$user->age = 14;
$user->password = 'newpassword';
$user->name = 'newname';
$user->save();
$user->delete();
</code>
The example would execute the following statements:
<code>
UPDATE entity SET name = 'newname' WHERE id = 1
UPDATE user SET age = 14, password = 'newpassword' WHERE id = 1
DELETE FROM entity WHERE id = 1
DELETE FROM user WHERE id = 1
</code>
+++ One table, one class
One-table-one-class inheritance is the only inheritance type that allows additional fields for inherited classes. As shown in the example above adding additional columns is very easy:
+++ Concrete inheritance
Concrete inheritance is similar to class table inheritance in a way that it creates separate tables for child classes. However in concrete inheritance each class generates a table which contains all columns (including inherited columns). In order to use concrete inheritance instead of the default class table inheritance you'll need to add explicit parent::setTableDefinition() calls to child classes as shown above.
<code type="php">
class TextItem extends Doctrine_Record
......@@ -388,7 +479,7 @@ class Comment extends TextItem
</code>
In one-table-one-class inheritance you don't necessarily have to define additional columns, but in order to make Doctrine create separate tables for each class you'll have to make iterative setTableDefinition() calls.
In concrete inheritance you don't necessarily have to define additional columns, but in order to make Doctrine create separate tables for each class you'll have to make iterative setTableDefinition() calls.
In the following example we have three database tables called {{entity}}, {{user}} and {{group}}. Users and groups are both entities. The only thing we have to do is write 3 classes ({{Entity}}, {{Group}} and {{User}}) and make iterative {{setTableDefinition}} method calls.
......@@ -425,8 +516,10 @@ class Group extends Entity
}
</code>
Even though concrete inheritance duplicates schema definitions its in many cases much better inheritance strategy to use than class table inheritance. In class table inheritance an inheritance tree of depth N uses N number of joins for SELECTs and executes N number of statements for each manipulation operation whereas in concrete inheritance every operation can be invoked by single statement.
+++ Column aggregation
+++ Column aggregation inheritance
In the following example we have one database table called {{entity}}. Users and groups are both entities and they share the same database table.
......@@ -449,8 +542,8 @@ class Entity extends Doctrine_Record
// aggregation inheritance
$this->hasColumn('type', 'integer', 11);
$this->setSubclasses(array(
"User" => array("type" => 1),
"Group" => array("type" => 2)
'User' => array('type' => 1),
'Group' => array('type' => 2)
));
}
}
......@@ -478,11 +571,11 @@ $group->password = 'password';
$group->save();
$q = new Doctrine_Query();
$user = $q->from('Entity')->where('id=?')->execute(array($user->id))->getFirst();
$user = $q->from('Entity')->where('id = ?')->fetchOne(array($user->id));
assert($user instanceOf User);
$q = new Doctrine_Query();
$group = $q->from('Entity')->where('id=?')->execute(array($group->id))->getFirst();
$group = $q->from('Entity')->where('id = ?')->fetchOne(array($group->id));
assert($group instanceOf Group);
</code>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment