Commit 1b979ff9 authored by zYne's avatar zYne

--no commit message

--no commit message
parent b5754f10
++++ One-To-One
Binding One-To-One foreign key associations is done with {{Doctrine_Record::ownsOne()}} and {{Doctrine_Record::hasOne()}} methods. In the following example user owns one email and has one address. So the relationship between user and email is one-to-one composite. The relationship between user and address is one-to-one aggregate.
The {{Email}} component here is mapped to {{User}} component's column {{email_id}} hence their relation is called LOCALKEY relation. On the other hand the {{Address}} component is mapped to {{User}} by it's {{user_id}} column hence the relation between {{User}} and {{Address}} is called FOREIGNKEY relation.
<code type="php">
class User extends Doctrine_Record {
public function setUp() {
$this->hasOne('Address','Address.user_id');
$this->ownsOne('Email','User.email_id');
$this->ownsMany('Phonenumber','Phonenumber.user_id');
}
public function setTableDefinition() {
$this->hasColumn('name','string',50);
$this->hasColumn('loginname','string',20);
$this->hasColumn('password','string',16);
// foreign key column for email ID
$this->hasColumn('email_id','integer');
}
}
class Email extends Doctrine_Record {
public function setTableDefinition() {
$this->hasColumn('address','string',150);
}
}
class Address extends Doctrine_Record {
public function setTableDefinition() {
$this->hasColumn('street','string',50);
$this->hasColumn('user_id','integer');
}
}
</code>
++++ One-to-Many, Many-to-One
<code type="php">
class User extends Doctrine_Record {
public function setUp() {
$this->ownsMany('Phonenumber','Phonenumber.user_id');
}
public function setTableDefinition() {
$this->hasColumn('name','string',50);
$this->hasColumn('loginname','string',20);
$this->hasColumn('password','string',16);
}
}
class Phonenumber extends Doctrine_Record {
public function setTableDefinition() {
$this->hasColumn('phonenumber','string',50);
$this->hasColumn('user_id','integer');
}
}
</code>
++++ Tree structure
<code type="php">
class Task extends Doctrine_Record {
public function setUp() {
$this->hasOne('Task as Parent','Task.parent_id');
$this->hasMany('Task as Subtask','Subtask.parent_id');
}
public function setTableDefinition() {
$this->hasColumn('name','string',100);
$this->hasColumn('parent_id','integer');
}
}
</code>
++++ Introduction
A foreign key constraint specifies that the values in a column (or a group of columns) must match the values appearing in some row of another table. In other words foreign key constraints maintain the referential integrity between two related tables.
Say you have the product table with the following definition:
<code type='php'>
class Product extends Doctrine_Record
{
public function setTableDefinition()
{
$this->hasColumn('id', 'integer', null, 'primary');
$this->hasColumn('name', 'string');
$this->hasColumn('price', 'decimal', 18);
}
}
</code>
Let's also assume you have a table storing orders of those products. We want to ensure that the order table only contains orders of products that actually exist. So we define a foreign key constraint in the orders table that references the products table:
<code type='php'>
class Order extends Doctrine_Record
{
public function setTableDefinition()
{
$this->hasColumn('order_id', 'integer', null, 'primary');
$this->hasColumn('product_id', 'integer');
$this->hasColumn('quantity', 'integer');
}
public function setUp()
{
$this->hasOne('Product', 'Order.product_id');
// foreign key columns should *always* have indexes
$this->index('product_id', array('fields' => 'product_id'));
}
}
</code>
When exported the class {{Order}} would execute the following SQL:
<code type="sql">
CREATE TABLE orders (
order_id integer PRIMARY KEY,
product_id integer REFERENCES products (id),
quantity integer,
INDEX product_id_idx (product_id)
)
</code>
Now it is impossible to create orders with product_no entries that do not appear in the products table.
We say that in this situation the orders table is the referencing table and the products table is the referenced table. Similarly, there are referencing and referenced columns.
++++ Constraint actions
//CASCADE//:
Delete or update the row from the parent table and automatically delete or update the matching rows in the child table. Both ON DELETE CASCADE and ON UPDATE CASCADE are supported. Between two tables, you should not define several ON UPDATE CASCADE clauses that act on the same column in the parent table or in the child table.
//SET NULL// :
Delete or update the row from the parent table and set the foreign key column or columns in the child table to NULL. This is valid only if the foreign key columns do not have the NOT NULL qualifier specified. Both ON DELETE SET NULL and ON UPDATE SET NULL clauses are supported.
//NO ACTION// :
In standard SQL, NO ACTION means no action in the sense that an attempt to delete or update a primary key value is not allowed to proceed if there is a related foreign key value in the referenced table.
//RESTRICT// :
Rejects the delete or update operation for the parent table. NO ACTION and RESTRICT are the same as omitting the ON DELETE or ON UPDATE clause.
//SET DEFAULT// :
In the following example we define two classes, User and Phonenumber with their relation being one-to-many. We also add a foreign key constraint with onDelete cascade action.
<code type='php'>
class User extends Doctrine_Record
{
public function setUp()
{
$this->hasMany('Phonenumber', 'Phonenumber.user_id', array('onDelete' => 'cascade'));
}
public function setTableDefinition()
{
$this->hasColumn('name', 'string', 50);
$this->hasColumn('loginname', 'string', 20);
$this->hasColumn('password', 'string', 16);
}
}
class Phonenumber extends Doctrine_Record
{
public function setTableDefinition()
{
$this->hasColumn('phonenumber', 'string', 50);
$this->hasColumn('user_id', 'integer');
}
}
</code>
++++ One-to-One
++++ One-to-Many, Many-to-One
++++ Many-to-Many
If you are coming from relational database background it may be familiar to you how many-to-many associations are handled: an additional association table is needed.
In many-to-many relations the relation between the two components is always an aggregate relation and the association table is owned by both ends. For example in the case of users and groups when user is being deleted the groups it belongs to are not being deleted and the associations between this user and the groups it belongs to are being deleted.
Sometimes you may not want that association table rows are being deleted when user / group is being deleted. You can override this behoviour by setting the relations to association component (in this case {{Groupuser}}) explicitly.
In the following example we have Groups and Users of which relation is defined as many-to-many. In this case we also need to define an additional class called {{Groupuser}}.
<code type="php">
class User extends Doctrine_Record {
public function setUp() {
$this->hasMany('Group','Groupuser.group_id');
}
public function setTableDefinition() {
$this->hasColumn('name','string',30);
}
}
class Group extends Doctrine_Record {
public function setUp() {
$this->hasMany('User','Groupuser.user_id');
}
public function setTableDefinition() {
$this->hasColumn('name','string',30);
}
}
class Groupuser extends Doctrine_Record {
public function setTableDefinition() {
$this->hasColumn('user_id','integer');
$this->hasColumn('group_id','integer');
}
}
$user = new User();
// add two groups
$user->Group[0]->name = 'First Group';
$user->Group[1]->name = 'Second Group';
// save changes into database
$user->save();
// deleting the associations between user and groups it belongs to
$user->Groupuser->delete();
$groups = new Doctrine_Collection($conn->getTable('Group'));
$groups[0]->name = 'Third Group';
$groups[1]->name = 'Fourth Group';
$user->Group[2] = $groups[0];
// $user will now have 3 groups
$user->Group = $groups;
// $user will now have two groups 'Third Group' and 'Fourth Group'
</code>
++++ Self-referencing
Self-referencing with join tables is done as follows:
<code type="php">
class User extends Doctrine_Record {
public function setUp() {
$this->hasMany('User as Friend','UserReference.user_id-user_id2');
}
public function setTableDefinition() {
$this->hasColumn('name','string',30);
}
}
class UserReference extends Doctrine_Record {
public function setTableDefinition() {
$this->hasColumn('user_id','integer');
$this->hasColumn('user_id2','integer');
}
}
</code>
......@@ -11,61 +11,76 @@ In the following example we make a user management system where
# When an entity is updated a current timestamp will be assigned to 'updated' field
# Entities will always be fetched in batches
<code type="php">
class Entity extends Doctrine_Record {
public function setUp() {
$this->ownsOne("Email","Entity.email_id");
$this->ownsMany("Phonenumber","Phonenumber.entity_id");
$this->setAttribute(Doctrine::ATTR_FETCHMODE,Doctrine::FETCH_BATCH);
$this->setAttribute(Doctrine::ATTR_LISTENER,new EntityListener());
<code type='php'>
class Entity extends Doctrine_Record
{
public function setUp()
{
$this->ownsOne('Email', 'Entity.email_id');
$this->ownsMany('Phonenumber', 'Phonenumber.entity_id');
$this->setAttribute(Doctrine::ATTR_LISTENER, new EntityListener());
}
public function setTableDefinition() {
$this->hasColumn("name","string",50);
$this->hasColumn("loginname","string",20);
$this->hasColumn("password","string",16);
$this->hasColumn("type","integer",1);
$this->hasColumn("created","integer",11);
$this->hasColumn("updated","integer",11);
$this->hasColumn("email_id","integer");
public function setTableDefinition()
{
$this->hasColumn('name', 'string', 50);
$this->hasColumn('loginname', 'string', 20);
$this->hasColumn('password', 'string', 16);
}
}
class Group extends Entity {
public function setUp() {
</code>
yep class Group extends Entity
{
public function setUp()
{
parent::setUp();
$this->hasMany("User","Groupuser.user_id");
$this->setInheritanceMap(array("type"=>1));
$this->hasMany('User', 'Groupuser.user_id');
$this->setInheritanceMap(array('type'=>1));
}
}
class User extends Entity {
public function setUp() {
class User extends Entity
{
public function setUp()
{
parent::setUp();
$this->hasMany("Group","Groupuser.group_id");
$this->setInheritanceMap(array("type"=>0));
$this->hasMany('Group', 'Groupuser.group_id');
$this->setInheritanceMap(array('type'=>0));
}
}
class Groupuser extends Doctrine_Record {
public function setTableDefinition() {
$this->hasColumn("group_id","integer");
$this->hasColumn("user_id","integer");
class Groupuser extends Doctrine_Record
{
public function setTableDefinition()
{
$this->hasColumn('group_id', 'integer');
$this->hasColumn('user_id', 'integer');
}
}
class Phonenumber extends Doctrine_Record {
public function setTableDefinition() {
$this->hasColumn("phonenumber","string",20);
$this->hasColumn("entity_id","integer");
class Phonenumber extends Doctrine_Record
{
public function setTableDefinition()
{
$this->hasColumn('phonenumber', 'string', 20);
$this->hasColumn('entity_id', 'integer');
}
}
class Email extends Doctrine_Record {
public function setTableDefinition() {
$this->hasColumn("address","string",150,"email|unique");
class Email extends Doctrine_Record
{
public function setTableDefinition()
{
$this->hasColumn('address', 'string', 150, 'email|unique');
}
}
class EntityListener extends Doctrine_EventListener {
public function onPreUpdate(Doctrine_Record $record) {
class EntityListener extends Doctrine_EventListener
{
public function onPreUpdate(Doctrine_Record $record)
{
$record->updated = time();
}
public function onPreInsert(Doctrine_Record $record) {
public function onPreInsert(Doctrine_Record $record)
{
$record->created = time();
}
}
......@@ -74,18 +89,17 @@ class EntityListener extends Doctrine_EventListener {
$manager = Doctrine_Manager::getInstance();
$conn = $manager->openConnection(new PDO("DSN","username","password"));
$conn = $manager->openConnection(new PDO('DSN','username','password'));
$user = new User();
$user->name = "Jack Daniels";
$user->Email->address = "jackdaniels@drinkmore.info";
$user->Phonenumber[0]->phonenumber = "123 123";
$user->Phonenumber[1]->phonenumber = "133 133";
$user->name = 'Jack Daniels';
$user->Email->address = 'jackdaniels@drinkmore.info';
$user->Phonenumber[0]->phonenumber = '123 123';
$user->Phonenumber[1]->phonenumber = '133 133';
$user->save();
$user->Group[0]->name = "beer lovers";
$user->Group[0]->Email->address = "beerlovers@drinkmore.info";
$user->Group[0]->name = 'beer lovers';
$user->Group[0]->Email->address = 'beerlovers@drinkmore.info';
$user->Group[0]->save();
</code>
+ Getting started
+ Connection management
+ Object relational mapping
+ Mapping relations
+ Working with objects
+ Configuration
+ Advanced components
......
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