Commit 95bd6100 authored by doctrine's avatar doctrine

Manual added

parent a33e2b89
<?php
class MyListener extends Doctrine_EventListener {
public function onLoad(Doctrine_Record $record) {
print $record->getTable()->getComponentName()." just got loaded!";
}
public function onSave(Doctrine_Record $record) {
print "saved data access object!";
}
}
class MyListener2 extends Doctrine_EventListener {
public function onPreUpdate() {
try {
$record->set("updated",time());
} catch(InvalidKeyException $e) {
}
}
}
// setting global listener
$manager = Doctrine_Manager::getInstance();
$manager->setAttribute(Doctrine::ATTR_LISTENER,new MyListener());
// setting session level listener
$session = $manager->openSession($dbh);
$session->setAttribute(Doctrine::ATTR_LISTENER,new MyListener2());
// setting factory level listener
$table = $session->getTable("User");
$table->setAttribute(Doctrine::ATTR_LISTENER,new MyListener());
?>
<?php
interface iDoctrine_EventListener {
public function onLoad(Doctrine_Record $record);
public function onPreLoad(Doctrine_Record $record);
public function onUpdate(Doctrine_Record $record);
public function onPreUpdate(Doctrine_Record $record);
public function onCreate(Doctrine_Record $record);
public function onPreCreate(Doctrine_Record $record);
public function onSave(Doctrine_Record $record);
public function onPreSave(Doctrine_Record $record);
public function onInsert(Doctrine_Record $record);
public function onPreInsert(Doctrine_Record $record);
public function onDelete(Doctrine_Record $record);
public function onPreDelete(Doctrine_Record $record);
public function onEvict(Doctrine_Record $record);
public function onPreEvict(Doctrine_Record $record);
public function onSleep(Doctrine_Record $record);
public function onWakeUp(Doctrine_Record $record);
public function onClose(Doctrine_Session $session);
public function onPreClose(Doctrine_Session $session);
public function onOpen(Doctrine_Session $session);
public function onTransactionCommit(Doctrine_Session $session);
public function onPreTransactionCommit(Doctrine_Session $session);
public function onTransactionRollback(Doctrine_Session $session);
public function onPreTransactionRollback(Doctrine_Session $session);
public function onTransactionBegin(Doctrine_Session $session);
public function onPreTransactionBegin(Doctrine_Session $session);
public function onCollectionDelete(Doctrine_Collection $collection);
public function onPreCollectionDelete(Doctrine_Collection $collection);
}
?>
<?php
$table = $session->getTable("User");
$table->setEventListener(new MyListener2());
// retrieve user whose primary key is 2
$user = $table->find(2);
$user->name = "John Locke";
// update event will be listened and current time will be assigned to the field 'updated'
$user->save();
?>
<?php
$hook = new Doctrine_Hook($table, $fields);
?>
<?php
try {
$user->name = "this is an example of too long name";
$user->Email->address = "drink@@notvalid..";
$user->save();
} catch(Doctrine_Validator_Exception $e) {
$stack = $e->getErrorStack();
foreach($stack as $component => $err) {
foreach($err as $field => $type) {
switch($type):
case Doctrine_Validator::ERR_TYPE:
print $field." is not right type";
break;
case Doctrine_Validator::ERR_UNIQUE:
print $field." is not unique";
break;
case Doctrine_Validator::ERR_VALID:
print $field." is not valid";
break;
case Doctrine_Validator::ERR_LENGTH:
print $field." is too long";
break;
endswitch;
}
}
}
?>
<?php
// turning on validation
Doctrine_Manager::getInstance()->setAttribute(Doctrine::ATTR_VLD, true);
?>
<?php
class User extends Doctrine_Record {
public function setUp() {
$this->ownsOne("Email","User.email_id");
}
public function setTableDefinition() {
// no special validators used only types
// and lengths will be validated
$this->hasColumn("name","string",15);
$this->hasColumn("email_id","integer");
$this->hasColumn("created","integer",11);
}
}
class Email extends Doctrine_Record {
public function setTableDefinition() {
// specialized validators 'email' and 'unique' used
$this->hasColumn("address","string",150,"email|unique");
}
}
$session = Doctrine_Manager::getInstance()->openSession(new PDO("dsn","username","password"));
$user = new User();
$user->name = "this is an example of too long name";
$user->save(); // throws a Doctrine_Validator_Exception
$user->name = "valid name";
$user->created = "not valid"; // not valid type
$user->save(); // throws a Doctrine_Validator_Exception
$user->created = time();
$user->Email->address = "drink@.."; // not valid email address
$user->save(); // throws a Doctrine_Validator_Exception
$user->Email->address = "drink@drinkmore.info";
$user->save(); // saved
$user = $session->create("User");
$user->Email->address = "drink@drinkmore.info"; // not unique!
$user->save(); // throws a Doctrine_Validator_Exception
?>
<?php
$table = $session->getTable("User");
$users = $table->findAll();
// accessing elements with ArrayAccess interface
$users[0]->name = "Jack Daniels";
$users[1]->name = "John Locke";
// accessing elements with get()
print $users->get(1)->name;
?>
<?php
$users = $table->findAll();
print count($users); // 5
$users[5]->name = "new user 1";
$users[6]->name = "new user 2";
?>
<?php
// delete all users with name 'John'
$users = $table->findBySql("name LIKE '%John%'");
$users->delete();
?>
<?php
$table = $session->getTable("User");
$table->setAttribute(Doctrine::ATTR_FETCHMODE, Doctrine::FETCH_IMMEDIATE);
$users = $table->findAll();
// or
$users = $session->query("FROM User-I"); // immediate collection
foreach($users as $user) {
print $user->name;
}
$table->setAttribute(Doctrine::ATTR_FETCHMODE, Doctrine::FETCH_LAZY);
$users = $table->findAll();
// or
$users = $session->query("FROM User-L"); // lazy collection
foreach($users as $user) {
print $user->name;
}
$table->setAttribute(Doctrine::ATTR_FETCHMODE, Doctrine::FETCH_BATCH);
$users = $table->findAll();
// or
$users = $session->query("FROM User-B"); // batch collection
foreach($users as $user) {
print $user->name;
}
$table->setAttribute(Doctrine::ATTR_FETCHMODE, Doctrine::FETCH_OFFSET);
$users = $table->findAll();
// or
$users = $session->query("FROM User-O"); // offset collection
foreach($users as $user) {
print $user->name;
}
?>
<?php
$users = $table->findAll();
$users->count();
// or
count($users); // Doctrine_Collection implements Countable interface
?>
<?php
$users = $table->findAll();
$users[0]->name = "Jack Daniels";
$users[1]->name = "John Locke";
$users->save();
?>
<?php
// Doctrine_Manager controls all the sessions
$manager = Doctrine_Manager::getInstance();
// open first session
$session = $manager->openSession(new PDO("dsn","username","password"), "session 1");
// open second session
$session2 = $manager->openSession(new PDO("dsn2","username2","password2"), "session 2");
$manager->getCurrentSession(); // $session2
$manager->setCurrentSession("session 1");
$manager->getCurrentSession(); // $session
// iterating through sessions
foreach($manager as $session) {
}
?>
<?php
// Doctrine_Manager controls all the sessions
$manager = Doctrine_Manager::getInstance();
// Doctrine_Session
// a script may have multiple open sessions
// (= multiple database connections)
$dbh = new PDO("dsn","username","password");
$session = $manager->openSession();
// or if you want to use Doctrine Doctrine_DB and its
// performance monitoring capabilities
$dsn = "schema://username:password@dsn/dbname";
$dbh = Doctrine_DB::getConnection($dsn);
$session = $manager->openSession();
?>
<?php
$query->from("User")
->where("User.name = ?");
$query->execute(array('Jack Daniels'));
?>
<?php
// find all users
$coll = $session->query("FROM User");
// find all groups
$coll = $session->query("FROM Group");
// find all users and user emails
$coll = $session->query("FROM User, User.Email");
?>
<?php
// select all users and load the data directly (Immediate fetching strategy)
$coll = $session->query("FROM User-I");
// or
$coll = $session->query("FROM User-IMMEDIATE");
// select all users and load the data in batches
$coll = $session->query("FROM User-B");
// or
$coll = $session->query("FROM User-BATCH");
// select all user and use lazy fetching
$coll = $session->query("FROM User-L");
// or
$coll = $session->query("FROM User-LAZY");
?>
<?php
// find the first ten users and their emails
$coll = $session->query("FROM User, User.Email LIMIT 10");
// find the first ten users starting from the user number 5
$coll = $session->query("FROM User LIMIT 10 OFFSET 5");
?>
<?php
// retrieve all users with only their properties id and name loaded
$users = $session->query("FROM User(id, name)");
?>
<?php
$session = Doctrine_Manager::getInstance()->openSession(new PDO("dsn","username","password"));
$query = new Doctrine_Query($session);
$query->from("User-b")
->where("User.name LIKE 'Jack%'")
->orderby("User.created");
->limit(5);
$users = $query->execute();
?>
<?php
// find all users, sort by name descending
$coll = $session->query("FROM User ORDER BY User.name DESC");
// find all users sort by name ascending
$coll = $session->query("FROM User ORDER BY User.name ASC");
// or
$coll = $session->query("FROM User ORDER BY User.name");
// find all users and their emails, sort by email address
$coll = $session->query("FROM User, User.Email ORDER BY User.Email.address");
// find all users and their emails, sort by user name and email address
$coll = $session->query("FROM User, User.Email ORDER BY User.name, User.Email.address");
?>
<?php
$query->from("User:Email");
$query->execute();
// executed SQL query:
// SELECT ... FROM user INNER JOIN email ON ...
$query->from("User.Email");
$query->execute();
// executed SQL query:
// SELECT ... FROM user LEFT JOIN email ON ...
?>
<?php
// find all groups where the group primary key is bigger than 10
$coll = $session->query("FROM Group WHERE Group.id > 10");
// find all users where users where user name matches a regular expression,
// REGEXP keyword must be supported by the underlying database
$coll = $session->query("FROM User WHERE User.name REGEXP '[ad]'");
// find all users and their associated emails where SOME of the users phonenumbers
// (the association between user and phonenumber tables is Many-To-Many) starts with 123
$coll = $session->query("FROM User, User.Email WHERE User.Phonenumber.phonenumber LIKE '123%'");
// multiple conditions
$coll = $session->query("FROM User WHERE User.name LIKE '%Jack%' && User.Email.address LIKE '%@drinkmore.info'");
// nesting conditions
$coll = $session->query("FROM User WHERE (User.name LIKE '%Jack%' || User.name LIKE '%John%') && User.Email.address LIKE '%@drinkmore.info'");
?>
<?php
$query = new Doctrine_RawSql($session);
$query->select('{entity.name}')
->from('entity');
$query->addComponent("entity", "User");
$coll = $query->execute();
?>
<?php
$query = new Doctrine_RawSql($session);
$query->parseQuery("SELECT {entity.name} FROM entity");
$entities = $query->execute();
?>
<?php
$user = $table->find(3);
// access property through overloading
$name = $user->name;
// access property with get()
$name = $user->get("name");
// access property with ArrayAccess interface
$name = $user['name'];
// iterating through properties
foreach($user as $key => $value) {
}
?>
<?php
$user = $session->create("User");
// alternative way:
$table = $session->getTable("User");
$user = $table->create();
// the simpliest way:
$user = new User();
// records support array access
$user["name"] = "John Locke";
// save user into database
$user->save();
?>
<?php
$table = $session->getTable("User");
try {
$user = $table->find(2);
} catch(Doctrine_Find_Exception $e) {
print "Couldn't find user";
}
// deletes user and all related composite objects
$user->delete();
$users = $table->findAll();
// delete all users and their related composite objects
$users->delete();
?>
<?php
$state = $record->getState();
switch($state):
case Doctrine_Record::STATE_PROXY:
// data access object is in proxy state,
// meaning its persistent but not all of its properties are
// loaded from the database
break;
case Doctrine_Record::STATE_TCLEAN:
// data access object is transient clean,
// meaning its transient and
// none of its properties are changed
break;
case Doctrine_Record::STATE_TDIRTY:
// data access object is transient dirty,
// meaning its transient and
// some of its properties are changed
break;
case Doctrine_Record::STATE_DIRTY:
// data access object is dirty,
// meaning its persistent and
// some of its properties are changed
break;
case Doctrine_Record::STATE_CLEAN:
// data access object is clean,
// meaning its persistent and
// none of its properties are changed
break;
endswitch;
?>
<?php
$table = $session->getTable("User");
// find by primary key
try {
$user = $table->find(2);
} catch(Doctrine_Find_Exception $e) {
print "Couldn't find user";
}
// get all users
foreach($table->findAll() as $user) {
print $user->name;
}
// finding by sql
foreach($table->findBySql("name LIKE '%John%'") as $user) {
print $user->created;
}
// finding objects with DQL
$users = $session->query("FROM User WHERE User.name LIKE '%John%'");
?>
<?php
$string = serialize($user);
$user = unserialize($string);
?>
<?php
$table = $session->getTable("User");
try {
$user = $table->find(2);
} catch(Doctrine_Find_Exception $e) {
print "Couldn't find user";
}
$user->name = "Jack Daniels";
$user->save();
?>
<?php
$user = new User();
$user->name = "Jack";
$group = $session->create("Group");
$group->name = "Drinking Club";
// saves all the changed objects into database
$session->flush();
?>
<?php
$manager = Doctrine_Manager::getInstance();
// open new session
$session = $manager->openSession(new PDO("dsn","username","password"));
// getting a table object
$table = $session->getTable("User");
?>
<?php
switch($session->getState())
case Doctrine_Session::STATE_ACTIVE:
// session open and zero open transactions
break;
case Doctrine_Session::STATE_ACTIVE:
// one open transaction
break;
case Doctrine_Session::STATE_BUSY:
// multiple open transactions
break;
case Doctrine_Session::STATE_CLOSED:
// session closed
break;
endswitch;
?>
<?php
// select all users
$session->query("FROM User");
// select all users where user email is jackdaniels@drinkmore.info
$session->query("FROM User WHERE User.Email.address = 'jackdaniels@drinkmore.info'");
?>
<?php
class UserTable extends Doctrine_Table {
/**
* you can add your own finder methods here
*/
public function findByName($name) {
return $this->getSession()->query("FROM User WHERE name LIKE '%$name%'");
}
}
class User extends Doctrine_Record { }
$session = Doctrine_Manager::getInstance()->openSession(new PDO("dsn","username","password"));
// doctrine will now check if a class called UserTable exists and if it inherits Doctrine_Table
$table = $session->getTable("User");
print get_class($table); // UserTable
$users = $table->findByName("Jack");
?>
<?php
// valid table object
class UserTable extends Doctrine_Table {
}
// not valid [doesn't extend Doctrine_Table]
class GroupTable { }
?>
<?php
$table = $session->getTable("User");
// find by primary key
try {
$user = $table->find(2);
} catch(Doctrine_Find_Exception $e) {
print "Couldn't find user";
}
// get all users
foreach($table->findAll() as $user) {
print $user->name;
}
// finding by sql
foreach($table->findBySql("name LIKE '%John%'") as $user) {
print $user->created;
}
?>
<?php
$table = $session->getTable('User');
// getting column names
$names = $table->getColumnNames();
// getting column information
$columns = $table->getColumns();
?>
<?php
class Customer extends Doctrine_Record {
public function setUp() {
// setup code goes here
}
public function setTableDefinition() {
// table definition code goes here
}
public function getAvailibleProducts() {
// some code
}
public function setName($name) {
if($this->isValidName($name))
$this->set("name",$name);
}
public function getName() {
return $this->get("name");
}
}
?>
<?php
// custom primary key column name
class Group extends Doctrine_Record {
public function setUp() {
$this->setPrimaryKeyColumn("group_id");
}
}
?>
<?php
// setting default batch size for batch collections
$manager->setAttribute(Doctrine::ATTR_BATCH_SIZE, 7);
?>
<?php
// setting default event listener
$manager->setAttribute(Doctrine::ATTR_LISTENER, new MyListener());
?>
<?php
// sets the default collection type (fetching strategy)
$manager->setAttribute(Doctrine::ATTR_FETCHMODE, Doctrine::FETCH_LAZY);
?>
<?php
// sets the default offset collection limit
$manager->setAttribute(Doctrine::ATTR_COLL_LIMIT, 10);
?>
<?php
// setting default lockmode
$manager->setAttribute(Doctrine::ATTR_LOCKMODE, Doctrine::LOCK_PESSIMISTIC);
?>
<?php
// turns automatic table creation off
$manager->setAttribute(Doctrine::ATTR_CREATE_TABLES, false);
?>
<?php
// turns transactional validation on
$manager->setAttribute(Doctrine::ATTR_VLD, true);
?>
<?php
class Email extends Doctrine_Record {
public function setUp() {
$this->setAttribute(Doctrine::ATTR_LISTENER,new MyListener());
}
public function setTableDefinition() {
$this->hasColumn("address","string",150,"email|unique");
}
}
?>
<?php
// setting default fetchmode
// availible fetchmodes are Doctrine::FETCH_LAZY, Doctrine::FETCH_IMMEDIATE and Doctrine::FETCH_BATCH
// the default fetchmode is Doctrine::FETCH_LAZY
class Address extends Doctrine_Record {
public function setUp() {
$this->setAttribute(Doctrine::ATTR_FETCHMODE,Doctrine::FETCH_IMMEDIATE);
}
}
?>
<?php
// using sequences
class User extends Doctrine_Record {
public function setUp() {
$this->setSequenceName("user_seq");
}
}
?>
<?php
$sess = Doctrine_Manager::getInstance()->openSession(new PDO("dsn","username","password"));
// select first ten rows starting from the row 20
$sess->select("select * from user",10,20);
?>
<?php
try {
$session->beginTransaction();
$user->save();
$session->beginTransaction();
$group->save();
$email->save();
$session->commit();
$session->commit();
} catch(Exception $e) {
$session->rollback();
}
?>
<?php
// works only if you use doctrine database handler
$dbh = $session->getDBH();
$times = $dbh->getExecTimes();
// print all executed queries and their execution times
foreach($dbh->getQueries() as $index => $query) {
print $query." ".$times[$index];
}
?>
<?php
$sess = Doctrine_Manager::getInstance()->openSession(new PDO("dsn","username","password"));
// gets the next ID from a sequence
$sess->getNextID($sequence);
?>
<?php
$sess = Doctrine_Manager::getInstance()->openSession(new PDO("dsn","username","password"));
try {
$sess->beginTransaction();
// some database operations
$sess->commit();
} catch(Exception $e) {
$sess->rollback();
}
?>
<?php
require_once("path-to-doctrine/Doctrine.class.php");
// autoloading objects
function __autoload($class) {
Doctrine::autoload($class);
}
// loading all components
Doctrine::loadAll();
?>
<?php
class Email extends Doctrine_Record {
public function setTableDefinition() {
/**
* email table has one column named 'address' which is
* php type 'string'
* maximum length 200
* database constraints: UNIQUE
* validators: email, unique
*
*/
$this->hasColumn("address","string",200,"email|unique");
}
}
?>
<?php
class User extends Doctrine_Record {
public function setTableDefinition() {
// set 'user' table columns, note that
// id column is always auto-created
$this->hasColumn("name","string",30);
$this->hasColumn("username","string",20);
$this->hasColumn("password","string",16);
$this->hasColumn("created","integer",11);
}
}
?>
<?php
// NOTE: related record have always the first letter in uppercase
$email = $user->Email;
$email->address = "jackdaniels@drinkmore.info";
$user->save();
// alternative:
$user->Email->address = "jackdaniels@drinkmore.info";
$user->save();
?>
<?php
$user->Email->delete();
$user->Phonenumber[3]->delete();
// deleting user and all related objects:
$user->delete();
?>
<?php
print $user->Email["address"];
print $user->Phonenumber[0]->phonenumber;
print $user->Group[0]->get("name");
?>
<?php
$user->Email["address"] = "koskenkorva@drinkmore.info";
$user->Phonenumber[0]->phonenumber = "123123";
$user->save();
// saves the email and phonenumber
?>
<?php
class User extends Doctrine_Record {
public function setUp() {
$this->ownsMany("Phonenumber","Phonenumber.user_id");
}
public function setTableDefition() {
$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");
}
}
?>
<?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 setTableDefition() {
$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");
}
}
?>
<?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");
}
}
?>
<?php
class Entity extends Doctrine_Record {
public function setTableDefinition() {
$this->hasColumn("name","string",30);
$this->hasColumn("username","string",20);
$this->hasColumn("password","string",16);
$this->hasColumn("created","integer",11);
}
}
class User extends Entity {
public function setUp() {
$this->setInheritanceMap(array("type"=>1);
}
}
class Group extends Entity {
public function setUp() {
$this->setInheritanceMap(array("type"=>2);
}
}
?>
<?php
class Entity extends Doctrine_Record {
public function setTableDefinition() {
$this->hasColumn("name","string",30);
$this->hasColumn("username","string",20);
$this->hasColumn("password","string",16);
$this->hasColumn("created","integer",11);
}
}
class User extends Entity { }
class Group extends Entity { }
?>
<?php
class Entity extends Doctrine_Record {
public function setTableDefinition() {
$this->hasColumn("name","string",30);
$this->hasColumn("username","string",20);
$this->hasColumn("password","string",16);
$this->hasColumn("created","integer",11);
}
}
class User extends Entity {
public function setTableDefinition() {
// the following method call is needed in
// one-table-one-class inheritance
parent::setTableDefinition();
}
}
class Group extends Entity {
public function setTableDefinition() {
// the following method call is needed in
// one-table-one-class inheritance
parent::setTableDefinition();
}
}
?>
<?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();
$groups = new Doctrine_Collection($session->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'
?>
<?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");
}
}
?>
<?php
class Forum_Board extends Doctrine_Record {
public function setTableDefinition() {
$this->hasColumn("name", "string", 100);
$this->hasColumn("description", "string", 5000);
}
public function setUp() {
// notice the 'as' keyword here
$this->ownsMany("Forum_Thread as Threads", "Forum_Thread.board_id");
}
}
class Forum_Thread extends Doctrine_Record {
public function setTableDefinition() {
$this->hasColumn("board_id", "integer", 10);
$this->hasColumn("updated", "integer", 10);
$this->hasColumn("closed", "integer", 1);
}
public function setUp() {
// notice the 'as' keyword here
$this->hasOne("Forum_Board as Board", "Forum_Thread.board_id");
}
}
$board = new Board();
$board->Threads[0]->updated = time();
?>
<?php
/**
* lets presume $users contains a collection of users
* each having 0-1 email and 0-* phonenumbers
*/
$users->delete();
/**
* On session drivers other than mysql doctrine would now perform three queries
* regardless of how many users, emails and phonenumbers there are
*
* the queries would look something like:
* DELETE FROM entity WHERE entity.id IN (1,2,3, ... ,15)
* DELETE FROM phonenumber WHERE phonenumber.id IN (4,6,7,8)
* DELETE FROM email WHERE email.id IN (1,2, ... ,10)
*
* On mysql doctrine is EVEN SMARTER! Now it would perform only one query!
* the query would look like:
* DELETE entity, email, phonenumber FROM entity
* LEFT JOIN phonenumber ON entity.id = phonenumber.entity_id, email
* WHERE (entity.email_id = email.id) && (entity.id IN(4, 5, 6, 7, 8, 9, 10, 11)) && (entity.type = 0)
*/
?>
<?php
// lets presume $users contains a collection of new users
// each having 0-1 email and 0-* phonenumbers
$users->save();
/**
* now doctrine would perform prepared queries in the following order:
*
* first the emails since every user needs to get the primary key of their newly created email
* INSERT INTO email (address) VALUES (:address)
* INSERT INTO email (address) VALUES (:address)
* INSERT INTO email (address) VALUES (:address)
*
* then the users
* INSERT INTO entity (name,email_id) VALUES (:name,:email_id)
* INSERT INTO entity (name,email_id) VALUES (:name,:email_id)
* INSERT INTO entity (name,email_id) VALUES (:name,:email_id)
*
* and at last the phonenumbers since they need the primary keys of the newly created users
* INSERT INTO phonenumber (phonenumber,entity_id) VALUES (:phonenumber,:entity_id)
* INSERT INTO phonenumber (phonenumber,entity_id) VALUES (:phonenumber,:entity_id)
* INSERT INTO phonenumber (phonenumber,entity_id) VALUES (:phonenumber,:entity_id)
* INSERT INTO phonenumber (phonenumber,entity_id) VALUES (:phonenumber,:entity_id)
* INSERT INTO phonenumber (phonenumber,entity_id) VALUES (:phonenumber,:entity_id)
*
* These operations are considerably fast, since many databases perform multiple
* prepared queries very rapidly
*/
?>
<?php
class Forum_Category extends Doctrine_Record {
public function setTableDefinition() {
$this->hasColumn("root_category_id", "integer", 10);
$this->hasColumn("parent_category_id", "integer", 10);
$this->hasColumn("name", "string", 50);
$this->hasColumn("description", "string", 99999);
}
public function setUp() {
$this->hasMany("Forum_Category as Subcategory", "Subcategory.parent_category_id");
$this->hasOne("Forum_Category as Rootcategory", "Forum_Category.root_category_id");
}
}
class Forum_Board extends Doctrine_Record {
public function setTableDefinition() {
$this->hasColumn("category_id", "integer", 10);
$this->hasColumn("name", "string", 100);
$this->hasColumn("description", "string", 5000);
}
public function setUp() {
$this->hasOne("Forum_Category as Category", "Forum_Board.category_id");
$this->ownsMany("Forum_Thread as Threads", "Forum_Thread.board_id");
}
}
class Forum_Entry extends Doctrine_Record {
public function setTableDefinition() {
$this->hasColumn("author", "string", 50);
$this->hasColumn("topic", "string", 100);
$this->hasColumn("message", "string", 99999);
$this->hasColumn("parent_entry_id", "integer", 10);
$this->hasColumn("thread_id", "integer", 10);
$this->hasColumn("date", "integer", 10);
}
public function setUp() {
$this->hasOne("Forum_Entry as Parent", "Forum_Entry.parent_entry_id");
$this->hasOne("Forum_Thread as Thread", "Forum_Entry.thread_id");
}
}
class Forum_Thread extends Doctrine_Record {
public function setTableDefinition() {
$this->hasColumn("board_id", "integer", 10);
$this->hasColumn("updated", "integer", 10);
$this->hasColumn("closed", "integer", 1);
}
public function setUp() {
$this->hasOne("Forum_Board as Board", "Forum_Thread.board_id");
$this->ownsMany("Forum_Entry as Entries", "Forum_Entry.thread_id");
}
}
?>
<?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());
}
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");
}
}
}
class Group extends Entity {
public function setUp() {
parent::setUp();
$this->hasMany("User","Groupuser.user_id");
$this->setInheritanceMap(array("type"=>1));
}
}
class User extends Entity {
public function setUp() {
parent::setUp();
$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 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 EntityListener extends Doctrine_EventListener {
public function onPreUpdate(Doctrine_Record $record) {
$record->updated = time();
}
public function onPreInsert(Doctrine_Record $record) {
$record->created = time();
}
}
// USER MANAGEMENT SYSTEM IN ACTION:
$manager = Doctrine_Manager::getInstance();
$session = $manager->openSession(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->save();
$user->Group[0]->name = "beer lovers";
$user->Group[0]->Email->address = "beerlovers@drinkmore.info";
$user->Group[0]->save();
?>
<?php
$user = $table->find(2);
// get state
$state = $user->getState();
print $user->name;
print $user["name"];
print $user->get("name");
$user->name = "Jack Daniels";
$user->set("name","Jack Daniels");
// serialize record
$serialized = serialize($user);
$user = unserialize($serialized);
// create a copy
$copy = $user->copy();
// get primary key
$id = $user->getID();
// print lots of useful info
print $user;
// save all the properties and composites
$user->save();
// delete this data access object and related objects
$user->delete();
?>
<?php
$sess = $manager->openSession(Doctrine_DB::getConnection("schema://username:password@hostname/database"));
// get session state:
switch($sess):
case Doctrine_Session::STATE_BUSY:
// multiple open transactions
break;
case Doctrine_Session::STATE_ACTIVE:
// one open transaction
break;
case Doctrine_Session::STATE_CLOSED:
// closed state
break;
case Doctrine_Session::STATE_OPEN:
// open state and zero open transactions
break;
endswitch;
// getting database handler
$dbh = $sess->getDBH();
// flushing the session
$sess->flush();
// print lots of useful info about session:
print $sess;
?>
<?php
$session->beginTransaction();
$user = new User();
$user->name = 'New user';
$user->save();
$user = $session->getTable('User')->find(5);
$user->name = 'Modified user';
$user->save();
$session->commit(); // all the queries are executed here
?>
<?php
function saveUserAndGroup(Doctrine_Session $session, User $user, Group $group) {
$session->beginTransaction();
$user->save();
$group->save();
$session->commit();
}
try {
$session->beginTransaction();
saveUserAndGroup($session,$user,$group);
saveUserAndGroup($session,$user2,$group2);
saveUserAndGroup($session,$user3,$group3);
$session->commit();
} catch(Doctrine_Exception $e) {
$session->rollback();
}
?>
<?php
$session->beginTransaction();
$user = new User();
$user->name = 'New user';
$user->save();
$user = $session->getTable('User')->find(5);
$user->name = 'Modified user';
$user->save();
$pending = $session->getInserts(); // an array containing one element
$pending = $session->getUpdates(); // an array containing one element
$session->commit(); // all the queries are executed here
?>
Caching is one of the most influental things when it comes to performance tuning. Doctrine_Cache provides means for
caching queries and for managing the cached queries.
Creating a new listener is very easy. You can set the listener in global, session or factory level.
Here is a list of availible events and their parameters:
Many web applications have different kinds of lists. The lists may contain data from multiple components (= database tables) and
they may have actions such as paging, sorting and setting conditions. Doctrine_Hook helps building these lists. It has a simple API for
building search criteria forms as well as building a DQL query from the 'hooked' parameters.
With Doctrine validators you can validate a whole transaction and get info of everything
that went wrong. Some Doctrine validators also act as a database level constraints. For example
adding a unique validator to column 'name' also adds a database level unique constraint into that
column.
<br \><br \>
Validators are added as a 4 argument for hasColumn() method. Validators should be separated
by '|' mark. For example email|unique would validate a value using Doctrine_Validator_Email
and Doctrine_Validator_Unique.
<br \><br \>
Doctrine has many predefined validators (see chapter 13.3). If you wish to use
custom validators just write *Validator classes and doctrine will automatically use them.
Here is a list of predefined validators. You cannot use these names for your custom validators.
<table width="500">
<tr>
<td>
<b>name</b>
</td>
<td>
<b>arguments</b>
</td>
<td>
<b>task</b>
</td>
</tr>
<tr>
<td>
email
</td>
<td>
</td>
<td>
Checks if value is valid email.
</td>
</tr>
<tr>
<td>
notblank
</td>
<td>
</td>
<td>
Checks if value is not blank.
</td>
</tr>
<tr>
<td>
notnull
</td>
<td>
</td>
<td>
Checks if value is not null.
</td>
</tr>
<tr>
<td>
country
</td>
<td>
</td>
<td>
Checks if value is valid country code.
</td>
</tr>
<tr>
<td>
ip
</td>
<td>
</td>
<td>
Checks if value is valid internet protocol address.
</td>
</tr>
<tr>
<td>
htmlcolor
</td>
<td>
</td>
<td>
Checks if value is valid html color.
</td>
</tr>
<tr>
<td>
nospace
</td>
<td>
</td>
<td>
Checks if value has no space chars.
</td>
</tr>
<tr>
<td>
range
</td>
<td>
[min, max]
</td>
<td>
Checks if value is in range specified by arguments.
</td>
</tr>
<tr>
<td>
unique
</td>
<td>
</td>
<td>
Checks if value is unique in its database table.
</td>
</tr>
<tr>
<td>
regexp
</td>
<td>
[expression]
</td>
<td>
Checks if value matches a given regexp.
</td>
</tr>
</table>
When the validation attribute is set as true all transactions will be validated, so whenever Doctrine_Record::save(),
Doctrine_Session::flush() or any other saving method is used all the properties of all records in that transaction will have their values
validated.
<br \><br \>
Validation errors are being stacked into Doctrine_Validator_Exception.
Database views can greatly increase the performance of complex queries. You can think of them as
cached queries. Doctrine_View provides integration between database views and DQL queries.
You can access the elements of Doctrine_Collection with set() and get() methods or with ArrayAccess interface.
Doctrine Collections can be deleted in very same way is Doctrine Records you just call delete() method.
As for all collections Doctrine knows how to perform single-shot-delete meaning it only performs one
database query for the each collection.
<br \> <br \>
For example if we have collection of users which own [0-*] phonenumbers. When deleting the collection
of users doctrine only performs two queries for this whole transaction. The queries would look something like:
<br \><br \>
DELETE FROM user WHERE id IN (1,2,3, ... ,N)<br \>
DELETE FROM phonenumber WHERE id IN (1,2,3, ... ,M)<br \>
Whenever you fetch records with eg. Doctrine_Table::findAll or Doctrine_Session::query methods an instance of
Doctrine_Collection is returned. There are many types of collections in Doctrine and it is crucial to understand
the differences of these collections. Remember choosing the right fetching strategy (collection type) is one of the most
influental things when it comes to boosting application performance.
<br \><br \>
<li>Immediate Collection<ul>
Fetches all records and all record data immediately into collection memory. Use this collection only if you really need to show all that data
in web page.
<br \><br \>
Example query:<br \>
SELECT id, name, type, created FROM user
<br \><br \></ul>
<li>Batch Collection<ul>
Fetches all record primary keys into colletion memory. When individual collection elements are accessed this collection initializes proxy objects.
When the non-primary-key-property of a proxy object is accessed that object sends request to Batch collection which loads the data
for that specific proxy object as well as other objects close to that proxy object.
<br \><br \>
Example queries:<br \>
SELECT id FROM user<br \>
SELECT id, name, type, created FROM user WHERE id IN (1,2,3,4,5)<br \>
SELECT id, name, type, created FROM user WHERE id IN (6,7,8,9,10)<br \>
[ ... ]<br \>
</ul>
<li>Lazy Collection<ul>
Lazy collection is exactly same as Batch collection with batch size preset to one.
<br \><br \>
Example queries:<br \>
SELECT id FROM user<br \>
SELECT id, name, type, created FROM user WHERE id = 1<br \>
SELECT id, name, type, created FROM user WHERE id = 2<br \>
SELECT id, name, type, created FROM user WHERE id = 3<br \>
[ ... ]<br \>
</ul>
<li>Offset Collection<ul>
Offset collection is the same as immediate collection with the difference that it uses database provided limiting of queries.
<br \><br \>
Example queries:<br \>
SELECT id, name, type, created FROM user LIMIT 5<br \>
SELECT id, name, type, created FROM user LIMIT 5 OFFSET 5<br \>
SELECT id, name, type, created FROM user LIMIT 5 OFFSET 10<br \>
[ ... ]<br \></ul>
Doctrine_Manager is the heart of every Doctrine based application. Doctrine_Manager handles all sessions (database connections).
Switching between sessions in Doctrine is very easy, you just call Doctrine_Manager::setCurrentSession() method.
You can access the session by calling Doctrine_Manager::getSession() or Doctrine_Manager::getCurrentSession() if you only
want to get the current session.
In order to get your first application started you first
need to get an instance of Doctrine_Manager which handles all the sessions (database connections).
The second thing to do is to open a new session.
<?php
$str = "
The following examples should give a hint of how DQL is converted into SQL.
The classes used in here are the same as in chapter 14.1 (Users and groups are both entities etc).
DQL QUERY: FROM Email WHERE Email.address LIKE '%@example%'
SQL QUERY: SELECT email.id AS Email__id FROM email WHERE (email.address LIKE '%@example%')
DQL QUERY: FROM User(id) WHERE User.Phonenumber.phonenumber LIKE '%123%'
SQL QUERY: SELECT entity.id AS entity__id FROM entity LEFT JOIN phonenumber ON entity.id = phonenumber.entity_id WHERE phonenumber.phonenumber LIKE '%123%' AND (entity.type = 0)
DQL QUERY: FROM Forum_Board(id).Threads(id).Entries(id)
SQL QUERY: SELECT forum_board.id AS forum_board__id, forum_thread.id AS forum_thread__id, forum_entry.id AS forum_entry__id FROM forum_board LEFT JOIN forum_thread ON forum_board.id = forum_thread.board_id LEFT JOIN forum_entry ON forum_thread.id = forum_entry.thread_id
DQL QUERY: FROM User(id) WHERE User.Group.name = 'Action Actors'
SQL QUERY: SELECT entity.id AS entity__id FROM entity LEFT JOIN groupuser ON entity.id = groupuser.user_id LEFT JOIN entity AS entity2 ON entity2.id = groupuser.group_id WHERE entity2.name = 'Action Actors' AND (entity.type = 0 AND (entity2.type = 1 OR entity2.type IS NULL))
DQL QUERY: FROM User(id) WHERE User.Group.Phonenumber.phonenumber LIKE '123 123'
SQL QUERY: SELECT entity.id AS entity__id FROM entity LEFT JOIN groupuser ON entity.id = groupuser.user_id LEFT JOIN entity AS entity2 ON entity2.id = groupuser.group_id LEFT JOIN phonenumber ON entity2.id = phonenumber.entity_id WHERE phonenumber.phonenumber LIKE '123 123' AND (entity.type = 0 AND (entity2.type = 1 OR entity2.type IS NULL))
";
$e = explode("\n",$str);
$color = "367FAC";
foreach($e as $line) {
if(strpos($line, "SQL") !== false)
$color = "A50A3D";
elseif(strpos($line, "DQL") !== false)
$color = "367FAC";
$l = str_replace("SELECT","<br \><font color='$color'><b>SELECT</b></font>",$line);
$l = str_replace("FROM","<br \><font color='$color'><b>FROM</b></font>",$l);
$l = str_replace("LEFT JOIN","<br \><font color='$color'><b>LEFT JOIN</b></font>",$l);
$l = str_replace("WHERE","<br \><font color='$color'><b>WHERE</b></font>",$l);
$l = str_replace("AS","<font color='$color'><b>AS</b></font>",$l);
$l = str_replace("ON","<font color='$color'><b>ON</b></font>",$l);
$l = str_replace("ORDER BY","<font color='$color'><b>ORDER BY</b></font>",$l);
$l = str_replace("LIMIT","<font color='$color'><b>LIMIT</b></font>",$l);
$l = str_replace("OFFSET","<font color='$color'><b>OFFSET</b></font>",$l);
$l = str_replace(" ","<dd>",$l);
if(substr($l,0,3) == "DQL") print "<hr valign='left' class='small'>";
print $l."<br>";
}
?>
DQL (Doctrine Query Language) is a object query language which allows
you to find objects. DQL understands things like object relationships, polymorphism and
inheritance (including column aggregation inheritance).
<br \><br \>
So instead of writing lots of SQL inner and outer joins, unions and subselects yourself,
you can write simple DQL queries where relationships are being referenced with dot-notation.
<br \><br \>
You can execute DQL queries with Doctrine_Session::query() method.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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