Added a folder remotely
This commit is contained in:
parent
539c7f3d36
commit
98dc74b639
Doctrine
Access.phpAssociation.phpCache.phpCollection.phpConfigurable.phpDB.phpDataDict.phpDebugger.phpEventListener.phpException.phpForeignKey.phpForm.class.phpIdentifier.phpIdentityMap.class.phpIndexGenerator.phpIterator.phpLib.phpLocalKey.phpManager.phpModule.class.phpNull.phpQuery.phpRecord.phpRelation.phpRepository.phpSession.phpStatement.class.phpTable.phpValidator.php
82
Doctrine/Access.php
Normal file
82
Doctrine/Access.php
Normal file
@ -0,0 +1,82 @@
|
||||
<?php
|
||||
/**
|
||||
* Doctrine_Access
|
||||
*
|
||||
* the purpose of Doctrine_Access is to provice array access
|
||||
* and property overload interface for subclasses
|
||||
*
|
||||
* @package Doctrine ORM
|
||||
* @url www.phpdoctrine.com
|
||||
* @license LGPL
|
||||
*/
|
||||
abstract class Doctrine_Access implements ArrayAccess {
|
||||
/**
|
||||
* setArray
|
||||
* @param array $array an array of key => value pairs
|
||||
*/
|
||||
public function setArray(array $array) {
|
||||
foreach($array as $k=>$v):
|
||||
$this->set($k,$v);
|
||||
endforeach;
|
||||
}
|
||||
/**
|
||||
* __set -- an alias of set()
|
||||
* @see set, offsetSet
|
||||
* @param $name
|
||||
* @param $value
|
||||
*/
|
||||
public function __set($name,$value) {
|
||||
$this->set($name,$value);
|
||||
}
|
||||
/**
|
||||
* __get -- an alias of get()
|
||||
* @see get, offsetGet
|
||||
* @param mixed $name
|
||||
* @return mixed
|
||||
*/
|
||||
public function __get($name) {
|
||||
return $this->get($name);
|
||||
}
|
||||
/**
|
||||
* @param mixed $offset
|
||||
* @return boolean -- whether or not the data has a field $offset
|
||||
*/
|
||||
public function offsetExists($offset) {
|
||||
return (bool) isset($this->data[$offset]);
|
||||
}
|
||||
/**
|
||||
* offsetGet -- an alias of get()
|
||||
* @see get, __get
|
||||
* @param mixed $offset
|
||||
* @return mixed
|
||||
*/
|
||||
public function offsetGet($offset) {
|
||||
return $this->get($offset);
|
||||
}
|
||||
/**
|
||||
* sets $offset to $value
|
||||
* @see set, __set
|
||||
* @param mixed $offset
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
*/
|
||||
public function offsetSet($offset, $value) {
|
||||
if( ! isset($offset)) {
|
||||
$this->add($value);
|
||||
} else
|
||||
$this->set($offset,$value);
|
||||
}
|
||||
/**
|
||||
* unset a given offset
|
||||
* @see set, offsetSet, __set
|
||||
* @param mixed $offset
|
||||
*/
|
||||
public function offsetUnset($offset) {
|
||||
if($this instanceof Doctrine_Collection) {
|
||||
return $this->remove($offset);
|
||||
} else {
|
||||
$this->set($offset,null);
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
38
Doctrine/Association.php
Normal file
38
Doctrine/Association.php
Normal file
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
require_once("Relation.php");
|
||||
/**
|
||||
* Doctrine_Association this class takes care of association mapping
|
||||
* (= many-to-many relationships, where the relationship is handled with an additional relational table
|
||||
* which holds 2 foreign keys)
|
||||
*
|
||||
*
|
||||
* @package Doctrine ORM
|
||||
* @url www.phpdoctrine.com
|
||||
* @license LGPL
|
||||
*/
|
||||
class Doctrine_Association extends Doctrine_Relation {
|
||||
/**
|
||||
* @var Doctrine_Table $associationTable
|
||||
*/
|
||||
private $associationTable;
|
||||
/**
|
||||
* the constructor
|
||||
* @param Doctrine_Table $table foreign factory object
|
||||
* @param Doctrine_Table $associationTable factory which handles the association
|
||||
* @param string $local local field name
|
||||
* @param string $foreign foreign field name
|
||||
* @param integer $type type of relation
|
||||
* @see Doctrine_Table constants
|
||||
*/
|
||||
public function __construct(Doctrine_Table $table, Doctrine_Table $associationTable, $local, $foreign, $type) {
|
||||
parent::__construct($table, $local, $foreign, $type);
|
||||
$this->associationTable = $associationTable;
|
||||
}
|
||||
/**
|
||||
* @return Doctrine_Table
|
||||
*/
|
||||
public function getAssociationFactory() {
|
||||
return $this->associationTable;
|
||||
}
|
||||
}
|
||||
?>
|
71
Doctrine/Cache.php
Normal file
71
Doctrine/Cache.php
Normal file
@ -0,0 +1,71 @@
|
||||
<?php
|
||||
interface iDoctrine_Cache {
|
||||
public function store(Doctrine_Record $record);
|
||||
public function clean();
|
||||
public function delete($id);
|
||||
public function fetch($id);
|
||||
public function exists($id);
|
||||
}
|
||||
class Doctrine_Cache implements iDoctrine_Cache {
|
||||
/**
|
||||
* implemented by child classes
|
||||
* @param Doctrine_Record $record
|
||||
* @return boolean
|
||||
*/
|
||||
public function store(Doctrine_Record $record) {
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* implemented by child classes
|
||||
* @return boolean
|
||||
*/
|
||||
public function clean() {
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* implemented by child classes
|
||||
* @return boolean
|
||||
*/
|
||||
public function delete($id) {
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* implemented by child classes
|
||||
* @throws InvalidKeyException
|
||||
* @return Doctrine_Record found Data Access Object
|
||||
*/
|
||||
public function fetch($id) {
|
||||
throw new InvalidKeyException();
|
||||
}
|
||||
/**
|
||||
* implemented by child classes
|
||||
* @param array $keys
|
||||
* @return boolean
|
||||
*/
|
||||
public function fetchMultiple($keys) {
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* implemented by child classes
|
||||
* @param integer $id
|
||||
* @return boolean
|
||||
*/
|
||||
public function exists($id) {
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* implemented by child classes
|
||||
*/
|
||||
public function deleteMultiple($keys) {
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* implemented by child classes
|
||||
* @return integer
|
||||
*/
|
||||
public function deleteAll() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
446
Doctrine/Collection.php
Normal file
446
Doctrine/Collection.php
Normal file
@ -0,0 +1,446 @@
|
||||
<?php
|
||||
require_once("Access.php");
|
||||
/**
|
||||
* Doctrine_Collection
|
||||
* Collection of Doctrine_Record objects.
|
||||
*
|
||||
* @package Doctrine ORM
|
||||
* @url www.phpdoctrine.com
|
||||
* @license LGPL
|
||||
*/
|
||||
class Doctrine_Collection extends Doctrine_Access implements Countable, IteratorAggregate {
|
||||
/**
|
||||
* @var array $data an array containing the data access objects of this collection
|
||||
*/
|
||||
protected $data = array();
|
||||
/**
|
||||
* @var Doctrine_Table $table each collection has only records of specified table
|
||||
*/
|
||||
protected $table;
|
||||
/**
|
||||
* @var Doctrine_Record $reference collection can belong to a record
|
||||
*/
|
||||
protected $reference;
|
||||
/**
|
||||
* @var string $reference_field the reference field of the collection
|
||||
*/
|
||||
protected $reference_field;
|
||||
/**
|
||||
* @var Doctrine_Relation the record this collection is related to, if any
|
||||
*/
|
||||
protected $relation;
|
||||
/**
|
||||
* @var boolean $expandable whether or not this collection has been expanded
|
||||
*/
|
||||
protected $expandable = true;
|
||||
/**
|
||||
* @var array $expanded
|
||||
*/
|
||||
protected $expanded = array();
|
||||
/**
|
||||
* @var mixed $generator
|
||||
*/
|
||||
protected $generator;
|
||||
/**
|
||||
* @var Doctrine_Null $null used for extremely fast SQL null value testing
|
||||
*/
|
||||
protected static $null;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
*/
|
||||
public function __construct(Doctrine_Table $table) {
|
||||
$this->table = $table;
|
||||
|
||||
$name = $table->getAttribute(Doctrine::ATTR_COLL_KEY);
|
||||
if($name !== null) {
|
||||
$this->generator = new Doctrine_IndexGenerator($name);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* initNullObject
|
||||
*/
|
||||
public static function initNullObject(Doctrine_Null $null) {
|
||||
self::$null = $null;
|
||||
}
|
||||
/**
|
||||
* @return object Doctrine_Table
|
||||
*/
|
||||
public function getTable() {
|
||||
return $this->table;
|
||||
}
|
||||
/**
|
||||
* whether or not an offset batch has been expanded
|
||||
* @return boolean
|
||||
*/
|
||||
public function isExpanded($offset) {
|
||||
return isset($this->expanded[$offset]);
|
||||
}
|
||||
/**
|
||||
* whether or not this collection is expandable
|
||||
* @return boolean
|
||||
*/
|
||||
public function isExpandable() {
|
||||
return $this->expandable;
|
||||
}
|
||||
/**
|
||||
* @param Doctrine_IndexGenerator $generator
|
||||
* @return void
|
||||
*/
|
||||
public function setGenerator($generator) {
|
||||
$this->generator = $generator;
|
||||
}
|
||||
/**
|
||||
* @return Doctrine_IndexGenerator
|
||||
*/
|
||||
public function getGenerator() {
|
||||
return $this->generator;
|
||||
}
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getData() {
|
||||
return $this->data;
|
||||
}
|
||||
/**
|
||||
* @param array $data
|
||||
*/
|
||||
public function addData(array $data) {
|
||||
$this->data[] = $data;
|
||||
}
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getLast() {
|
||||
return end($this->data);
|
||||
}
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function setReference(Doctrine_Record $record,Doctrine_Relation $relation) {
|
||||
$this->reference = $record;
|
||||
$this->relation = $relation;
|
||||
|
||||
if($relation instanceof Doctrine_ForeignKey ||
|
||||
$relation instanceof Doctrine_LocalKey) {
|
||||
|
||||
$this->reference_field = $relation->getForeign();
|
||||
|
||||
$value = $record->get($relation->getLocal());
|
||||
|
||||
foreach($this->getNormalIterator() as $record) {
|
||||
if($value !== null) {
|
||||
$record->rawSet($this->reference_field, $value);
|
||||
} else {
|
||||
$record->rawSet($this->reference_field, $this->reference);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getReference() {
|
||||
return $this->reference;
|
||||
}
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
public function expand($key) {
|
||||
$where = array();
|
||||
$params = array();
|
||||
$limit = null;
|
||||
$offset = null;
|
||||
|
||||
switch(get_class($this)):
|
||||
case "Doctrine_Collection_Offset":
|
||||
$limit = $this->getLimit();
|
||||
$offset = (floor($key / $limit) * $limit);
|
||||
|
||||
if( ! $this->expandable && isset($this->expanded[$offset]))
|
||||
return false;
|
||||
|
||||
$fields = implode(", ",$this->table->getColumnNames());
|
||||
break;
|
||||
default:
|
||||
if( ! $this->expandable)
|
||||
return false;
|
||||
|
||||
if( ! isset($this->reference))
|
||||
return false;
|
||||
|
||||
$id = $this->reference->getID();
|
||||
|
||||
if(empty($id))
|
||||
return false;
|
||||
|
||||
switch(get_class($this)):
|
||||
case "Doctrine_Collection_Immediate":
|
||||
$fields = implode(", ",$this->table->getColumnNames());
|
||||
break;
|
||||
default:
|
||||
$fields = implode(", ",$this->table->getPrimaryKeys());
|
||||
endswitch;
|
||||
|
||||
|
||||
endswitch;
|
||||
|
||||
if(isset($this->relation)) {
|
||||
if($this->relation instanceof Doctrine_ForeignKey) {
|
||||
$params = array($this->reference->getID());
|
||||
$where[] = $this->reference_field." = ?";
|
||||
|
||||
if( ! isset($offset)) {
|
||||
$ids = $this->getPrimaryKeys();
|
||||
|
||||
if( ! empty($ids)) {
|
||||
$where[] = $this->table->getIdentifier()." NOT IN (".substr(str_repeat("?, ",count($ids)),0,-2).")";
|
||||
$params = array_merge($params,$ids);
|
||||
}
|
||||
|
||||
$this->expandable = false;
|
||||
}
|
||||
|
||||
|
||||
} elseif($this->relation instanceof Doctrine_Association) {
|
||||
|
||||
$asf = $fk->getAssociationFactory();
|
||||
$query = "SELECT ".$foreign." FROM ".$asf->getTableName()." WHERE ".$local."=".$this->getID();
|
||||
|
||||
$table = $fk->getTable();
|
||||
$graph = new Doctrine_DQL_Parser($table->getSession());
|
||||
|
||||
$q = "FROM ".$table->getComponentName()." WHERE ".$table->getComponentName().".".$table->getIdentifier()." IN ($query)";
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
$query = "SELECT ".$fields." FROM ".$this->table->getTableName();
|
||||
|
||||
// apply column aggregation inheritance
|
||||
foreach($this->table->getInheritanceMap() as $k => $v) {
|
||||
$where[] = $k." = ?";
|
||||
$params[] = $v;
|
||||
}
|
||||
if( ! empty($where)) {
|
||||
$query .= " WHERE ".implode(" AND ",$where);
|
||||
}
|
||||
|
||||
$params = array_merge($params, array_values($this->table->getInheritanceMap()));
|
||||
|
||||
$coll = $this->table->execute($query, $params, $limit, $offset);
|
||||
|
||||
if( ! isset($offset)) {
|
||||
foreach($coll as $record) {
|
||||
if(isset($this->reference_field))
|
||||
$record->rawSet($this->reference_field,$this->reference);
|
||||
|
||||
$this->reference->addReference($record);
|
||||
}
|
||||
} else {
|
||||
$i = $offset;
|
||||
|
||||
foreach($coll as $record) {
|
||||
if(isset($this->reference)) {
|
||||
$this->reference->addReference($record,$i);
|
||||
} else
|
||||
$this->data[$i] = $record;
|
||||
|
||||
$i++;
|
||||
}
|
||||
|
||||
$this->expanded[$offset] = true;
|
||||
|
||||
// check if the fetched collection's record count is smaller
|
||||
// than the query limit, if so this collection has been expanded to its max size
|
||||
|
||||
if(count($coll) < $limit) {
|
||||
$this->expandable = false;
|
||||
}
|
||||
}
|
||||
|
||||
return $coll;
|
||||
}
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
public function remove($key) {
|
||||
if( ! isset($this->data[$key]))
|
||||
throw new InvalidKeyException();
|
||||
|
||||
$removed = $this->data[$key];
|
||||
|
||||
unset($this->data[$key]);
|
||||
return $removed;
|
||||
}
|
||||
/**
|
||||
* @param mixed $key
|
||||
* @return boolean
|
||||
*/
|
||||
public function contains($key) {
|
||||
return isset($this->data[$key]);
|
||||
}
|
||||
/**
|
||||
* @param mixed $key
|
||||
* @return object Doctrine_Record return a specified record
|
||||
*/
|
||||
public function get($key) {
|
||||
if( ! isset($this->data[$key])) {
|
||||
$this->expand($key);
|
||||
|
||||
if( ! isset($this->data[$key]))
|
||||
$this->data[$key] = $this->table->create();
|
||||
|
||||
if(isset($this->reference_field)) {
|
||||
$value = $this->reference->get($this->relation->getLocal());
|
||||
|
||||
if($value !== null) {
|
||||
$this->data[$key]->rawSet($this->reference_field, $value);
|
||||
} else {
|
||||
$this->data[$key]->rawSet($this->reference_field, $this->reference);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->data[$key];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array an array containing all primary keys
|
||||
*/
|
||||
public function getPrimaryKeys() {
|
||||
$list = array();
|
||||
$name = $this->table->getIdentifier();
|
||||
|
||||
foreach($this->data as $record):
|
||||
if(is_array($record) && isset($record[$name])) {
|
||||
$list[] = $record[$name];
|
||||
} else {
|
||||
$list[] = $record->getID();
|
||||
}
|
||||
endforeach;
|
||||
return $list;
|
||||
}
|
||||
/**
|
||||
* returns all keys
|
||||
* @return array
|
||||
*/
|
||||
public function getKeys() {
|
||||
return array_keys($this->data);
|
||||
}
|
||||
/**
|
||||
* count
|
||||
* this class implements interface countable
|
||||
* @return integer number of records in this collection
|
||||
*/
|
||||
public function count() {
|
||||
return count($this->data);
|
||||
}
|
||||
/**
|
||||
* set
|
||||
* @param integer $key
|
||||
* @param Doctrine_Record $record
|
||||
* @return void
|
||||
*/
|
||||
public function set($key,Doctrine_Record $record) {
|
||||
if(isset($this->reference_field))
|
||||
$record->rawSet($this->reference_field,$this->reference);
|
||||
|
||||
$this->data[$key] = $record;
|
||||
}
|
||||
|
||||
/**
|
||||
* adds a record to collection
|
||||
* @param Doctrine_Record $record record to be added
|
||||
* @param string $key optional key for the record
|
||||
* @return boolean
|
||||
*/
|
||||
public function add(Doctrine_Record $record,$key = null) {
|
||||
if(isset($this->reference_field))
|
||||
$record->rawSet($this->reference_field,$this->reference);
|
||||
|
||||
if(isset($key)) {
|
||||
if(isset($this->data[$key]))
|
||||
return false;
|
||||
|
||||
$this->data[$key] = $record;
|
||||
return true;
|
||||
}
|
||||
|
||||
if(isset($this->generator)) {
|
||||
$key = $this->generator->getIndex($record);
|
||||
$this->data[$key] = $record;
|
||||
} else
|
||||
$this->data[] = $record;
|
||||
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* @param Doctrine_Query $query
|
||||
* @param integer $key
|
||||
*/
|
||||
public function populate(Doctrine_Query $query) {
|
||||
$name = $this->table->getComponentName();
|
||||
|
||||
if($this instanceof Doctrine_Collection_Immediate ||
|
||||
$this instanceof Doctrine_Collection_Offset) {
|
||||
|
||||
$data = $query->getData($name);
|
||||
if(is_array($data)) {
|
||||
foreach($data as $k=>$v):
|
||||
$this->table->setData($v);
|
||||
$this->add($this->table->getRecord());
|
||||
endforeach;
|
||||
}
|
||||
} elseif($this instanceof Doctrine_Collection_Batch) {
|
||||
$this->data = $query->getData($name);
|
||||
|
||||
if(isset($this->generator)) {
|
||||
foreach($this->data as $k => $v) {
|
||||
$record = $this->get($k);
|
||||
$i = $this->generator->getIndex($record);
|
||||
$this->data[$i] = $record;
|
||||
unset($this->data[$k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @return Doctrine_Iterator_Normal
|
||||
*/
|
||||
public function getNormalIterator() {
|
||||
return new Doctrine_Iterator_Normal($this);
|
||||
}
|
||||
/**
|
||||
* save
|
||||
* saves all records
|
||||
*/
|
||||
public function save() {
|
||||
$this->table->getSession()->saveCollection($this);
|
||||
}
|
||||
/**
|
||||
* single shot delete
|
||||
* deletes all records from this collection
|
||||
* uses only one database query to perform this operation
|
||||
* @return boolean
|
||||
*/
|
||||
public function delete() {
|
||||
$ids = $this->table->getSession()->deleteCollection($this);
|
||||
$this->data = array();
|
||||
}
|
||||
/**
|
||||
* getIterator
|
||||
* @return object ArrayIterator
|
||||
*/
|
||||
public function getIterator() {
|
||||
$data = $this->data;
|
||||
return new ArrayIterator($data);
|
||||
}
|
||||
/**
|
||||
* returns a string representation of this object
|
||||
*/
|
||||
public function __toString() {
|
||||
return Doctrine_Lib::getCollectionAsString($this);
|
||||
}
|
||||
}
|
||||
?>
|
174
Doctrine/Configurable.php
Normal file
174
Doctrine/Configurable.php
Normal file
@ -0,0 +1,174 @@
|
||||
<?php
|
||||
/**
|
||||
* Doctrine_Configurable
|
||||
* the base for Doctrine_Table, Doctrine_Manager and Doctrine_Session
|
||||
*
|
||||
*
|
||||
* @package Doctrine ORM
|
||||
* @url www.phpdoctrine.com
|
||||
* @license LGPL
|
||||
*/
|
||||
abstract class Doctrine_Configurable {
|
||||
|
||||
/**
|
||||
* @var array $attributes an array of containing all attributes
|
||||
*/
|
||||
private $attributes = array();
|
||||
/**
|
||||
* @var $parent the parents of this component
|
||||
*/
|
||||
private $parent;
|
||||
/**
|
||||
* sets a given attribute
|
||||
*
|
||||
* @throws Doctrine_Exception if the value is invalid
|
||||
* @param integer $attribute
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
*/
|
||||
final public function setAttribute($attribute,$value) {
|
||||
switch($attribute):
|
||||
case Doctrine::ATTR_BATCH_SIZE:
|
||||
if($value < 0)
|
||||
throw new Doctrine_Exception("Batch size should be greater than or equal to zero");
|
||||
break;
|
||||
case Doctrine::ATTR_CACHE_DIR:
|
||||
if(substr(trim($value),0,6) == "%ROOT%") {
|
||||
$dir = dirname(__FILE__);
|
||||
$value = $dir.substr($value,6);
|
||||
}
|
||||
|
||||
if(! is_dir($value) && ! file_exists($value))
|
||||
mkdir($value,0777);
|
||||
break;
|
||||
case Doctrine::ATTR_CACHE_TTL:
|
||||
if($value < 1)
|
||||
throw new Doctrine_Exception("Cache TimeToLive should be greater than or equal to 1");
|
||||
break;
|
||||
case Doctrine::ATTR_CACHE_SIZE:
|
||||
if($value < 1)
|
||||
throw new Doctrine_Exception("Cache size should be greater than or equal to 1");
|
||||
break;
|
||||
case Doctrine::ATTR_CACHE_SLAM:
|
||||
if($value < 0 || $value > 1)
|
||||
throw new Doctrine_Exception("Cache slam defense should be a floating point number between 0 and 1");
|
||||
break;
|
||||
case Doctrine::ATTR_FETCHMODE:
|
||||
if($value < 0)
|
||||
throw new Doctrine_Exception("Unknown fetchmode. See Doctrine::FETCH_* constants.");
|
||||
break;
|
||||
case Doctrine::ATTR_LISTENER:
|
||||
$this->setEventListener($value);
|
||||
break;
|
||||
case Doctrine::ATTR_PK_COLUMNS:
|
||||
if( ! is_array($value))
|
||||
throw new Doctrine_Exception("The value of Doctrine::ATTR_PK_COLUMNS attribute must be an array");
|
||||
break;
|
||||
case Doctrine::ATTR_PK_TYPE:
|
||||
if($value != Doctrine::INCREMENT_KEY && $value != Doctrine::UNIQUE_KEY)
|
||||
throw new Doctrine_Exception("The value of Doctrine::ATTR_PK_TYPE attribute must be either Doctrine::INCREMENT_KEY or Doctrine::UNIQUE_KEY");
|
||||
|
||||
break;
|
||||
case Doctrine::ATTR_LOCKMODE:
|
||||
if($this instanceof Doctrine_Session) {
|
||||
if($this->getState() != Doctrine_Session::STATE_OPEN)
|
||||
throw new Doctrine_Exception("Couldn't set lockmode. There are transactions open.");
|
||||
|
||||
} elseif($this instanceof Doctrine_Manager) {
|
||||
foreach($this as $session) {
|
||||
if($session->getState() != Doctrine_Session::STATE_OPEN)
|
||||
throw new Doctrine_Exception("Couldn't set lockmode. There are transactions open.");
|
||||
}
|
||||
} else {
|
||||
throw new Doctrine_Exception("Lockmode attribute can only be set at the global or session level.");
|
||||
}
|
||||
break;
|
||||
case Doctrine::ATTR_CREATE_TABLES:
|
||||
$value = (bool) $value;
|
||||
break;
|
||||
case Doctrine::ATTR_COLL_LIMIT:
|
||||
if($value < 1) {
|
||||
throw new Doctrine_Exception("Collection limit should be a value greater than or equal to 1.");
|
||||
}
|
||||
break;
|
||||
case Doctrine::ATTR_COLL_KEY:
|
||||
if( ! ($this instanceof Doctrine_Table))
|
||||
throw new Doctrine_Exception("This attribute can only be set at table level.");
|
||||
|
||||
if( ! $this->hasColumn($value))
|
||||
throw new Doctrine_Exception("Couldn't set collection key attribute. No such column '$value'");
|
||||
|
||||
|
||||
break;
|
||||
case Doctrine::ATTR_VLD:
|
||||
|
||||
break;
|
||||
case Doctrine::ATTR_CACHE:
|
||||
if($value != Doctrine::CACHE_SQLITE && $value != Doctrine::CACHE_NONE)
|
||||
throw new Doctrine_Exception("Unknown cache container. See Doctrine::CACHE_* constants for availible containers.");
|
||||
break;
|
||||
default:
|
||||
throw new Doctrine_Exception("Unknown attribute.");
|
||||
endswitch;
|
||||
|
||||
$this->attributes[$attribute] = $value;
|
||||
|
||||
}
|
||||
/**
|
||||
* @param Doctrine_EventListener $listener
|
||||
* @return void
|
||||
*/
|
||||
final public function setEventListener(Doctrine_EventListener $listener) {
|
||||
$i = Doctrine::ATTR_LISTENER;
|
||||
$this->attributes[$i] = $listener;
|
||||
}
|
||||
/**
|
||||
* returns the value of an attribute
|
||||
*
|
||||
* @param integer $attribute
|
||||
* @return mixed
|
||||
*/
|
||||
final public function getAttribute($attribute) {
|
||||
$attribute = (int) $attribute;
|
||||
|
||||
if($attribute < 1 || $attribute > 16)
|
||||
throw new InvalidKeyException();
|
||||
|
||||
if( ! isset($this->attributes[$attribute])) {
|
||||
if(isset($this->parent))
|
||||
return $this->parent->getAttribute($attribute);
|
||||
|
||||
return null;
|
||||
}
|
||||
return $this->attributes[$attribute];
|
||||
}
|
||||
/**
|
||||
* getAttributes
|
||||
* returns all attributes as an array
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
final public function getAttributes() {
|
||||
return $this->attributes;
|
||||
}
|
||||
/**
|
||||
* sets a parent for this configurable component
|
||||
* the parent must be configurable component itself
|
||||
*
|
||||
* @param Doctrine_Configurable $component
|
||||
* @return void
|
||||
*/
|
||||
final public function setParent(Doctrine_Configurable $component) {
|
||||
$this->parent = $component;
|
||||
}
|
||||
/**
|
||||
* getParent
|
||||
* returns the parent of this component
|
||||
*
|
||||
* @return Doctrine_Configurable
|
||||
*/
|
||||
final public function getParent() {
|
||||
return $this->parent;
|
||||
}
|
||||
}
|
||||
?>
|
140
Doctrine/DB.php
Normal file
140
Doctrine/DB.php
Normal file
@ -0,0 +1,140 @@
|
||||
<?php
|
||||
class Doctrine_DB extends PDO implements Countable, IteratorAggregate {
|
||||
/**
|
||||
* default DSN
|
||||
*/
|
||||
const DSN = "mysql://root:dc34@localhost/test";
|
||||
/**
|
||||
* executed queries
|
||||
*/
|
||||
private $queries = array();
|
||||
/**
|
||||
* execution times of the executed queries
|
||||
*/
|
||||
private $exectimes = array();
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* @param string $dsn
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
*/
|
||||
public function __construct($dsn,$username,$password) {
|
||||
parent::__construct($dsn,$username,$password);
|
||||
$this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
$this->setAttribute(PDO::ATTR_STATEMENT_CLASS, array("Doctrine_DBStatement",array($this)));
|
||||
}
|
||||
|
||||
|
||||
public static function getConn($dsn,$username = null, $password = null) {
|
||||
static $instance;
|
||||
|
||||
if( ! isset($instance)) {
|
||||
$instance = new Doctrine_DB($dsn,$username,$password);
|
||||
}
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $dsn PEAR::DB like DSN
|
||||
* format: schema://user:password@address/dbname
|
||||
*/
|
||||
public static function getConnection($dsn = null) {
|
||||
static $instance = array();
|
||||
$md5 = md5($dsn);
|
||||
|
||||
if( ! isset($instance[$md5])) {
|
||||
if( ! isset($dsn)) {
|
||||
$a = parse_url(self::DSN);
|
||||
} else {
|
||||
$a = parse_url($dsn);
|
||||
}
|
||||
$e = array();
|
||||
|
||||
$e[0] = $a["scheme"].":host=".$a["host"].";dbname=".substr($a["path"],1);
|
||||
$e[1] = $a["user"];
|
||||
$e[2] = $a["pass"];
|
||||
|
||||
$instance[$md5] = new Doctrine_DB($e[0],$e[1],$e[2]);
|
||||
}
|
||||
return $instance[$md5];
|
||||
}
|
||||
/**
|
||||
* @param string $query query to be executed
|
||||
*/
|
||||
public function query($query) {
|
||||
try {
|
||||
$this->queries[] = $query;
|
||||
$time = microtime();
|
||||
|
||||
$stmt = parent::query($query);
|
||||
|
||||
$this->exectimes[] = (microtime() - $time);
|
||||
return $stmt;
|
||||
} catch(PDOException $e) {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @param string $query query to be prepared
|
||||
*/
|
||||
public function prepare($query) {
|
||||
$this->queries[] = $query;
|
||||
return parent::prepare($query);
|
||||
}
|
||||
/**
|
||||
* @param string $time exectime of the last executed query
|
||||
* @return void
|
||||
*/
|
||||
public function addExecTime($time) {
|
||||
$this->exectimes[] = $time;
|
||||
}
|
||||
|
||||
public function getExecTimes() {
|
||||
return $this->exectimes;
|
||||
}
|
||||
/**
|
||||
* @return array an array of executed queries
|
||||
*/
|
||||
public function getQueries() {
|
||||
return $this->queries;
|
||||
}
|
||||
/**
|
||||
* @return ArrayIterator
|
||||
*/
|
||||
public function getIterator() {
|
||||
return new ArrayIterator($this->queries);
|
||||
}
|
||||
/**
|
||||
* returns the number of executed queries
|
||||
* @return integer
|
||||
*/
|
||||
public function count() {
|
||||
return count($this->queries);
|
||||
}
|
||||
|
||||
}
|
||||
class Doctrine_DBStatement extends PDOStatement {
|
||||
/**
|
||||
* @param Doctrine_DB $dbh Doctrine Database Handler
|
||||
*/
|
||||
private $dbh;
|
||||
/**
|
||||
* @param Doctrine_DB $dbh
|
||||
*/
|
||||
private function __construct(Doctrine_DB $dbh) {
|
||||
$this->dbh = $dbh;
|
||||
}
|
||||
/**
|
||||
* @param array $params
|
||||
*/
|
||||
public function execute(array $params = null) {
|
||||
$time = microtime();
|
||||
$result = parent::execute($params);
|
||||
|
||||
$exectime = (microtime() - $time);
|
||||
$this->dbh->addExecTime($exectime);
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
?>
|
101
Doctrine/DataDict.php
Normal file
101
Doctrine/DataDict.php
Normal file
@ -0,0 +1,101 @@
|
||||
<?php
|
||||
class Doctrine_DataDict {
|
||||
private $dbh;
|
||||
public function __construct(PDO $dbh) {
|
||||
$manager = Doctrine_Manager::getInstance();
|
||||
require_once($manager->getRoot()."/adodb-hack/adodb.inc.php");
|
||||
|
||||
$this->dbh = $dbh;
|
||||
$this->dict = NewDataDictionary($dbh);
|
||||
}
|
||||
|
||||
public function metaColumns(Doctrine_Table $table) {
|
||||
return $this->dict->metaColumns($table->getTableName());
|
||||
}
|
||||
|
||||
|
||||
public function createTable($tablename, $columns) {
|
||||
foreach($columns as $name => $args) {
|
||||
$r[] = $name." ".$this->getADOType($args[0],$args[1])." ".str_replace("|"," ",$args[2]);
|
||||
}
|
||||
|
||||
|
||||
$r = implode(", ",$r);
|
||||
$a = $this->dict->createTableSQL($tablename,$r);
|
||||
|
||||
$return = true;
|
||||
foreach($a as $sql) {
|
||||
try {
|
||||
$this->dbh->query($sql);
|
||||
} catch(PDOException $e) {
|
||||
if($this->dbh->getAttribute(PDO::ATTR_DRIVER_NAME) == "sqlite")
|
||||
throw $e;
|
||||
$return = false;
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
/**
|
||||
* converts doctrine type to adodb type
|
||||
*
|
||||
* @param string $type column type
|
||||
* @param integer $length column length
|
||||
*/
|
||||
public function getADOType($type,$length) {
|
||||
switch($type):
|
||||
case "string":
|
||||
case "s":
|
||||
if($length < 255)
|
||||
return "C($length)";
|
||||
elseif($length < 4000)
|
||||
return "X";
|
||||
else
|
||||
return "X2";
|
||||
break;
|
||||
case "mbstring":
|
||||
if($length < 255)
|
||||
return "C2($length)";
|
||||
|
||||
return "X2";
|
||||
case "clob":
|
||||
return "XL";
|
||||
break;
|
||||
case "d":
|
||||
case "date":
|
||||
return "D";
|
||||
break;
|
||||
case "float":
|
||||
case "f":
|
||||
case "double":
|
||||
return "F";
|
||||
break;
|
||||
case "timestamp":
|
||||
case "t":
|
||||
return "T";
|
||||
break;
|
||||
case "boolean":
|
||||
case "bool":
|
||||
return "L";
|
||||
break;
|
||||
case "integer":
|
||||
case "int":
|
||||
case "i":
|
||||
if(empty($length))
|
||||
return "I8";
|
||||
elseif($length < 4)
|
||||
return "I1";
|
||||
elseif($length < 6)
|
||||
return "I2";
|
||||
elseif($length < 10)
|
||||
return "I4";
|
||||
elseif($length <= 20)
|
||||
return "I8";
|
||||
else
|
||||
throw new Doctrine_Exception("Too long integer (max length is 20).");
|
||||
|
||||
break;
|
||||
endswitch;
|
||||
}
|
||||
}
|
||||
?>
|
151
Doctrine/Debugger.php
Normal file
151
Doctrine/Debugger.php
Normal file
@ -0,0 +1,151 @@
|
||||
<?php
|
||||
require_once("EventListener.php");
|
||||
|
||||
class Doctrine_DebugMessage {
|
||||
private $code;
|
||||
private $object;
|
||||
public function __construct($object, $code) {
|
||||
$this->object = $object;
|
||||
$this->code = $code;
|
||||
}
|
||||
final public function getCode() {
|
||||
return $this->code;
|
||||
}
|
||||
final public function getObject() {
|
||||
return $this->object;
|
||||
}
|
||||
}
|
||||
class Doctrine_Debugger extends Doctrine_EventListener {
|
||||
const EVENT_LOAD = 1;
|
||||
const EVENT_PRELOAD = 2;
|
||||
const EVENT_SLEEP = 3;
|
||||
const EVENT_WAKEUP = 4;
|
||||
const EVENT_UPDATE = 5;
|
||||
const EVENT_PREUPDATE = 6;
|
||||
const EVENT_CREATE = 7;
|
||||
const EVENT_PRECREATE = 8;
|
||||
|
||||
const EVENT_SAVE = 9;
|
||||
const EVENT_PRESAVE = 10;
|
||||
const EVENT_INSERT = 11;
|
||||
const EVENT_PREINSERT = 12;
|
||||
const EVENT_DELETE = 13;
|
||||
const EVENT_PREDELETE = 14;
|
||||
const EVENT_EVICT = 15;
|
||||
const EVENT_PREEVICT = 16;
|
||||
const EVENT_CLOSE = 17;
|
||||
const EVENT_PRECLOSE = 18;
|
||||
|
||||
const EVENT_OPEN = 19;
|
||||
const EVENT_COMMIT = 20;
|
||||
const EVENT_PRECOMMIT = 21;
|
||||
const EVENT_ROLLBACK = 22;
|
||||
const EVENT_PREROLLBACK = 23;
|
||||
const EVENT_BEGIN = 24;
|
||||
const EVENT_PREBEGIN = 25;
|
||||
const EVENT_COLLDELETE = 26;
|
||||
const EVENT_PRECOLLDELETE = 27;
|
||||
private $debug;
|
||||
|
||||
public function getMessages() {
|
||||
return $this->debug;
|
||||
}
|
||||
|
||||
|
||||
public function onLoad(Doctrine_Record $record) {
|
||||
$this->debug[] = new Doctrine_DebugMessage($record,self::EVENT_LOAD);
|
||||
}
|
||||
public function onPreLoad(Doctrine_Record $record) {
|
||||
$this->debug[] = new Doctrine_DebugMessage($record,self::EVENT_PRELOAD);
|
||||
}
|
||||
|
||||
public function onSleep(Doctrine_Record $record) {
|
||||
$this->debug[] = new Doctrine_DebugMessage($record,self::EVENT_SLEEP);
|
||||
}
|
||||
|
||||
public function onWakeUp(Doctrine_Record $record) {
|
||||
$this->debug[] = new Doctrine_DebugMessage($record,self::EVENT_WAKEUP);
|
||||
}
|
||||
|
||||
public function onUpdate(Doctrine_Record $record) {
|
||||
$this->debug[] = new Doctrine_DebugMessage($record,self::EVENT_UPDATE);
|
||||
}
|
||||
public function onPreUpdate(Doctrine_Record $record) {
|
||||
$this->debug[] = new Doctrine_DebugMessage($record,self::EVENT_PREUPDATE);
|
||||
}
|
||||
|
||||
public function onCreate(Doctrine_Record $record) {
|
||||
$this->debug[] = new Doctrine_DebugMessage($record,self::EVENT_CREATE);
|
||||
}
|
||||
public function onPreCreate(Doctrine_Record $record) {
|
||||
$this->debug[] = new Doctrine_DebugMessage($record,self::EVENT_PRECREATE);
|
||||
}
|
||||
|
||||
public function onSave(Doctrine_Record $record) {
|
||||
$this->debug[] = new Doctrine_DebugMessage($record,self::EVENT_SAVE);
|
||||
}
|
||||
public function onPreSave(Doctrine_Record $record) {
|
||||
$this->debug[] = new Doctrine_DebugMessage($record,self::EVENT_PRESAVE);
|
||||
}
|
||||
|
||||
public function onInsert(Doctrine_Record $record) {
|
||||
$this->debug[] = new Doctrine_DebugMessage($record,self::EVENT_INSERT);
|
||||
}
|
||||
public function onPreInsert(Doctrine_Record $record) {
|
||||
$this->debug[] = new Doctrine_DebugMessage($record,self::EVENT_PREINSERT);
|
||||
}
|
||||
|
||||
public function onDelete(Doctrine_Record $record) {
|
||||
$this->debug[] = new Doctrine_DebugMessage($record,self::EVENT_DELETE);
|
||||
}
|
||||
public function onPreDelete(Doctrine_Record $record) {
|
||||
$this->debug[] = new Doctrine_DebugMessage($record,self::EVENT_PREDELETE);
|
||||
}
|
||||
|
||||
public function onEvict(Doctrine_Record $record) {
|
||||
$this->debug[] = new Doctrine_DebugMessage($record,self::EVENT_EVICT);
|
||||
}
|
||||
public function onPreEvict(Doctrine_Record $record) {
|
||||
$this->debug[] = new Doctrine_DebugMessage($record,self::EVENT_PREEVICT);
|
||||
}
|
||||
|
||||
public function onClose(Doctrine_Session $session) {
|
||||
$this->debug[] = new Doctrine_DebugMessage($session,self::EVENT_CLOSE);
|
||||
}
|
||||
public function onPreClose(Doctrine_Session $session) {
|
||||
$this->debug[] = new Doctrine_DebugMessage($session,self::EVENT_PRECLOSE);
|
||||
}
|
||||
|
||||
public function onOpen(Doctrine_Session $session) {
|
||||
$this->debug[] = new Doctrine_DebugMessage($session,self::EVENT_OPEN);
|
||||
}
|
||||
|
||||
public function onTransactionCommit(Doctrine_Session $session) {
|
||||
$this->debug[] = new Doctrine_DebugMessage($session,self::EVENT_COMMIT);
|
||||
}
|
||||
public function onPreTransactionCommit(Doctrine_Session $session) {
|
||||
$this->debug[] = new Doctrine_DebugMessage($session,self::EVENT_PRECOMMIT);
|
||||
}
|
||||
|
||||
public function onTransactionRollback(Doctrine_Session $session) {
|
||||
$this->debug[] = new Doctrine_DebugMessage($session,self::EVENT_ROLLBACK);
|
||||
}
|
||||
public function onPreTransactionRollback(Doctrine_Session $session) {
|
||||
$this->debug[] = new Doctrine_DebugMessage($session,self::EVENT_PREROLLBACK);
|
||||
}
|
||||
|
||||
public function onTransactionBegin(Doctrine_Session $session) {
|
||||
$this->debug[] = new Doctrine_DebugMessage($session,self::EVENT_BEGIN);
|
||||
}
|
||||
public function onPreTransactionBegin(Doctrine_Session $session) {
|
||||
$this->debug[] = new Doctrine_DebugMessage($session,self::EVENT_PREBEGIN);
|
||||
}
|
||||
|
||||
public function onCollectionDelete(Doctrine_Collection $collection) {
|
||||
$this->debug[] = new Doctrine_DebugMessage($collection,self::EVENT_COLLDELETE);
|
||||
}
|
||||
public function onPreCollectionDelete(Doctrine_Collection $collection) {
|
||||
$this->debug[] = new Doctrine_DebugMessage($collection,self::EVENT_PRECOLLDELETE);
|
||||
}
|
||||
}
|
||||
?>
|
124
Doctrine/EventListener.php
Normal file
124
Doctrine/EventListener.php
Normal file
@ -0,0 +1,124 @@
|
||||
<?php
|
||||
/**
|
||||
* interface for event listening, forces all classes that extend
|
||||
* Doctrine_EventListener to have the same method arguments as their parent
|
||||
*/
|
||||
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 onSaveCascade(Doctrine_Record $record);
|
||||
public function onPreSaveCascade(Doctrine_Record $record);
|
||||
|
||||
public function onDeleteCascade(Doctrine_Record $record);
|
||||
public function onPreDeleteCascade(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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Doctrine_EventListener all event listeners extend this base class
|
||||
* the empty methods allow child classes to only implement the methods they need to implement
|
||||
*
|
||||
*
|
||||
* @author Konsta Vesterinen
|
||||
* @package Doctrine ORM
|
||||
* @url www.phpdoctrine.com
|
||||
* @license LGPL
|
||||
* @version 1.0 alpha
|
||||
*
|
||||
*/
|
||||
abstract class Doctrine_EventListener implements iDoctrine_EventListener {
|
||||
|
||||
public function onLoad(Doctrine_Record $record) { }
|
||||
public function onPreLoad(Doctrine_Record $record) { }
|
||||
|
||||
public function onSleep(Doctrine_Record $record) { }
|
||||
|
||||
public function onWakeUp(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 onSaveCascade(Doctrine_Record $record) { }
|
||||
public function onPreSaveCascade(Doctrine_Record $record) { }
|
||||
|
||||
public function onDeleteCascade(Doctrine_Record $record) { }
|
||||
public function onPreDeleteCascade(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) { }
|
||||
}
|
||||
/**
|
||||
* an emtpy listener all components use this by default
|
||||
*/
|
||||
class EmptyEventListener extends Doctrine_EventListener { }
|
||||
|
||||
?>
|
6
Doctrine/Exception.php
Normal file
6
Doctrine/Exception.php
Normal file
@ -0,0 +1,6 @@
|
||||
<?php
|
||||
class InvalidKeyException extends Exception { }
|
||||
class InvalidTypeException extends Exception { }
|
||||
class Doctrine_Exception extends Exception { }
|
||||
class DQLException extends Doctrine_Exception { }
|
||||
?>
|
7
Doctrine/ForeignKey.php
Normal file
7
Doctrine/ForeignKey.php
Normal file
@ -0,0 +1,7 @@
|
||||
<?php
|
||||
require_once("Relation.php");
|
||||
/**
|
||||
* Foreign Key
|
||||
*/
|
||||
class Doctrine_ForeignKey extends Doctrine_Relation { }
|
||||
?>
|
77
Doctrine/Form.class.php
Normal file
77
Doctrine/Form.class.php
Normal file
@ -0,0 +1,77 @@
|
||||
<?php
|
||||
class Doctrine_Form implements Iterator {
|
||||
protected $record;
|
||||
protected $elements = array();
|
||||
protected $columns;
|
||||
protected $current;
|
||||
protected $keys;
|
||||
protected $index;
|
||||
protected $count;
|
||||
public function __construct(Doctrine_Record $record) {
|
||||
$this->record = $record;
|
||||
$this->columns = $record->getTable()->getColumns();
|
||||
$this->keys = array_keys($this->columns);
|
||||
$this->index = 0;
|
||||
$this->count = count($this->keys);
|
||||
}
|
||||
public function current() {
|
||||
$i = $this->index;
|
||||
$column = $this->keys[$i];
|
||||
|
||||
$definitions = $this->columns[$column];
|
||||
|
||||
$e = explode("|",$definitions[2]);
|
||||
$enum = false;
|
||||
foreach($e as $v) {
|
||||
$e2 = explode(":",$v);
|
||||
if($e2[0] == "enum") {
|
||||
$enum = explode("-",$e2[1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
$length = $definitions[1];
|
||||
if( ! in_array("autoincrement",$e) && ! in_array("protected",$e)) {
|
||||
if($enum) {
|
||||
$elements[$column] = "<select name='data[$column]'>\n";
|
||||
foreach($enum as $k => $v) {
|
||||
if($this->record->get($column) == $k) {
|
||||
$str = 'selected';
|
||||
} else
|
||||
$str = '';
|
||||
|
||||
$elements[$column] .= " <option value='$k' $str>$v</option>\n";
|
||||
}
|
||||
$elements[$column] .= "</select>\n";
|
||||
} else {
|
||||
if($length <= 255) {
|
||||
$elements[$column] = "<input name='data[$column]' type='text' value='".$this->record->get($column)."' maxlength=$length \>\n";
|
||||
} else {
|
||||
$elements[$column] = "<textarea name='data[$column]' cols=40 rows=10>".$this->record->get($column)."</textarea>\n";
|
||||
}
|
||||
}
|
||||
return $elements[$column];
|
||||
} else {
|
||||
$this->index++;
|
||||
|
||||
if($this->index < $this->count)
|
||||
return self::current();
|
||||
}
|
||||
}
|
||||
public function key() {
|
||||
$i = $this->index;
|
||||
return $this->keys[$i];
|
||||
}
|
||||
public function next() {
|
||||
$this->index++;
|
||||
}
|
||||
public function rewind() {
|
||||
$this->index = 0;
|
||||
}
|
||||
public function valid() {
|
||||
if($this->index >= $this->count)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
?>
|
24
Doctrine/Identifier.php
Normal file
24
Doctrine/Identifier.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
class Doctrine_Identifier {
|
||||
/**
|
||||
* constant for unique identifier
|
||||
*/
|
||||
const UNIQUE = 0;
|
||||
/**
|
||||
* constant for auto_increment identifier
|
||||
*/
|
||||
const AUTO_INCREMENT = 1;
|
||||
/**
|
||||
* constant for sequence identifier
|
||||
*/
|
||||
const SEQUENCE = 2;
|
||||
/**
|
||||
* constant for normal identifier
|
||||
*/
|
||||
const NORMAL = 3;
|
||||
/**
|
||||
* constant for composite identifier
|
||||
*/
|
||||
const COMPOSITE = 4;
|
||||
}
|
||||
?>
|
51
Doctrine/IdentityMap.class.php
Normal file
51
Doctrine/IdentityMap.class.php
Normal file
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
abstract class Doctrine_Creator {
|
||||
protected $_table;
|
||||
/**
|
||||
* constructor
|
||||
*
|
||||
* @param Doctrine_Table $table
|
||||
*/
|
||||
public function __construct(Doctrine_Table $table) {
|
||||
$this->_table = $_table;
|
||||
}
|
||||
|
||||
|
||||
abstract public function get();
|
||||
}
|
||||
class Doctrine_IdentityMap {
|
||||
private $identityMap = array();
|
||||
|
||||
/**
|
||||
* first checks if record exists in identityMap, if not
|
||||
* returns a new record
|
||||
*
|
||||
* @return Doctrine_Record
|
||||
*/
|
||||
public function get() {
|
||||
$key = $this->getIdentifier();
|
||||
|
||||
if( ! is_array($key))
|
||||
$key = array($key);
|
||||
|
||||
|
||||
foreach($key as $k) {
|
||||
if( ! isset($this->data[$k]))
|
||||
throw new Doctrine_Exception("No primary key found");
|
||||
|
||||
$id[] = $this->data[$k];
|
||||
}
|
||||
$id = implode(' ', $id);
|
||||
|
||||
if(isset($this->identityMap[$id]))
|
||||
$record = $this->identityMap[$id];
|
||||
else {
|
||||
$record = new $this->name($this);
|
||||
$this->identityMap[$id] = $record;
|
||||
}
|
||||
$this->data = array();
|
||||
|
||||
return $record;
|
||||
}
|
||||
}
|
||||
?>
|
25
Doctrine/IndexGenerator.php
Normal file
25
Doctrine/IndexGenerator.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
class Doctrine_IndexGenerator {
|
||||
/**
|
||||
* @var string $name
|
||||
*/
|
||||
private $name;
|
||||
/**
|
||||
* @param string $name
|
||||
*/
|
||||
public function __construct($name) {
|
||||
$this->name = $name;
|
||||
}
|
||||
/**
|
||||
* @param Doctrine_Record $record
|
||||
* @return mixed
|
||||
*/
|
||||
public function getIndex(Doctrine_Record $record) {
|
||||
$value = $record->get($this->name);
|
||||
if($value === null)
|
||||
throw new Doctrine_Exception("Couldn't create collection index. Record field '".$this->name."' was null.");
|
||||
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
?>
|
83
Doctrine/Iterator.php
Normal file
83
Doctrine/Iterator.php
Normal file
@ -0,0 +1,83 @@
|
||||
<?php
|
||||
/**
|
||||
* Doctrine_Iterator
|
||||
* iterates through Doctrine_Collection
|
||||
*
|
||||
* @package Doctrine ORM
|
||||
* @url www.phpdoctrine.com
|
||||
* @license LGPL
|
||||
*/
|
||||
abstract class Doctrine_Iterator implements Iterator {
|
||||
/**
|
||||
* @var Doctrine_Collection $collection
|
||||
*/
|
||||
protected $collection;
|
||||
/**
|
||||
* @var array $keys
|
||||
*/
|
||||
protected $keys;
|
||||
/**
|
||||
* @var mixed $key
|
||||
*/
|
||||
protected $key;
|
||||
/**
|
||||
* @var integer $index
|
||||
*/
|
||||
protected $index;
|
||||
/**
|
||||
* @var integer $count
|
||||
*/
|
||||
protected $count;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* @var Doctrine_Collection $collection
|
||||
*/
|
||||
public function __construct(Doctrine_Collection $collection) {
|
||||
$this->collection = $collection;
|
||||
$this->keys = $this->collection->getKeys();
|
||||
$this->count = $this->collection->count();
|
||||
}
|
||||
/**
|
||||
* rewinds the iterator
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function rewind() {
|
||||
$this->index = 0;
|
||||
$i = $this->index;
|
||||
if(isset($this->keys[$i]))
|
||||
$this->key = $this->keys[$i];
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the current key
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function key() {
|
||||
return $this->key;
|
||||
}
|
||||
/**
|
||||
* returns the current record
|
||||
*
|
||||
* @return Doctrine_Record
|
||||
*/
|
||||
public function current() {
|
||||
return $this->collection->get($this->key);
|
||||
}
|
||||
/**
|
||||
* advances the internal pointer
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function next() {
|
||||
$this->index++;
|
||||
$i = $this->index;
|
||||
if(isset($this->keys[$i]))
|
||||
$this->key = $this->keys[$i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
?>
|
140
Doctrine/Lib.php
Normal file
140
Doctrine/Lib.php
Normal file
@ -0,0 +1,140 @@
|
||||
<?php
|
||||
class Doctrine_Lib {
|
||||
/**
|
||||
* @param integer $state the state of record
|
||||
* @see Doctrine_Record::STATE_* constants
|
||||
* @return string string representation of given state
|
||||
*/
|
||||
public static function getRecordStateAsString($state) {
|
||||
switch($state):
|
||||
case Doctrine_Record::STATE_PROXY:
|
||||
return "proxy";
|
||||
break;
|
||||
case Doctrine_Record::STATE_CLEAN:
|
||||
return "persistent clean";
|
||||
break;
|
||||
case Doctrine_Record::STATE_DIRTY:
|
||||
return "persistent dirty";
|
||||
break;
|
||||
case Doctrine_Record::STATE_TDIRTY:
|
||||
return "transient dirty";
|
||||
break;
|
||||
case Doctrine_Record::STATE_TCLEAN:
|
||||
return "transient clean";
|
||||
break;
|
||||
endswitch;
|
||||
}
|
||||
/**
|
||||
* returns a string representation of Doctrine_Record object
|
||||
* @param Doctrine_Record $record
|
||||
* @return string
|
||||
*/
|
||||
public function getRecordAsString(Doctrine_Record $record) {
|
||||
$r[] = "<pre>";
|
||||
$r[] = "Component : ".$record->getTable()->getComponentName();
|
||||
$r[] = "ID : ".$record->getID();
|
||||
$r[] = "References : ".count($record->getReferences());
|
||||
$r[] = "State : ".Doctrine_Lib::getRecordStateAsString($record->getState());
|
||||
$r[] = "OID : ".$record->getOID();
|
||||
$r[] = "</pre>";
|
||||
return implode("\n",$r)."<br />";
|
||||
}
|
||||
/**
|
||||
* getStateAsString
|
||||
* returns a given session state as string
|
||||
* @param integer $state session state
|
||||
*/
|
||||
public static function getSessionStateAsString($state) {
|
||||
switch($state):
|
||||
case Doctrine_Session::STATE_OPEN:
|
||||
return "open";
|
||||
break;
|
||||
case Doctrine_Session::STATE_CLOSED:
|
||||
return "closed";
|
||||
break;
|
||||
case Doctrine_Session::STATE_BUSY:
|
||||
return "busy";
|
||||
break;
|
||||
case Doctrine_Session::STATE_ACTIVE:
|
||||
return "active";
|
||||
break;
|
||||
endswitch;
|
||||
}
|
||||
/**
|
||||
* returns a string representation of Doctrine_Session object
|
||||
* @param Doctrine_Session $session
|
||||
* @return string
|
||||
*/
|
||||
public function getSessionAsString(Doctrine_Session $session) {
|
||||
$r[] = "<pre>";
|
||||
$r[] = "Doctrine_Session object";
|
||||
$r[] = "State : ".Doctrine_Lib::getSessionStateAsString($session->getState());
|
||||
$r[] = "Open Transactions : ".$session->getTransactionLevel();
|
||||
$r[] = "Open Factories : ".$session->count();
|
||||
$sum = 0;
|
||||
$rsum = 0;
|
||||
$csum = 0;
|
||||
foreach($session->getTables() as $objTable) {
|
||||
if($objTable->getCache() instanceof Doctrine_Cache_File) {
|
||||
$sum += array_sum($objTable->getCache()->getStats());
|
||||
$rsum += $objTable->getRepository()->count();
|
||||
$csum += $objTable->getCache()->count();
|
||||
}
|
||||
}
|
||||
$r[] = "Cache Hits : ".$sum." hits ";
|
||||
$r[] = "Cache : ".$csum." objects ";
|
||||
|
||||
$r[] = "Repositories : ".$rsum." objects ";
|
||||
$queries = false;
|
||||
if($session->getDBH() instanceof Doctrine_DB) {
|
||||
$handler = "Doctrine Database Handler";
|
||||
$queries = count($session->getDBH()->getQueries());
|
||||
$sum = array_sum($session->getDBH()->getExecTimes());
|
||||
} elseif($session->getDBH() instanceof PDO) {
|
||||
$handler = "PHP Native PDO Driver";
|
||||
} else
|
||||
$handler = "Unknown Database Handler";
|
||||
|
||||
$r[] = "DB Handler : ".$handler;
|
||||
if($queries) {
|
||||
$r[] = "Executed Queries : ".$queries;
|
||||
$r[] = "Sum of Exec Times : ".$sum;
|
||||
}
|
||||
|
||||
$r[] = "</pre>";
|
||||
return implode("\n",$r)."<br>";
|
||||
}
|
||||
/**
|
||||
* returns a string representation of Doctrine_Table object
|
||||
* @param Doctrine_Table $table
|
||||
* @return string
|
||||
*/
|
||||
public function getTableAsString(Doctrine_Table $table) {
|
||||
$r[] = "<pre>";
|
||||
$r[] = "Component : ".$this->getComponentName();
|
||||
$r[] = "Table : ".$this->getTableName();
|
||||
$r[] = "Repository : ".$this->getRepository()->count()." objects";
|
||||
if($table->getCache() instanceof Doctrine_Cache_File) {
|
||||
$r[] = "Cache : ".$this->getCache()->count()." objects";
|
||||
$r[] = "Cache hits : ".array_sum($this->getCache()->getStats())." hits";
|
||||
}
|
||||
$r[] = "</pre>";
|
||||
return implode("\n",$r)."<br>";
|
||||
}
|
||||
/**
|
||||
* returns a string representation of Doctrine_Collection object
|
||||
* @param Doctrine_Collection $collection
|
||||
* @return string
|
||||
*/
|
||||
public function getCollectionAsString(Doctrine_Collection $collection) {
|
||||
$r[] = "<pre>";
|
||||
$r[] = get_class($collection);
|
||||
|
||||
foreach($collection as $key => $record) {
|
||||
$r[] = "Key : ".$key." ID : ".$record->getID();
|
||||
}
|
||||
$r[] = "</pre>";
|
||||
return implode("\n",$r);
|
||||
}
|
||||
}
|
||||
?>
|
7
Doctrine/LocalKey.php
Normal file
7
Doctrine/LocalKey.php
Normal file
@ -0,0 +1,7 @@
|
||||
<?php
|
||||
require_once("Relation.php");
|
||||
/**
|
||||
* Local Key
|
||||
*/
|
||||
class Doctrine_LocalKey extends Doctrine_Relation { }
|
||||
?>
|
249
Doctrine/Manager.php
Normal file
249
Doctrine/Manager.php
Normal file
@ -0,0 +1,249 @@
|
||||
<?php
|
||||
require_once("Configurable.php");
|
||||
require_once("EventListener.php");
|
||||
/**
|
||||
* @package Doctrine ORM
|
||||
* @url www.phpdoctrine.com
|
||||
* @license LGPL
|
||||
*
|
||||
* Doctrine_Manager is the base component of all doctrine based projects.
|
||||
* It opens and keeps track of all sessions (database connections).
|
||||
*/
|
||||
class Doctrine_Manager extends Doctrine_Configurable implements Countable, IteratorAggregate {
|
||||
/**
|
||||
* @var array $session an array containing all the opened sessions
|
||||
*/
|
||||
private $sessions = array();
|
||||
/**
|
||||
* @var integer $index the incremented index
|
||||
*/
|
||||
private $index = 0;
|
||||
/**
|
||||
* @var integer $currIndex the current session index
|
||||
*/
|
||||
private $currIndex = 0;
|
||||
/**
|
||||
* @var string $root root directory
|
||||
*/
|
||||
private $root;
|
||||
/**
|
||||
* @var Doctrine_Null $null Doctrine_Null object, used for extremely fast null value checking
|
||||
*/
|
||||
private $null;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
*/
|
||||
private function __construct() {
|
||||
$this->root = dirname(__FILE__);
|
||||
$this->null = new Doctrine_Null;
|
||||
|
||||
Doctrine_Record::initNullObject($this->null);
|
||||
Doctrine_Collection::initNullObject($this->null);
|
||||
}
|
||||
/**
|
||||
* @return Doctrine_Null
|
||||
*/
|
||||
final public function getNullObject() {
|
||||
return $this->null;
|
||||
}
|
||||
/**
|
||||
* setDefaultAttributes
|
||||
* sets default attributes
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
final public function setDefaultAttributes() {
|
||||
static $init = false;
|
||||
if( ! $init) {
|
||||
$init = true;
|
||||
$attributes = array(
|
||||
Doctrine::ATTR_CACHE_DIR => "%ROOT%".DIRECTORY_SEPARATOR."cachedir",
|
||||
Doctrine::ATTR_FETCHMODE => Doctrine::FETCH_LAZY,
|
||||
Doctrine::ATTR_CACHE_TTL => 100,
|
||||
Doctrine::ATTR_CACHE_SIZE => 100,
|
||||
Doctrine::ATTR_CACHE => Doctrine::CACHE_NONE,
|
||||
Doctrine::ATTR_BATCH_SIZE => 5,
|
||||
Doctrine::ATTR_COLL_LIMIT => 5,
|
||||
Doctrine::ATTR_LISTENER => new EmptyEventListener(),
|
||||
Doctrine::ATTR_PK_COLUMNS => array("id"),
|
||||
Doctrine::ATTR_PK_TYPE => Doctrine::INCREMENT_KEY,
|
||||
Doctrine::ATTR_LOCKMODE => 1,
|
||||
Doctrine::ATTR_VLD => false,
|
||||
Doctrine::ATTR_CREATE_TABLES => true
|
||||
);
|
||||
foreach($attributes as $attribute => $value) {
|
||||
$old = $this->getAttribute($attribute);
|
||||
if($old === null)
|
||||
$this->setAttribute($attribute,$value);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* returns the root directory of Doctrine
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
final public function getRoot() {
|
||||
return $this->root;
|
||||
}
|
||||
/**
|
||||
* getInstance
|
||||
* returns an instance of this class
|
||||
* (this class uses the singleton pattern)
|
||||
*
|
||||
* @return Doctrine_Manager
|
||||
*/
|
||||
final public static function getInstance() {
|
||||
static $instance;
|
||||
if( ! isset($instance))
|
||||
$instance = new self();
|
||||
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* openSession
|
||||
* opens a new session and saves it to Doctrine_Manager->sessions
|
||||
*
|
||||
* @param PDO $pdo PDO database driver
|
||||
* @param string $name name of the session, if empty numeric key is used
|
||||
* @return Doctrine_Session
|
||||
*/
|
||||
final public function openSession(PDO $pdo, $name = null) {
|
||||
// initialize the default attributes
|
||||
$this->setDefaultAttributes();
|
||||
|
||||
if($name !== null) {
|
||||
$name = (string) $name;
|
||||
if(isset($this->sessions[$name]))
|
||||
throw new InvalidKeyException();
|
||||
|
||||
} else {
|
||||
$name = $this->index;
|
||||
$this->index++;
|
||||
}
|
||||
switch($pdo->getAttribute(PDO::ATTR_DRIVER_NAME)):
|
||||
case "mysql":
|
||||
$this->sessions[$name] = new Doctrine_Session_Mysql($this,$pdo);
|
||||
break;
|
||||
case "sqlite":
|
||||
$this->sessions[$name] = new Doctrine_Session_Sqlite($this,$pdo);
|
||||
break;
|
||||
case "pgsql":
|
||||
$this->sessions[$name] = new Doctrine_Session_Pgsql($this,$pdo);
|
||||
break;
|
||||
case "oci":
|
||||
$this->sessions[$name] = new Doctrine_Session_Oracle($this,$pdo);
|
||||
break;
|
||||
case "mssql":
|
||||
$this->sessions[$name] = new Doctrine_Session_Mssql($this,$pdo);
|
||||
break;
|
||||
case "firebird":
|
||||
$this->sessions[$name] = new Doctrine_Session_Firebird($this,$pdo);
|
||||
break;
|
||||
case "informix":
|
||||
$this->sessions[$name] = new Doctrine_Session_Informix($this,$pdo);
|
||||
break;
|
||||
endswitch;
|
||||
|
||||
|
||||
$this->currIndex = $name;
|
||||
return $this->sessions[$name];
|
||||
}
|
||||
/**
|
||||
* getSession
|
||||
* @param integer $index
|
||||
* @return object Doctrine_Session
|
||||
* @throws InvalidKeyException
|
||||
*/
|
||||
final public function getSession($index) {
|
||||
if( ! isset($this->sessions[$index]))
|
||||
throw new InvalidKeyException();
|
||||
|
||||
$this->currIndex = $index;
|
||||
return $this->sessions[$index];
|
||||
}
|
||||
/**
|
||||
* closes the session
|
||||
*
|
||||
* @param Doctrine_Session $session
|
||||
* @return void
|
||||
*/
|
||||
final public function closeSession(Doctrine_Session $session) {
|
||||
$session->close();
|
||||
unset($session);
|
||||
}
|
||||
/**
|
||||
* getSessions
|
||||
* returns all opened sessions
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
final public function getSessions() {
|
||||
return $this->sessions;
|
||||
}
|
||||
/**
|
||||
* setCurrentSession
|
||||
* sets the current session to $key
|
||||
*
|
||||
* @param mixed $key the session key
|
||||
* @throws InvalidKeyException
|
||||
* @return void
|
||||
*/
|
||||
final public function setCurrentSession($key) {
|
||||
$key = (string) $key;
|
||||
if( ! isset($this->sessions[$key]))
|
||||
throw new InvalidKeyException();
|
||||
|
||||
$this->currIndex = $key;
|
||||
}
|
||||
/**
|
||||
* count
|
||||
* returns the number of opened sessions
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function count() {
|
||||
return count($this->sessions);
|
||||
}
|
||||
/**
|
||||
* getIterator
|
||||
* returns an ArrayIterator that iterates through all sessions
|
||||
*
|
||||
* @return ArrayIterator
|
||||
*/
|
||||
public function getIterator() {
|
||||
return new ArrayIterator($this->sessions);
|
||||
}
|
||||
/**
|
||||
* getCurrentSession
|
||||
* returns the current session
|
||||
*
|
||||
* @throws Doctrine_Session_Exception if there are no open sessions
|
||||
* @return Doctrine_Session
|
||||
*/
|
||||
final public function getCurrentSession() {
|
||||
$i = $this->currIndex;
|
||||
if( ! isset($this->sessions[$i]))
|
||||
throw new Doctrine_Session_Exception();
|
||||
|
||||
return $this->sessions[$i];
|
||||
}
|
||||
/**
|
||||
* __toString
|
||||
* returns a string representation of this object
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString() {
|
||||
$r[] = "<pre>";
|
||||
$r[] = "Doctrine_Manager";
|
||||
$r[] = "Sessions : ".count($this->sessions);
|
||||
$r[] = "</pre>";
|
||||
return implode("\n",$r);
|
||||
}
|
||||
}
|
||||
?>
|
60
Doctrine/Module.class.php
Normal file
60
Doctrine/Module.class.php
Normal file
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
class Doctrine_Module implements IteratorAggregate, Countable {
|
||||
/**
|
||||
* @var array $components an array containing all the components in this module
|
||||
*/
|
||||
private $components = array();
|
||||
/**
|
||||
* @var string $name the name of this module
|
||||
*/
|
||||
private $name;
|
||||
/**
|
||||
* constructor
|
||||
*
|
||||
* @param string $name the name of this module
|
||||
*/
|
||||
public function __construct($name) {
|
||||
$this->name = $name;
|
||||
}
|
||||
/**
|
||||
* returns the name of this module
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName() {
|
||||
return $this->name;
|
||||
}
|
||||
/**
|
||||
* flush
|
||||
* saves all components
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function flush() {
|
||||
$session = Doctrine_Manager::getInstance()->getCurrentSession();
|
||||
|
||||
$tree = $session->buildFlushTree($this->components);
|
||||
}
|
||||
/**
|
||||
* getIterator
|
||||
* this class implements IteratorAggregate interface
|
||||
* returns an iterator that iterates through the components
|
||||
* in this module
|
||||
*
|
||||
* @return ArrayIterator
|
||||
*/
|
||||
public function getIterator() {
|
||||
return new ArrayIterator($this->components);
|
||||
}
|
||||
/**
|
||||
* count
|
||||
* this class implements Countable interface
|
||||
* returns the number of components in this module
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function count() {
|
||||
return count($this->components);
|
||||
}
|
||||
}
|
||||
?>
|
6
Doctrine/Null.php
Normal file
6
Doctrine/Null.php
Normal file
@ -0,0 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* Doctrine_Null
|
||||
*/
|
||||
class Doctrine_Null { }
|
||||
?>
|
1005
Doctrine/Query.php
Normal file
1005
Doctrine/Query.php
Normal file
File diff suppressed because it is too large
Load Diff
1110
Doctrine/Record.php
Normal file
1110
Doctrine/Record.php
Normal file
File diff suppressed because it is too large
Load Diff
101
Doctrine/Relation.php
Normal file
101
Doctrine/Relation.php
Normal file
@ -0,0 +1,101 @@
|
||||
<?php
|
||||
/**
|
||||
* Doctrine_Relation
|
||||
*
|
||||
* @package Doctrine ORM
|
||||
* @url www.phpdoctrine.com
|
||||
* @license LGPL
|
||||
*/
|
||||
class Doctrine_Relation {
|
||||
/**
|
||||
* RELATION CONSTANTS
|
||||
*/
|
||||
|
||||
/**
|
||||
* constant for ONE_TO_ONE and MANY_TO_ONE aggregate relationships
|
||||
*/
|
||||
const ONE_AGGREGATE = 0;
|
||||
/**
|
||||
* constant for ONE_TO_ONE and MANY_TO_ONE composite relationships
|
||||
*/
|
||||
const ONE_COMPOSITE = 1;
|
||||
/**
|
||||
* constant for MANY_TO_MANY and ONE_TO_MANY aggregate relationships
|
||||
*/
|
||||
const MANY_AGGREGATE = 2;
|
||||
/**
|
||||
* constant for MANY_TO_MANY and ONE_TO_MANY composite relationships
|
||||
*/
|
||||
const MANY_COMPOSITE = 3;
|
||||
|
||||
|
||||
/**
|
||||
* @var Doctrine_Table $table foreign factory
|
||||
*/
|
||||
private $table;
|
||||
/**
|
||||
* @var string $local local field
|
||||
*/
|
||||
private $local;
|
||||
/**
|
||||
* @var string $foreign foreign field
|
||||
*/
|
||||
private $foreign;
|
||||
/**
|
||||
* @var integer $type bind type
|
||||
*/
|
||||
private $type;
|
||||
/**
|
||||
* @param Doctrine_Table $table
|
||||
* @param string $local
|
||||
* @param string $foreign
|
||||
* @param integer $type
|
||||
*/
|
||||
public function __construct(Doctrine_Table $table,$local,$foreign,$type) {
|
||||
$this->table = $table;
|
||||
$this->local = $local;
|
||||
$this->foreign = $foreign;
|
||||
$this->type = $type;
|
||||
}
|
||||
/**
|
||||
* @return integer bind type 1 or 0
|
||||
*/
|
||||
public function getType() {
|
||||
return $this->type;
|
||||
}
|
||||
/**
|
||||
* @return object Doctrine_Table foreign factory object
|
||||
*/
|
||||
public function getTable() {
|
||||
return $this->table;
|
||||
}
|
||||
/**
|
||||
* @return string the name of the local column
|
||||
*/
|
||||
public function getLocal() {
|
||||
return $this->local;
|
||||
}
|
||||
/**
|
||||
* @return string the name of the foreign column where
|
||||
* the local column is pointing at
|
||||
*/
|
||||
public function getForeign() {
|
||||
return $this->foreign;
|
||||
}
|
||||
/**
|
||||
* __toString
|
||||
*/
|
||||
public function __toString() {
|
||||
$r[] = "<pre>";
|
||||
$r[] = "Class : ".get_class($this);
|
||||
$r[] = "Component : ".$this->table->getComponentName();
|
||||
$r[] = "Table : ".$this->table->getTableName();
|
||||
$r[] = "Local key : ".$this->local;
|
||||
$r[] = "Foreign key : ".$this->foreign;
|
||||
$r[] = "Type : ".$this->type;
|
||||
$r[] = "</pre>";
|
||||
return implode("\n", $r);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
114
Doctrine/Repository.php
Normal file
114
Doctrine/Repository.php
Normal file
@ -0,0 +1,114 @@
|
||||
<?php
|
||||
/**
|
||||
* Doctrine_Repository
|
||||
* each record is added into Doctrine_Repository at the same time they are created,
|
||||
* loaded from the database or retrieved from the cache
|
||||
*
|
||||
* @author Konsta Vesterinen
|
||||
* @package Doctrine ORM
|
||||
* @url www.phpdoctrine.com
|
||||
* @license LGPL
|
||||
* @version 1.0 alpha
|
||||
*
|
||||
*/
|
||||
class Doctrine_Repository implements Countable, IteratorAggregate {
|
||||
/**
|
||||
* @var object Doctrine_Table $table
|
||||
*/
|
||||
private $table;
|
||||
/**
|
||||
* @var array $registry
|
||||
* an array of all records
|
||||
* keys representing record object identifiers
|
||||
*/
|
||||
private $registry = array();
|
||||
/**
|
||||
* constructor
|
||||
*/
|
||||
public function __construct(Doctrine_Table $table) {
|
||||
$this->table = $table;
|
||||
}
|
||||
/**
|
||||
* @return object Doctrine_Table
|
||||
*/
|
||||
public function getTable() {
|
||||
return $this->table;
|
||||
}
|
||||
/**
|
||||
* add
|
||||
* @param Doctrine_Record $record record to be added into registry
|
||||
*/
|
||||
public function add(Doctrine_Record $record) {
|
||||
$oid = $record->getOID();
|
||||
|
||||
if(isset($this->registry[$oid]))
|
||||
return false;
|
||||
|
||||
$this->registry[$oid] = $record;
|
||||
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* get
|
||||
* @param integer $oid
|
||||
* @throws InvalidKeyException
|
||||
*/
|
||||
public function get($oid) {
|
||||
if( ! isset($this->registry[$oid]))
|
||||
throw new InvalidKeyException();
|
||||
|
||||
return $this->registry[$oid];
|
||||
}
|
||||
/**
|
||||
* count
|
||||
* Doctrine_Registry implements interface Countable
|
||||
* @return integer the number of records this registry has
|
||||
*/
|
||||
public function count() {
|
||||
return count($this->registry);
|
||||
}
|
||||
/**
|
||||
* @param integer $oid object identifier
|
||||
* @return boolean whether ot not the operation was successful
|
||||
*/
|
||||
public function evict($oid) {
|
||||
if( ! isset($this->registry[$oid]))
|
||||
return false;
|
||||
|
||||
unset($this->registry[$oid]);
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* @return integer number of records evicted
|
||||
*/
|
||||
public function evictAll() {
|
||||
$evicted = 0;
|
||||
foreach($this->registry as $oid=>$record) {
|
||||
if($this->evict($oid))
|
||||
$evicted++;
|
||||
}
|
||||
return $evicted;
|
||||
}
|
||||
/**
|
||||
* getIterator
|
||||
* @return ArrayIterator
|
||||
*/
|
||||
public function getIterator() {
|
||||
return new ArrayIterator($this->registry);
|
||||
}
|
||||
/**
|
||||
* contains
|
||||
* @param integer $oid object identifier
|
||||
*/
|
||||
public function contains($oid) {
|
||||
return isset($this->registry[$oid]);
|
||||
}
|
||||
/**
|
||||
* loadAll
|
||||
* @return void
|
||||
*/
|
||||
public function loadAll() {
|
||||
$this->table->findAll();
|
||||
}
|
||||
}
|
||||
?>
|
934
Doctrine/Session.php
Normal file
934
Doctrine/Session.php
Normal file
@ -0,0 +1,934 @@
|
||||
<?php
|
||||
require_once("Configurable.php");
|
||||
require_once("Record.php");
|
||||
/**
|
||||
* Doctrine_Session
|
||||
*
|
||||
* @package Doctrine ORM
|
||||
* @url www.phpdoctrine.com
|
||||
* @license LGPL
|
||||
* @version 1.0 alpha
|
||||
*/
|
||||
abstract class Doctrine_Session extends Doctrine_Configurable implements Countable, IteratorAggregate {
|
||||
/**
|
||||
* Doctrine_Session is in open state when it is opened and there are no active transactions
|
||||
*/
|
||||
const STATE_OPEN = 0;
|
||||
/**
|
||||
* Doctrine_Session is in closed state when it is closed
|
||||
*/
|
||||
const STATE_CLOSED = 1;
|
||||
/**
|
||||
* Doctrine_Session is in active state when it has one active transaction
|
||||
*/
|
||||
const STATE_ACTIVE = 2;
|
||||
/**
|
||||
* Doctrine_Session is in busy state when it has multiple active transactions
|
||||
*/
|
||||
const STATE_BUSY = 3;
|
||||
/**
|
||||
* @var $dbh the database handle
|
||||
*/
|
||||
private $dbh;
|
||||
/**
|
||||
* @see Doctrine_Session::STATE_* constants
|
||||
* @var boolean $state the current state of the session
|
||||
*/
|
||||
private $state = 0;
|
||||
/**
|
||||
* @var integer $transaction_level the nesting level of transactions, used by transaction methods
|
||||
*/
|
||||
private $transaction_level = 0;
|
||||
|
||||
/**
|
||||
* @var PDO $cacheHandler cache handler
|
||||
*/
|
||||
private $cacheHandler;
|
||||
/**
|
||||
* @var array $tables an array containing all the initialized Doctrine_Table objects
|
||||
* keys representing Doctrine_Table component names and values as Doctrine_Table objects
|
||||
*/
|
||||
protected $tables = array();
|
||||
/**
|
||||
* @var Doctrine_Validator $validator transaction validator
|
||||
*/
|
||||
protected $validator;
|
||||
/**
|
||||
* @var array $update two dimensional pending update list, the records in
|
||||
* this list will be updated when transaction is committed
|
||||
*/
|
||||
protected $update = array();
|
||||
/**
|
||||
* @var array $insert two dimensional pending insert list, the records in
|
||||
* this list will be inserted when transaction is committed
|
||||
*/
|
||||
protected $insert = array();
|
||||
/**
|
||||
* @var array $delete two dimensional pending delete list, the records in
|
||||
* this list will be deleted when transaction is committed
|
||||
*/
|
||||
protected $delete = array();
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* the constructor
|
||||
* @param PDO $pdo -- database handle
|
||||
*/
|
||||
public function __construct(Doctrine_Manager $manager,PDO $pdo) {
|
||||
$this->dbh = $pdo;
|
||||
|
||||
$this->setParent($manager);
|
||||
|
||||
$this->state = Doctrine_Session::STATE_OPEN;
|
||||
|
||||
$this->dbh->setAttribute(PDO::ATTR_CASE, PDO::CASE_LOWER);
|
||||
$this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
|
||||
switch($this->getAttribute(Doctrine::ATTR_CACHE)):
|
||||
case Doctrine::CACHE_SQLITE:
|
||||
$dir = $this->getAttribute(Doctrine::ATTR_CACHE_DIR).DIRECTORY_SEPARATOR;
|
||||
$dsn = "sqlite:".$dir."data.cache";
|
||||
|
||||
$this->cacheHandler = Doctrine_DB::getConn($dsn);
|
||||
$this->cacheHandler->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
$this->cacheHandler->setAttribute(PDO::ATTR_CASE, PDO::CASE_LOWER);
|
||||
break;
|
||||
endswitch;
|
||||
|
||||
$this->getAttribute(Doctrine::ATTR_LISTENER)->onOpen($this);
|
||||
}
|
||||
|
||||
public function getCacheHandler() {
|
||||
return $this->cacheHandler;
|
||||
}
|
||||
/**
|
||||
* returns the state of this session
|
||||
*
|
||||
* @see Doctrine_Session::STATE_* constants
|
||||
* @return integer the session state
|
||||
*/
|
||||
public function getState() {
|
||||
return $this->state;
|
||||
}
|
||||
/**
|
||||
* returns the manager that created this session
|
||||
*
|
||||
* @return Doctrine_Manager
|
||||
*/
|
||||
public function getManager() {
|
||||
return $this->getParent();
|
||||
}
|
||||
/**
|
||||
* returns the database handler of which this session uses
|
||||
*
|
||||
* @return object PDO the database handler
|
||||
*/
|
||||
public function getDBH() {
|
||||
return $this->dbh;
|
||||
}
|
||||
/**
|
||||
* query
|
||||
* queries the database with Doctrine Query Language
|
||||
*
|
||||
* @param string $query DQL query
|
||||
* @param array $params query parameters
|
||||
*/
|
||||
final public function query($query,array $params = array()) {
|
||||
$parser = new Doctrine_Query($this);
|
||||
|
||||
return $parser->query($query, $params);
|
||||
}
|
||||
/**
|
||||
* queries the database with limit and offset
|
||||
* added to the query and returns a PDOStatement object
|
||||
*
|
||||
* @param string $query
|
||||
* @param integer $limit
|
||||
* @param integer $offset
|
||||
* @return PDOStatement
|
||||
*/
|
||||
public function select($query,$limit = 0,$offset = 0) {
|
||||
if($limit > 0 || $offset > 0)
|
||||
$query = $this->modifyLimitQuery($query,$limit,$offset);
|
||||
|
||||
return $this->dbh->query($query);
|
||||
}
|
||||
/**
|
||||
* @param string $query sql query
|
||||
* @param array $params query parameters
|
||||
*
|
||||
* @return PDOStatement
|
||||
*/
|
||||
public function execute($query, array $params = array()) {
|
||||
if( ! empty($params)) {
|
||||
$stmt = $this->dbh->prepare($query);
|
||||
$stmt->execute($params);
|
||||
return $stmt;
|
||||
} else {
|
||||
return $this->dbh->query($query);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* whether or not this session has table $name initialized
|
||||
*
|
||||
* @param $mixed $name
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasTable($name) {
|
||||
return isset($this->tables[$name]);
|
||||
}
|
||||
/**
|
||||
* returns a table object for given component name
|
||||
*
|
||||
* @param string $name component name
|
||||
* @return object Doctrine_Table
|
||||
*/
|
||||
public function getTable($name) {
|
||||
if(isset($this->tables[$name]))
|
||||
return $this->tables[$name];
|
||||
|
||||
$class = $name."Table";
|
||||
|
||||
if(class_exists($class) && in_array("Doctrine_Table", class_parents($class))) {
|
||||
return new $class($name);
|
||||
} else {
|
||||
|
||||
return new Doctrine_Table($name);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* returns an array of all initialized tables
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getTables() {
|
||||
return $this->tables;
|
||||
}
|
||||
/**
|
||||
* returns an iterator that iterators through all
|
||||
* initialized table objects
|
||||
*
|
||||
* @return ArrayIterator
|
||||
*/
|
||||
public function getIterator() {
|
||||
return new ArrayIterator($this->tables);
|
||||
}
|
||||
/**
|
||||
* returns the count of initialized table objects
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function count() {
|
||||
return count($this->tables);
|
||||
}
|
||||
/**
|
||||
* @param $objTable a Doctrine_Table object to be added into registry
|
||||
* @return boolean
|
||||
*/
|
||||
public function addTable(Doctrine_Table $objTable) {
|
||||
$name = $objTable->getComponentName();
|
||||
|
||||
if(isset($this->tables[$name]))
|
||||
return false;
|
||||
|
||||
$this->tables[$name] = $objTable;
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* creates a record
|
||||
*
|
||||
* create creates a record
|
||||
* @param string $name component name
|
||||
* @return Doctrine_Record Doctrine_Record object
|
||||
*/
|
||||
public function create($name) {
|
||||
return $this->getTable($name)->create();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* buildFlushTree
|
||||
* builds a flush tree that is used in transactions
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function buildFlushTree(array $tables) {
|
||||
$tree = array();
|
||||
foreach($tables as $k => $table) {
|
||||
$k = $k.$table;
|
||||
if( ! ($table instanceof Doctrine_Table))
|
||||
$table = $this->getTable($table);
|
||||
|
||||
$nm = $table->getComponentName();
|
||||
|
||||
$index = array_search($nm,$tree);
|
||||
if($index === false) {
|
||||
$tree[] = $nm;
|
||||
$index = max(array_keys($tree));
|
||||
|
||||
//print "$k -- adding <b>$nm</b>...<br \>";
|
||||
}
|
||||
|
||||
$rels = $table->getForeignKeys();
|
||||
|
||||
// group relations
|
||||
|
||||
foreach($rels as $key => $rel) {
|
||||
if($rel instanceof Doctrine_ForeignKey) {
|
||||
unset($rels[$key]);
|
||||
array_unshift($rels, $rel);
|
||||
}
|
||||
}
|
||||
|
||||
foreach($rels as $rel) {
|
||||
$name = $rel->getTable()->getComponentName();
|
||||
$index2 = array_search($name,$tree);
|
||||
$type = $rel->getType();
|
||||
|
||||
// skip self-referenced relations
|
||||
if($name === $nm)
|
||||
continue;
|
||||
|
||||
if($rel instanceof Doctrine_ForeignKey) {
|
||||
if($index2 !== false) {
|
||||
if($index2 >= $index)
|
||||
continue;
|
||||
|
||||
unset($tree[$index]);
|
||||
array_splice($tree,$index2,0,$nm);
|
||||
$index = $index2;
|
||||
|
||||
//print "$k -- pushing $nm into $index2...<br \>";
|
||||
|
||||
} else {
|
||||
$tree[] = $name;
|
||||
//print "$k -- adding $nm :$name...<br>";
|
||||
}
|
||||
|
||||
} elseif($rel instanceof Doctrine_LocalKey) {
|
||||
if($index2 !== false) {
|
||||
if($index2 <= $index)
|
||||
continue;
|
||||
|
||||
unset($tree[$index2]);
|
||||
array_splice($tree,$index,0,$name);
|
||||
|
||||
//print "$k -- pushing $name into <b>$index</b>...<br \>";
|
||||
|
||||
} else {
|
||||
//array_splice($tree, $index, 0, $name);
|
||||
array_unshift($tree,$name);
|
||||
$index++;
|
||||
|
||||
//print "$k -- pushing <b>$name</b> into 0...<br \>";
|
||||
}
|
||||
} elseif($rel instanceof Doctrine_Association) {
|
||||
$t = $rel->getAssociationFactory();
|
||||
$n = $t->getComponentName();
|
||||
|
||||
if($index2 !== false)
|
||||
unset($tree[$index2]);
|
||||
|
||||
array_splice($tree,$index, 0,$name);
|
||||
$index++;
|
||||
|
||||
$index3 = array_search($n,$tree);
|
||||
|
||||
if($index3 !== false) {
|
||||
if($index3 >= $index)
|
||||
continue;
|
||||
|
||||
unset($tree[$index]);
|
||||
array_splice($tree,$index3,0,$n);
|
||||
$index = $index2;
|
||||
|
||||
//print "$k -- pushing $nm into $index3...<br \>";
|
||||
|
||||
} else {
|
||||
$tree[] = $n;
|
||||
//print "$k -- adding $nm :$name...<br>";
|
||||
}
|
||||
}
|
||||
//print_r($tree);
|
||||
}
|
||||
//print_r($tree);
|
||||
|
||||
}
|
||||
return array_values($tree);
|
||||
}
|
||||
|
||||
/**
|
||||
* flush
|
||||
* saves all the records from all tables
|
||||
* this operation is isolated using a transaction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function flush() {
|
||||
$this->beginTransaction();
|
||||
$this->saveAll();
|
||||
$this->commit();
|
||||
}
|
||||
/**
|
||||
* saveAll
|
||||
* saves all the records from all tables
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function saveAll() {
|
||||
$tree = $this->buildFlushTree($this->tables);
|
||||
|
||||
foreach($tree as $name) {
|
||||
$table = $this->tables[$name];
|
||||
|
||||
foreach($table->getRepository() as $record) {
|
||||
$this->save($record);
|
||||
}
|
||||
}
|
||||
foreach($tree as $name) {
|
||||
$table = $this->tables[$name];
|
||||
foreach($table->getRepository() as $record) {
|
||||
$record->saveAssociations();
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* clear
|
||||
* clears all repositories
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function clear() {
|
||||
foreach($this->tables as $k => $table) {
|
||||
$table->getRepository()->evictAll();
|
||||
$table->clear();
|
||||
}
|
||||
$this->tables = array();
|
||||
}
|
||||
/**
|
||||
* close
|
||||
* closes the session
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function close() {
|
||||
$this->getAttribute(Doctrine::ATTR_LISTENER)->onPreClose($this);
|
||||
|
||||
$this->clear();
|
||||
$this->state = Doctrine_Session::STATE_CLOSED;
|
||||
|
||||
$this->getAttribute(Doctrine::ATTR_LISTENER)->onClose($this);
|
||||
}
|
||||
/**
|
||||
* get the current transaction nesting level
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getTransactionLevel() {
|
||||
return $this->transaction_level;
|
||||
}
|
||||
/**
|
||||
* beginTransaction
|
||||
* starts a new transaction
|
||||
* @return void
|
||||
*/
|
||||
public function beginTransaction() {
|
||||
if($this->transaction_level == 0) {
|
||||
|
||||
if($this->getAttribute(Doctrine::ATTR_LOCKMODE) == Doctrine::LOCK_PESSIMISTIC) {
|
||||
$this->getAttribute(Doctrine::ATTR_LISTENER)->onPreTransactionBegin($this);
|
||||
$this->dbh->beginTransaction();
|
||||
$this->getAttribute(Doctrine::ATTR_LISTENER)->onTransactionBegin($this);
|
||||
}
|
||||
$this->state = Doctrine_Session::STATE_ACTIVE;
|
||||
} else {
|
||||
$this->state = Doctrine_Session::STATE_BUSY;
|
||||
}
|
||||
$this->transaction_level++;
|
||||
}
|
||||
/**
|
||||
* commits the current transaction
|
||||
* if lockmode is optimistic this method starts a transaction
|
||||
* and commits it instantly
|
||||
* @return void
|
||||
*/
|
||||
public function commit() {
|
||||
|
||||
$this->transaction_level--;
|
||||
|
||||
if($this->transaction_level == 0) {
|
||||
|
||||
|
||||
if($this->getAttribute(Doctrine::ATTR_LOCKMODE) == Doctrine::LOCK_OPTIMISTIC) {
|
||||
$this->getAttribute(Doctrine::ATTR_LISTENER)->onPreTransactionBegin($this);
|
||||
|
||||
$this->dbh->beginTransaction();
|
||||
|
||||
$this->getAttribute(Doctrine::ATTR_LISTENER)->onTransactionBegin($this);
|
||||
}
|
||||
|
||||
if($this->getAttribute(Doctrine::ATTR_VLD))
|
||||
$this->validator = new Doctrine_Validator();
|
||||
|
||||
try {
|
||||
|
||||
$this->bulkInsert();
|
||||
$this->bulkUpdate();
|
||||
$this->bulkDelete();
|
||||
|
||||
if($this->getAttribute(Doctrine::ATTR_VLD)) {
|
||||
if($this->validator->hasErrors()) {
|
||||
$this->rollback();
|
||||
throw new Doctrine_Validator_Exception($this->validator);
|
||||
}
|
||||
}
|
||||
|
||||
} catch(PDOException $e) {
|
||||
$this->rollback();
|
||||
|
||||
throw new Doctrine_Exception($e->getMessage());
|
||||
}
|
||||
$this->dbh->commit();
|
||||
$this->getAttribute(Doctrine::ATTR_LISTENER)->onTransactionCommit($this);
|
||||
|
||||
$this->delete = array();
|
||||
$this->state = Doctrine_Session::STATE_OPEN;
|
||||
|
||||
$this->validator = null;
|
||||
|
||||
} elseif($this->transaction_level == 1)
|
||||
$this->state = Doctrine_Session::STATE_ACTIVE;
|
||||
}
|
||||
/**
|
||||
* rollback
|
||||
* rolls back all transactions
|
||||
* @return void
|
||||
*/
|
||||
public function rollback() {
|
||||
$this->getAttribute(Doctrine::ATTR_LISTENER)->onPreTransactionRollback($this);
|
||||
|
||||
$this->transaction_level = 0;
|
||||
$this->dbh->rollback();
|
||||
$this->state = Doctrine_Session::STATE_OPEN;
|
||||
|
||||
$this->getAttribute(Doctrine::ATTR_LISTENER)->onTransactionRollback($this);
|
||||
}
|
||||
/**
|
||||
* bulkInsert
|
||||
* inserts all the objects in the pending insert list into database
|
||||
* @return void
|
||||
*/
|
||||
public function bulkInsert() {
|
||||
if(empty($this->insert))
|
||||
return false;
|
||||
|
||||
foreach($this->insert as $name => $inserts) {
|
||||
if( ! isset($inserts[0]))
|
||||
continue;
|
||||
|
||||
$record = $inserts[0];
|
||||
$table = $record->getTable();
|
||||
$seq = $table->getSequenceName();
|
||||
|
||||
$increment = false;
|
||||
$keys = $table->getPrimaryKeys();
|
||||
$id = null;
|
||||
|
||||
if(count($keys) == 1 && $keys[0] == $table->getIdentifier()) {
|
||||
$increment = true;
|
||||
}
|
||||
|
||||
foreach($inserts as $k => $record) {
|
||||
$record->getTable()->getAttribute(Doctrine::ATTR_LISTENER)->onPreSave($record);
|
||||
// listen the onPreInsert event
|
||||
$record->getTable()->getAttribute(Doctrine::ATTR_LISTENER)->onPreInsert($record);
|
||||
|
||||
|
||||
$this->insert($record);
|
||||
if($increment) {
|
||||
if($k == 0) {
|
||||
// record uses auto_increment column
|
||||
|
||||
$id = $table->getMaxIdentifier();
|
||||
}
|
||||
|
||||
$record->setID($id);
|
||||
$id++;
|
||||
} else
|
||||
$record->setID(true);
|
||||
|
||||
// listen the onInsert event
|
||||
$record->getTable()->getAttribute(Doctrine::ATTR_LISTENER)->onInsert($record);
|
||||
|
||||
$record->getTable()->getAttribute(Doctrine::ATTR_LISTENER)->onSave($record);
|
||||
}
|
||||
}
|
||||
$this->insert = array();
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* returns maximum identifier values
|
||||
*
|
||||
* @param array $names an array of component names
|
||||
* @return array
|
||||
*/
|
||||
public function getMaximumValues(array $names) {
|
||||
$values = array();
|
||||
foreach($names as $name) {
|
||||
$table = $this->tables[$name];
|
||||
$keys = $table->getPrimaryKeys();
|
||||
$tablename = $table->getTableName();
|
||||
|
||||
if(count($keys) == 1 && $keys[0] == $table->getIdentifier()) {
|
||||
// record uses auto_increment column
|
||||
|
||||
$sql = "SELECT MAX(".$table->getIdentifier().") FROM ".$tablename;
|
||||
$stmt = $this->dbh->query($sql);
|
||||
$data = $stmt->fetch(PDO::FETCH_NUM);
|
||||
$values[$tablename] = $data[0];
|
||||
|
||||
$stmt->closeCursor();
|
||||
}
|
||||
}
|
||||
return $values;
|
||||
}
|
||||
/**
|
||||
* bulkUpdate
|
||||
* updates all objects in the pending update list
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function bulkUpdate() {
|
||||
foreach($this->update as $name => $updates) {
|
||||
$ids = array();
|
||||
|
||||
foreach($updates as $k => $record) {
|
||||
$record->getTable()->getAttribute(Doctrine::ATTR_LISTENER)->onPreSave($record);
|
||||
// listen the onPreUpdate event
|
||||
$record->getTable()->getAttribute(Doctrine::ATTR_LISTENER)->onPreUpdate($record);
|
||||
|
||||
$this->update($record);
|
||||
// listen the onUpdate event
|
||||
$record->getTable()->getAttribute(Doctrine::ATTR_LISTENER)->onUpdate($record);
|
||||
|
||||
$record->getTable()->getAttribute(Doctrine::ATTR_LISTENER)->onSave($record);
|
||||
|
||||
$ids[] = $record->getID();
|
||||
}
|
||||
if(isset($record))
|
||||
$record->getTable()->getCache()->deleteMultiple($ids);
|
||||
}
|
||||
$this->update = array();
|
||||
}
|
||||
/**
|
||||
* bulkDelete
|
||||
* deletes all records from the pending delete list
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function bulkDelete() {
|
||||
foreach($this->delete as $name => $deletes) {
|
||||
$record = false;
|
||||
$ids = array();
|
||||
foreach($deletes as $k => $record) {
|
||||
$ids[] = $record->getID();
|
||||
$record->setID(false);
|
||||
}
|
||||
if($record instanceof Doctrine_Record) {
|
||||
$table = $record->getTable();
|
||||
|
||||
$params = substr(str_repeat("?, ",count($ids)),0,-2);
|
||||
$query = "DELETE FROM ".$record->getTable()->getTableName()." WHERE ".$table->getIdentifier()." IN(".$params.")";
|
||||
$this->execute($query,$ids);
|
||||
|
||||
$record->getTable()->getCache()->deleteMultiple($ids);
|
||||
}
|
||||
}
|
||||
$this->delete = array();
|
||||
}
|
||||
/**
|
||||
* saves a collection
|
||||
*
|
||||
* @param Doctrine_Collection $coll
|
||||
* @return void
|
||||
*/
|
||||
public function saveCollection(Doctrine_Collection $coll) {
|
||||
$this->beginTransaction();
|
||||
|
||||
foreach($coll as $key=>$record):
|
||||
$record->save();
|
||||
endforeach;
|
||||
|
||||
$this->commit();
|
||||
}
|
||||
/**
|
||||
* deletes all records from collection
|
||||
*
|
||||
* @param Doctrine_Collection $coll
|
||||
* @return void
|
||||
*/
|
||||
public function deleteCollection(Doctrine_Collection $coll) {
|
||||
$this->beginTransaction();
|
||||
foreach($coll as $k=>$record) {
|
||||
$record->delete();
|
||||
}
|
||||
$this->commit();
|
||||
}
|
||||
/**
|
||||
* saves the given record
|
||||
*
|
||||
* @param Doctrine_Record $record
|
||||
* @return void
|
||||
*/
|
||||
public function save(Doctrine_Record $record) {
|
||||
switch($record->getState()):
|
||||
case Doctrine_Record::STATE_TDIRTY:
|
||||
$this->addInsert($record);
|
||||
break;
|
||||
case Doctrine_Record::STATE_DIRTY:
|
||||
case Doctrine_Record::STATE_PROXY:
|
||||
$this->addUpdate($record);
|
||||
break;
|
||||
case Doctrine_Record::STATE_CLEAN:
|
||||
case Doctrine_Record::STATE_TCLEAN:
|
||||
// do nothing
|
||||
break;
|
||||
endswitch;
|
||||
}
|
||||
/**
|
||||
* saves all related records to $record
|
||||
*
|
||||
* @param Doctrine_Record $record
|
||||
*/
|
||||
final public function saveRelated(Doctrine_Record $record) {
|
||||
$saveLater = array();
|
||||
foreach($record->getReferences() as $k=>$v) {
|
||||
$fk = $record->getTable()->getForeignKey($k);
|
||||
if($fk instanceof Doctrine_ForeignKey ||
|
||||
$fk instanceof Doctrine_LocalKey) {
|
||||
switch($fk->getType()):
|
||||
case Doctrine_Relation::ONE_COMPOSITE:
|
||||
case Doctrine_Relation::MANY_COMPOSITE:
|
||||
$local = $fk->getLocal();
|
||||
$foreign = $fk->getForeign();
|
||||
|
||||
if($record->getTable()->hasPrimaryKey($fk->getLocal())) {
|
||||
switch($record->getState()):
|
||||
case Doctrine_Record::STATE_TDIRTY:
|
||||
case Doctrine_Record::STATE_TCLEAN:
|
||||
$saveLater[$k] = $fk;
|
||||
break;
|
||||
case Doctrine_Record::STATE_CLEAN:
|
||||
case Doctrine_Record::STATE_DIRTY:
|
||||
$v->save();
|
||||
break;
|
||||
endswitch;
|
||||
} else {
|
||||
// ONE-TO-ONE relationship
|
||||
$obj = $record->get($fk->getTable()->getComponentName());
|
||||
|
||||
if($obj->getState() != Doctrine_Record::STATE_TCLEAN)
|
||||
$obj->save();
|
||||
|
||||
}
|
||||
break;
|
||||
endswitch;
|
||||
} elseif($fk instanceof Doctrine_Association) {
|
||||
$v->save();
|
||||
}
|
||||
}
|
||||
return $saveLater;
|
||||
}
|
||||
/**
|
||||
* updates the given record
|
||||
*
|
||||
* @param Doctrine_Record $record
|
||||
* @return boolean
|
||||
*/
|
||||
private function update(Doctrine_Record $record) {
|
||||
$array = $record->getModified();
|
||||
|
||||
if(empty($array))
|
||||
return false;
|
||||
|
||||
$set = array();
|
||||
foreach($array as $name => $value):
|
||||
$set[] = $name." = ?";
|
||||
|
||||
if($value instanceof Doctrine_Record) {
|
||||
switch($value->getState()):
|
||||
case Doctrine_Record::STATE_TCLEAN:
|
||||
case Doctrine_Record::STATE_TDIRTY:
|
||||
$record->save();
|
||||
default:
|
||||
$array[$name] = $value->getID();
|
||||
$record->set($name, $value->getID());
|
||||
endswitch;
|
||||
}
|
||||
endforeach;
|
||||
|
||||
if(isset($this->validator)) {
|
||||
if( ! $this->validator->validateRecord($record)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$params = array_values($array);
|
||||
$id = $record->getID();
|
||||
|
||||
|
||||
if( ! is_array($id))
|
||||
$id = array($id);
|
||||
|
||||
$id = array_values($id);
|
||||
$params = array_merge($params, $id);
|
||||
|
||||
|
||||
$sql = "UPDATE ".$record->getTable()->getTableName()." SET ".implode(", ",$set)." WHERE ".implode(" = ? && ",$record->getTable()->getPrimaryKeys())." = ?";
|
||||
|
||||
$stmt = $this->dbh->prepare($sql);
|
||||
$stmt->execute($params);
|
||||
|
||||
$record->setID(true);
|
||||
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* inserts a record into database
|
||||
*
|
||||
* @param Doctrine_Record $record
|
||||
* @return boolean
|
||||
*/
|
||||
private function insert(Doctrine_Record $record) {
|
||||
$array = $record->getPrepared();
|
||||
|
||||
if(empty($array))
|
||||
return false;
|
||||
|
||||
$seq = $record->getTable()->getSequenceName();
|
||||
|
||||
if( ! empty($seq)) {
|
||||
$id = $this->getNextID($seq);
|
||||
$name = $record->getTable()->getIdentifier();
|
||||
$array[$name] = $id;
|
||||
}
|
||||
|
||||
if(isset($this->validator)) {
|
||||
if( ! $this->validator->validateRecord($record)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$strfields = join(", ", array_keys($array));
|
||||
$strvalues = substr(str_repeat("?, ",count($array)),0,-2);
|
||||
|
||||
$sql = "INSERT INTO ".$record->getTable()->getTableName()." (".$strfields.") VALUES (".$strvalues.")";
|
||||
|
||||
$stmt = $this->dbh->prepare($sql);
|
||||
|
||||
$stmt->execute(array_values($array));
|
||||
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* deletes all related composites
|
||||
* this method is always called internally when a record is deleted
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
final public function deleteComposites(Doctrine_Record $record) {
|
||||
foreach($record->getTable()->getForeignKeys() as $fk) {
|
||||
switch($fk->getType()):
|
||||
case Doctrine_Relation::ONE_COMPOSITE:
|
||||
case Doctrine_Relation::MANY_COMPOSITE:
|
||||
$obj = $record->get($fk->getTable()->getComponentName());
|
||||
$obj->delete();
|
||||
break;
|
||||
endswitch;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* deletes this data access object and all the related composites
|
||||
* this operation is isolated by a transaction
|
||||
*
|
||||
* this event can be listened by the onPreDelete and onDelete listeners
|
||||
*
|
||||
* @return boolean true on success, false on failure
|
||||
*/
|
||||
final public function delete(Doctrine_Record $record) {
|
||||
switch($record->getState()):
|
||||
case Doctrine_Record::STATE_PROXY:
|
||||
case Doctrine_Record::STATE_CLEAN:
|
||||
case Doctrine_Record::STATE_DIRTY:
|
||||
$this->beginTransaction();
|
||||
|
||||
$this->deleteComposites($record);
|
||||
$this->addDelete($record);
|
||||
|
||||
$this->commit();
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
endswitch;
|
||||
}
|
||||
/**
|
||||
* adds record into pending insert list
|
||||
* @param Doctrine_Record $record
|
||||
*/
|
||||
public function addInsert(Doctrine_Record $record) {
|
||||
$name = $record->getTable()->getComponentName();
|
||||
$this->insert[$name][] = $record;
|
||||
}
|
||||
/**
|
||||
* adds record into penging update list
|
||||
* @param Doctrine_Record $record
|
||||
*/
|
||||
public function addUpdate(Doctrine_Record $record) {
|
||||
$name = $record->getTable()->getComponentName();
|
||||
$this->update[$name][] = $record;
|
||||
}
|
||||
/**
|
||||
* adds record into pending delete list
|
||||
* @param Doctrine_Record $record
|
||||
*/
|
||||
public function addDelete(Doctrine_Record $record) {
|
||||
$name = $record->getTable()->getComponentName();
|
||||
$this->delete[$name][] = $record;
|
||||
}
|
||||
/**
|
||||
* returns the pending insert list
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getInserts() {
|
||||
return $this->insert;
|
||||
}
|
||||
/**
|
||||
* returns the pending update list
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getUpdates() {
|
||||
return $this->update;
|
||||
}
|
||||
/**
|
||||
* returns the pending delete list
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getDeletes() {
|
||||
return $this->delete;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns a string representation of this object
|
||||
* @return string
|
||||
*/
|
||||
public function __toString() {
|
||||
return Doctrine_Lib::getSessionAsString($this);
|
||||
}
|
||||
}
|
||||
?>
|
188
Doctrine/Statement.class.php
Normal file
188
Doctrine/Statement.class.php
Normal file
@ -0,0 +1,188 @@
|
||||
<?php
|
||||
require_once("Access.php");
|
||||
/**
|
||||
* Doctrine_Statement
|
||||
*
|
||||
* Doctrine_Statement is a wrapper for PDOStatement with DQL support
|
||||
*
|
||||
* @package Doctrine ORM
|
||||
* @url www.phpdoctrine.com
|
||||
* @license LGPL
|
||||
*/
|
||||
class Doctrine_Statement extends Doctrine_Access {
|
||||
/**
|
||||
* @var Doctrine_Query $query
|
||||
*/
|
||||
private $query;
|
||||
/**
|
||||
* @var PDOStatement $stmt
|
||||
*/
|
||||
private $stmt;
|
||||
/**
|
||||
* @var array $reserved
|
||||
*/
|
||||
private $reserved = array();
|
||||
|
||||
/**
|
||||
* constructor
|
||||
*
|
||||
* @param Doctrine_Query $query
|
||||
* @param PDOStatement $stmt
|
||||
*/
|
||||
public function __construct(Doctrine_Query $query, PDOStatement $stmt) {
|
||||
$this->query = $query;
|
||||
$this->stmt = $stmt;
|
||||
}
|
||||
public function set($name, $value) { }
|
||||
public function get($name) { }
|
||||
/**
|
||||
* getCollection
|
||||
* returns Doctrine_Collection object
|
||||
*
|
||||
* @parma string $name component name
|
||||
* @param integer $index
|
||||
* @return Doctrine_Collection
|
||||
*/
|
||||
private function getCollection($name) {
|
||||
$table = $this->session->getTable($name);
|
||||
switch($this->fetchModes[$name]):
|
||||
case Doctrine::FETCH_BATCH:
|
||||
$coll = new Doctrine_Collection_Batch($table);
|
||||
break;
|
||||
case Doctrine::FETCH_LAZY:
|
||||
$coll = new Doctrine_Collection_Lazy($table);
|
||||
break;
|
||||
case Doctrine::FETCH_OFFSET:
|
||||
$coll = new Doctrine_Collection_Offset($table);
|
||||
break;
|
||||
case Doctrine::FETCH_IMMEDIATE:
|
||||
$coll = new Doctrine_Collection_Immediate($table);
|
||||
break;
|
||||
case Doctrine::FETCH_LAZY_OFFSET:
|
||||
$coll = new Doctrine_Collection_LazyOffset($table);
|
||||
break;
|
||||
endswitch;
|
||||
|
||||
$coll->populate($this);
|
||||
return $coll;
|
||||
}
|
||||
/**
|
||||
* execute
|
||||
* executes the dql query, populates all collections
|
||||
* and returns the root collection
|
||||
*
|
||||
* @param array $params
|
||||
* @return Doctrine_Collection
|
||||
*/
|
||||
public function execute($params = array()) {
|
||||
switch(count($this->tables)):
|
||||
case 0:
|
||||
throw new DQLException();
|
||||
break;
|
||||
case 1:
|
||||
$query = $this->getQuery();
|
||||
|
||||
$keys = array_keys($this->tables);
|
||||
|
||||
$name = $this->tables[$keys[0]]->getComponentName();
|
||||
$stmt = $this->session->execute($query,$params);
|
||||
|
||||
while($data = $stmt->fetch(PDO::FETCH_ASSOC)):
|
||||
foreach($data as $key => $value):
|
||||
$e = explode("__",$key);
|
||||
if(count($e) > 1) {
|
||||
$data[$e[1]] = $value;
|
||||
} else {
|
||||
$data[$e[0]] = $value;
|
||||
}
|
||||
unset($data[$key]);
|
||||
endforeach;
|
||||
$this->data[$name][] = $data;
|
||||
endwhile;
|
||||
|
||||
return $this->getCollection($keys[0]);
|
||||
break;
|
||||
default:
|
||||
$query = $this->getQuery();
|
||||
|
||||
$keys = array_keys($this->tables);
|
||||
$root = $keys[0];
|
||||
$stmt = $this->session->execute($query,$params);
|
||||
|
||||
$previd = array();
|
||||
|
||||
$coll = $this->getCollection($root);
|
||||
|
||||
$array = $this->parseData($stmt);
|
||||
|
||||
foreach($array as $data):
|
||||
|
||||
/**
|
||||
* remove duplicated data rows and map data into objects
|
||||
*/
|
||||
foreach($data as $key => $row):
|
||||
if(empty($row))
|
||||
continue;
|
||||
|
||||
$key = ucwords($key);
|
||||
$name = $this->tables[$key]->getComponentName();
|
||||
|
||||
if( ! isset($previd[$name]))
|
||||
$previd[$name] = array();
|
||||
|
||||
|
||||
if($previd[$name] !== $row) {
|
||||
$this->tables[$name]->setData($row);
|
||||
$record = $this->tables[$name]->getRecord();
|
||||
|
||||
if($name == $root) {
|
||||
$this->tables[$name]->setData($row);
|
||||
$record = $this->tables[$name]->getRecord();
|
||||
$coll->add($record);
|
||||
} else {
|
||||
$last = $coll->getLast();
|
||||
|
||||
if( ! $last->hasReference($name)) {
|
||||
$last->initReference($this->getCollection($name),$this->connectors[$name]);
|
||||
}
|
||||
$last->addReference($record);
|
||||
}
|
||||
}
|
||||
|
||||
$previd[$name] = $row;
|
||||
endforeach;
|
||||
endforeach;
|
||||
|
||||
return $coll;
|
||||
endswitch;
|
||||
}
|
||||
/**
|
||||
* parseData
|
||||
* parses the data returned by PDOStatement
|
||||
*
|
||||
* @param PDOStatement $stmt
|
||||
* @return array
|
||||
*/
|
||||
public function parseData(PDOStatement $stmt) {
|
||||
$array = array();
|
||||
while($data = $stmt->fetch(PDO::FETCH_ASSOC)):
|
||||
/**
|
||||
* parse the data into two-dimensional array
|
||||
*/
|
||||
foreach($data as $key => $value):
|
||||
$e = explode("__",$key);
|
||||
|
||||
if(count($e) > 1) {
|
||||
$data[$e[0]][$e[1]] = $value;
|
||||
} else {
|
||||
$data[0][$e[0]] = $value;
|
||||
}
|
||||
unset($data[$key]);
|
||||
endforeach;
|
||||
$array[] = $data;
|
||||
endwhile;
|
||||
$stmt->closeCursor();
|
||||
return $array;
|
||||
}
|
||||
}
|
||||
?>
|
870
Doctrine/Table.php
Normal file
870
Doctrine/Table.php
Normal file
@ -0,0 +1,870 @@
|
||||
<?php
|
||||
require_once("Exception/Find.class.php");
|
||||
require_once("Exception/Mapping.class.php");
|
||||
require_once("Exception/PrimaryKey.class.php");
|
||||
require_once("Configurable.php");
|
||||
/**
|
||||
* Doctrine_Table represents a database table
|
||||
* each Doctrine_Table holds the information of foreignKeys and associations
|
||||
*
|
||||
*
|
||||
* @author Konsta Vesterinen
|
||||
* @package Doctrine ORM
|
||||
* @url www.phpdoctrine.com
|
||||
* @license LGPL
|
||||
* @version 1.0 alpha
|
||||
*/
|
||||
class Doctrine_Table extends Doctrine_Configurable {
|
||||
/**
|
||||
* @var boolean $isNewEntry whether ot not this table created a new record or not, used only internally
|
||||
*/
|
||||
private $isNewEntry = false;
|
||||
/**
|
||||
* @var array $data temporary data which is then loaded into Doctrine_Record::$data
|
||||
*/
|
||||
private $data = array();
|
||||
/**
|
||||
* @var array $relations an array containing all the Doctrine_Relation objects for this table
|
||||
*/
|
||||
private $relations = array();
|
||||
/**
|
||||
* @var array $primaryKeys an array containing all primary key column names
|
||||
*/
|
||||
private $primaryKeys = array();
|
||||
/**
|
||||
* @var mixed $identifier
|
||||
*/
|
||||
private $identifier;
|
||||
/**
|
||||
* @var integer $identifierType
|
||||
*/
|
||||
private $identifierType;
|
||||
/**
|
||||
* @var string $query cached simple query
|
||||
*/
|
||||
private $query;
|
||||
/**
|
||||
* @var Doctrine_Session $session Doctrine_Session object that created this table
|
||||
*/
|
||||
private $session;
|
||||
/**
|
||||
* @var string $name name of the component, for example component name of the GroupTable is 'Group'
|
||||
*/
|
||||
private $name;
|
||||
/**
|
||||
* @var string $tableName database table name, in most cases this is the same as component name but in some cases
|
||||
* where one-table-multi-class inheritance is used this will be the name of the inherited table
|
||||
*/
|
||||
private $tableName;
|
||||
/**
|
||||
* @var string $sequenceName Some databases need sequences instead of auto incrementation primary keys, you can set specific
|
||||
* sequence for your table by calling setSequenceName()
|
||||
*/
|
||||
private $sequenceName;
|
||||
/**
|
||||
* @var array $identityMap first level cache
|
||||
*/
|
||||
private $identityMap = array();
|
||||
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* @var Doctrine_Cache $cache second level cache
|
||||
*/
|
||||
private $cache;
|
||||
/**
|
||||
* @var array $columns an array of column definitions
|
||||
*/
|
||||
private $columns;
|
||||
/**
|
||||
* @var array $bound bound relations
|
||||
*/
|
||||
private $bound = array();
|
||||
/**
|
||||
* @var array $boundAliases bound relation aliases
|
||||
*/
|
||||
private $boundAliases = array();
|
||||
/**
|
||||
* @var integer $columnCount cached column count
|
||||
*/
|
||||
private $columnCount;
|
||||
|
||||
|
||||
/**
|
||||
* @var array $inheritanceMap inheritanceMap is used for inheritance mapping, keys representing columns and values
|
||||
* the column values that should correspond to child classes
|
||||
*/
|
||||
private $inheritanceMap = array();
|
||||
/**
|
||||
* @var array $parents the parent classes of this component
|
||||
*/
|
||||
private $parents = array();
|
||||
|
||||
/**
|
||||
* the constructor
|
||||
* @throws Doctrine_ManagerException if there are no opened sessions
|
||||
* @throws Doctrine_TableException if there is already an instance of this table
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($name) {
|
||||
$this->session = Doctrine_Manager::getInstance()->getCurrentSession();
|
||||
|
||||
$this->setParent($this->session);
|
||||
|
||||
$this->name = $name;
|
||||
|
||||
if( ! class_exists($name) || empty($name))
|
||||
throw new Doctrine_Exception("Couldn't find class $name");
|
||||
|
||||
$record = new $name($this);
|
||||
|
||||
|
||||
$names = array();
|
||||
|
||||
$class = $name;
|
||||
|
||||
|
||||
|
||||
// get parent classes
|
||||
|
||||
do {
|
||||
if($class == "Doctrine_Record") break;
|
||||
|
||||
$name = $class;
|
||||
$names[] = $name;
|
||||
} while($class = get_parent_class($class));
|
||||
|
||||
// reverse names
|
||||
$names = array_reverse($names);
|
||||
|
||||
|
||||
// create database table
|
||||
if(method_exists($record,"setTableDefinition")) {
|
||||
$record->setTableDefinition();
|
||||
|
||||
$this->columnCount = count($this->columns);
|
||||
|
||||
if(isset($this->columns)) {
|
||||
$method = new ReflectionMethod($this->name,"setTableDefinition");
|
||||
$class = $method->getDeclaringClass();
|
||||
|
||||
if( ! isset($this->tableName))
|
||||
$this->tableName = strtolower($class->getName());
|
||||
|
||||
switch(count($this->primaryKeys)):
|
||||
case 0:
|
||||
$this->columns = array_merge(array("id" => array("integer",11,"autoincrement|primary")), $this->columns);
|
||||
$this->primaryKeys[] = "id";
|
||||
$this->identifier = "id";
|
||||
$this->identifierType = Doctrine_Identifier::AUTO_INCREMENT;
|
||||
break;
|
||||
default:
|
||||
if(count($this->primaryKeys) > 1) {
|
||||
$this->identifier = $this->primaryKeys;
|
||||
$this->identifierType = Doctrine_Identifier::COMPOSITE;
|
||||
|
||||
} else {
|
||||
foreach($this->primaryKeys as $pk) {
|
||||
$o = $this->columns[$pk][2];
|
||||
$e = explode("|",$o);
|
||||
$found = false;
|
||||
|
||||
|
||||
foreach($e as $option) {
|
||||
if($found)
|
||||
break;
|
||||
|
||||
$e2 = explode(":",$option);
|
||||
|
||||
switch(strtolower($e2[0])):
|
||||
case "unique":
|
||||
$this->identifierType = Doctrine_Identifier::UNIQUE;
|
||||
$found = true;
|
||||
break;
|
||||
case "autoincrement":
|
||||
$this->identifierType = Doctrine_Identifier::AUTO_INCREMENT;
|
||||
$found = true;
|
||||
break;
|
||||
case "seq":
|
||||
$this->identifierType = Doctrine_Identifier::SEQUENCE;
|
||||
$found = true;
|
||||
break;
|
||||
endswitch;
|
||||
}
|
||||
if( ! isset($this->identifierType))
|
||||
$this->identifierType = Doctrine_Identifier::NORMAL;
|
||||
|
||||
$this->identifier = $pk;
|
||||
}
|
||||
}
|
||||
endswitch;
|
||||
|
||||
if($this->getAttribute(Doctrine::ATTR_CREATE_TABLES)) {
|
||||
$dict = new Doctrine_DataDict($this->getSession()->getDBH());
|
||||
$dict->createTable($this->tableName, $this->columns);
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
throw new Doctrine_Exception("Class '$name' has no table definition.");
|
||||
}
|
||||
|
||||
$record->setUp();
|
||||
|
||||
// save parents
|
||||
array_pop($names);
|
||||
$this->parents = $names;
|
||||
|
||||
$this->query = "SELECT ".implode(", ",array_keys($this->columns))." FROM ".$this->getTableName();
|
||||
|
||||
// check if an instance of this table is already initialized
|
||||
if( ! $this->session->addTable($this))
|
||||
throw new Doctrine_Table_Exception();
|
||||
|
||||
$this->initComponents();
|
||||
}
|
||||
/**
|
||||
* initializes components this table uses
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
final public function initComponents() {
|
||||
$this->repository = new Doctrine_Repository($this);
|
||||
switch($this->getAttribute(Doctrine::ATTR_CACHE)):
|
||||
case Doctrine::CACHE_SQLITE:
|
||||
$this->cache = new Doctrine_Cache_Sqlite($this);
|
||||
break;
|
||||
case Doctrine::CACHE_NONE:
|
||||
$this->cache = new Doctrine_Cache($this);
|
||||
break;
|
||||
endswitch;
|
||||
}
|
||||
/**
|
||||
* @return Doctrine_Repository
|
||||
*/
|
||||
public function getRepository() {
|
||||
return $this->repository;
|
||||
}
|
||||
/**
|
||||
* setColumn
|
||||
* @param string $name
|
||||
* @param string $type
|
||||
* @param integer $length
|
||||
* @param mixed $options
|
||||
* @return void
|
||||
*/
|
||||
final public function setColumn($name, $type, $length, $options = "") {
|
||||
$this->columns[$name] = array($type,$length,$options);
|
||||
|
||||
$e = explode("|",$options);
|
||||
if(in_array("primary",$e)) {
|
||||
$this->primaryKeys[] = $name;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
final public function getIdentifier() {
|
||||
return $this->identifier;
|
||||
}
|
||||
/**
|
||||
* @return integer
|
||||
*/
|
||||
final public function getIdentifierType() {
|
||||
return $this->identifierType;
|
||||
}
|
||||
/**
|
||||
* hasColumn
|
||||
* @return boolean
|
||||
*/
|
||||
final public function hasColumn($name) {
|
||||
return isset($this->columns[$name]);
|
||||
}
|
||||
/**
|
||||
* @param mixed $key
|
||||
* @return void
|
||||
*/
|
||||
final public function setPrimaryKey($key) {
|
||||
switch(gettype($key)):
|
||||
case "array":
|
||||
$this->primaryKeys = array_values($key);
|
||||
break;
|
||||
case "string":
|
||||
$this->primaryKeys[] = $key;
|
||||
break;
|
||||
endswitch;
|
||||
}
|
||||
/**
|
||||
* returns all primary keys
|
||||
* @return array
|
||||
*/
|
||||
final public function getPrimaryKeys() {
|
||||
return $this->primaryKeys;
|
||||
}
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
final public function hasPrimaryKey($key) {
|
||||
return in_array($key,$this->primaryKeys);
|
||||
}
|
||||
/**
|
||||
* @param $sequence
|
||||
* @return void
|
||||
*/
|
||||
final public function setSequenceName($sequence) {
|
||||
$this->sequenceName = $sequence;
|
||||
}
|
||||
/**
|
||||
* @return string sequence name
|
||||
*/
|
||||
final public function getSequenceName() {
|
||||
return $this->sequenceName;
|
||||
}
|
||||
/**
|
||||
* setInheritanceMap
|
||||
* @param array $inheritanceMap
|
||||
* @return void
|
||||
*/
|
||||
final public function setInheritanceMap(array $inheritanceMap) {
|
||||
$this->inheritanceMap = $inheritanceMap;
|
||||
}
|
||||
/**
|
||||
* @return array inheritance map (array keys as fields)
|
||||
*/
|
||||
final public function getInheritanceMap() {
|
||||
return $this->inheritanceMap;
|
||||
}
|
||||
/**
|
||||
* return all composite paths in the form [component1].[component2]. . .[componentN]
|
||||
* @return array
|
||||
*/
|
||||
final public function getCompositePaths() {
|
||||
$array = array();
|
||||
$name = $this->getComponentName();
|
||||
foreach($this->bound as $k=>$a) {
|
||||
try {
|
||||
$fk = $this->getForeignKey($k);
|
||||
switch($fk->getType()):
|
||||
case Doctrine_Relation::ONE_COMPOSITE:
|
||||
case Doctrine_Relation::MANY_COMPOSITE:
|
||||
$n = $fk->getTable()->getComponentName();
|
||||
$array[] = $name.".".$n;
|
||||
$e = $fk->getTable()->getCompositePaths();
|
||||
if( ! empty($e)) {
|
||||
foreach($e as $name) {
|
||||
$array[] = $name.".".$n.".".$name;
|
||||
}
|
||||
}
|
||||
break;
|
||||
endswitch;
|
||||
} catch(InvalidKeyException $e) {
|
||||
|
||||
}
|
||||
}
|
||||
return $array;
|
||||
}
|
||||
/**
|
||||
* returns all bound relations
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
final public function getBounds() {
|
||||
return $this->bound;
|
||||
}
|
||||
/**
|
||||
* returns a bound relation array
|
||||
*
|
||||
* @param string $name
|
||||
* @return array
|
||||
*/
|
||||
final public function getBound($name) {
|
||||
if( ! isset($this->bound[$name]))
|
||||
throw new InvalidKeyException();
|
||||
|
||||
return $this->bound[$name];
|
||||
}
|
||||
/**
|
||||
* returns a bound relation array
|
||||
*
|
||||
* @param string $name
|
||||
* @return array
|
||||
*/
|
||||
final public function getBoundForName($name) {
|
||||
foreach($this->bound as $k => $bound) {
|
||||
if($bound[3] == $name) {
|
||||
return $this->bound[$k];
|
||||
}
|
||||
}
|
||||
throw new InvalidKeyException();
|
||||
}
|
||||
/**
|
||||
* returns the alias for given component name
|
||||
*
|
||||
* @param string $name
|
||||
* @return string
|
||||
*/
|
||||
final public function getAlias($name) {
|
||||
if(isset($this->boundAliases[$name]))
|
||||
return $this->boundAliases[$name];
|
||||
|
||||
return $name;
|
||||
}
|
||||
/**
|
||||
* returns component name for given alias
|
||||
*
|
||||
* @param string $alias
|
||||
* @return string
|
||||
*/
|
||||
final public function getAliasName($alias) {
|
||||
if($name = array_search($this->boundAliases,$alias))
|
||||
return $name;
|
||||
|
||||
throw new InvalidKeyException();
|
||||
}
|
||||
/**
|
||||
* unbinds all relations
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
final public function unbindAll() {
|
||||
$this->bound = array();
|
||||
$this->relations = array();
|
||||
$this->boundAliases = array();
|
||||
}
|
||||
/**
|
||||
* unbinds a relation
|
||||
* returns true on success, false on failure
|
||||
*
|
||||
* @param $name
|
||||
* @return boolean
|
||||
*/
|
||||
final public function unbind() {
|
||||
if( ! isset($this->bound[$name]))
|
||||
return false;
|
||||
|
||||
unset($this->bound[$name]);
|
||||
|
||||
if(isset($this->relations[$name]))
|
||||
unset($this->relations[$name]);
|
||||
|
||||
if(isset($this->boundAliases[$name]))
|
||||
unset($this->boundAliases[$name]);
|
||||
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* binds a relation
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $field
|
||||
* @return void
|
||||
*/
|
||||
final public function bind($name,$field,$type,$localKey) {
|
||||
if(isset($this->relations[$name]))
|
||||
throw new InvalidKeyException();
|
||||
|
||||
$e = explode(" as ",$name);
|
||||
$name = $e[0];
|
||||
|
||||
if(isset($e[1])) {
|
||||
$alias = $e[1];
|
||||
$this->boundAliases[$name] = $alias;
|
||||
} else
|
||||
$alias = $name;
|
||||
|
||||
|
||||
$this->bound[$alias] = array($field,$type,$localKey,$name);
|
||||
}
|
||||
/**
|
||||
* getComponentName
|
||||
* @return string the component name
|
||||
*/
|
||||
final public function getComponentName() {
|
||||
return $this->name;
|
||||
}
|
||||
/**
|
||||
* @return Doctrine_Session
|
||||
*/
|
||||
final public function getSession() {
|
||||
return $this->session;
|
||||
}
|
||||
/**
|
||||
* @return Doctrine_Cache
|
||||
*/
|
||||
final public function getCache() {
|
||||
return $this->cache;
|
||||
}
|
||||
/**
|
||||
* @param string $name component name of which a foreign key object is bound
|
||||
* @return Doctrine_Relation
|
||||
*/
|
||||
final public function getForeignKey($name) {
|
||||
if(isset($this->relations[$name]))
|
||||
return $this->relations[$name];
|
||||
|
||||
if(isset($this->bound[$name])) {
|
||||
$type = $this->bound[$name][1];
|
||||
$local = $this->bound[$name][2];
|
||||
list($component, $foreign) = explode(".",$this->bound[$name][0]);
|
||||
$alias = $name;
|
||||
$name = $this->bound[$alias][3];
|
||||
|
||||
$table = $this->session->getTable($name);
|
||||
|
||||
if($component == $this->name || in_array($component, $this->parents)) {
|
||||
|
||||
// ONE-TO-ONE
|
||||
if($type == Doctrine_Relation::ONE_COMPOSITE ||
|
||||
$type == Doctrine_Relation::ONE_AGGREGATE) {
|
||||
if( ! isset($local))
|
||||
$local = $table->getIdentifier();
|
||||
|
||||
$relation = new Doctrine_LocalKey($table,$foreign,$local,$type);
|
||||
} else
|
||||
throw new Doctrine_Mapping_Exception("Only one-to-one relations are possible when local reference key is used.");
|
||||
|
||||
} elseif($component == $name || ($component == $alias && $name == $this->name)) {
|
||||
if( ! isset($local))
|
||||
$local = $this->identifier;
|
||||
|
||||
// ONE-TO-MANY or ONE-TO-ONE
|
||||
$relation = new Doctrine_ForeignKey($table,$local,$foreign,$type);
|
||||
|
||||
} else {
|
||||
// MANY-TO-MANY
|
||||
// only aggregate relations allowed
|
||||
|
||||
if($type != Doctrine_Relation::MANY_AGGREGATE)
|
||||
throw new Doctrine_Mapping_Exception("Only aggregate relations are allowed for many-to-many relations");
|
||||
|
||||
$classes = array_merge($this->parents, array($this->name));
|
||||
|
||||
foreach(array_reverse($classes) as $class) {
|
||||
try {
|
||||
$bound = $table->getBoundForName($class);
|
||||
break;
|
||||
} catch(InvalidKeyException $exc) { }
|
||||
|
||||
}
|
||||
if( ! isset($local))
|
||||
$local = $this->identifier;
|
||||
|
||||
$e2 = explode(".",$bound[0]);
|
||||
$fields = explode("-",$e2[1]);
|
||||
|
||||
if($e2[0] != $component)
|
||||
throw new Doctrine_Mapping_Exception($e2[0]." doesn't match ".$component);
|
||||
|
||||
$associationTable = $this->session->getTable($e2[0]);
|
||||
|
||||
if(count($fields) > 1) {
|
||||
// SELF-REFERENCING THROUGH JOIN TABLE
|
||||
$this->relations[$e2[0]] = new Doctrine_ForeignKey($associationTable,$local,$fields[0],Doctrine_Relation::MANY_COMPOSITE);
|
||||
|
||||
$relation = new Doctrine_Association($table,$associationTable,$fields[0],$fields[1],$type);
|
||||
} else {
|
||||
// NORMAL MANY-TO-MANY RELATIONSHIP
|
||||
$this->relations[$e2[0]] = new Doctrine_ForeignKey($associationTable,$local,$e2[1],Doctrine_Relation::MANY_COMPOSITE);
|
||||
|
||||
$relation = new Doctrine_Association($table,$associationTable,$e2[1],$foreign,$type);
|
||||
}
|
||||
|
||||
}
|
||||
$this->relations[$alias] = $relation;
|
||||
return $this->relations[$alias];
|
||||
}
|
||||
throw new InvalidKeyException();
|
||||
}
|
||||
/**
|
||||
* returns an array containing all foreign key objects
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
final public function getForeignKeys() {
|
||||
$a = array();
|
||||
foreach($this->bound as $k=>$v) {
|
||||
$this->getForeignKey($k);
|
||||
}
|
||||
|
||||
return $this->relations;
|
||||
}
|
||||
/**
|
||||
* sets the database table name
|
||||
*
|
||||
* @param string $name database table name
|
||||
* @return void
|
||||
*/
|
||||
final public function setTableName($name) {
|
||||
$this->tableName = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the database table name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
final public function getTableName() {
|
||||
return $this->tableName;
|
||||
}
|
||||
/**
|
||||
* create
|
||||
* creates a new record
|
||||
*
|
||||
* @param $array an array where keys are field names and values representing field values
|
||||
* @return Doctrine_Record
|
||||
*/
|
||||
public function create(array $array = array()) {
|
||||
$this->data = $array;
|
||||
$this->isNewEntry = true;
|
||||
$record = new $this->name($this);
|
||||
$this->isNewEntry = false;
|
||||
$this->data = array();
|
||||
return $record;
|
||||
}
|
||||
/**
|
||||
* finds a record by its identifier
|
||||
*
|
||||
* @param $id database row id
|
||||
* @throws Doctrine_Find_Exception
|
||||
* @return Doctrine_Record a record for given database identifier
|
||||
*/
|
||||
public function find($id) {
|
||||
if($id !== null) {
|
||||
if( ! is_array($id))
|
||||
$id = array($id);
|
||||
else
|
||||
$id = array_values($id);
|
||||
|
||||
$query = $this->query." WHERE ".implode(" = ? AND ",$this->primaryKeys)." = ?";
|
||||
$query = $this->applyInheritance($query);
|
||||
|
||||
$params = array_merge($id, array_values($this->inheritanceMap));
|
||||
|
||||
$this->data = $this->session->execute($query,$params)->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if($this->data === false)
|
||||
throw new Doctrine_Find_Exception();
|
||||
}
|
||||
return $this->getRecord();
|
||||
}
|
||||
/**
|
||||
* applyInheritance
|
||||
* @param $where query where part to be modified
|
||||
* @return string query where part with column aggregation inheritance added
|
||||
*/
|
||||
final public function applyInheritance($where) {
|
||||
if( ! empty($this->inheritanceMap)) {
|
||||
$a = array();
|
||||
foreach($this->inheritanceMap as $field => $value) {
|
||||
$a[] = $field." = ?";
|
||||
}
|
||||
$i = implode(" AND ",$a);
|
||||
$where .= " AND $i";
|
||||
}
|
||||
return $where;
|
||||
}
|
||||
/**
|
||||
* findAll
|
||||
* returns a collection of records
|
||||
*
|
||||
* @return Doctrine_Collection
|
||||
*/
|
||||
public function findAll() {
|
||||
$graph = new Doctrine_Query($this->session);
|
||||
$users = $graph->query("FROM ".$this->name);
|
||||
return $users;
|
||||
}
|
||||
/**
|
||||
* findBySql
|
||||
* finds records with given sql where clause
|
||||
* returns a collection of records
|
||||
*
|
||||
* @param string $sql SQL after WHERE clause
|
||||
* @param array $params query parameters
|
||||
* @return Doctrine_Collection
|
||||
*/
|
||||
public function findBySql($sql, array $params = array()) {
|
||||
$q = new Doctrine_Query($this->session);
|
||||
$users = $q->query("FROM ".$this->name." WHERE ".$sql, $params);
|
||||
return $users;
|
||||
}
|
||||
/**
|
||||
* clear
|
||||
* clears the first level cache (identityMap)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function clear() {
|
||||
$this->identityMap = array();
|
||||
}
|
||||
/**
|
||||
* getRecord
|
||||
* first checks if record exists in identityMap, if not
|
||||
* returns a new record
|
||||
*
|
||||
* @return Doctrine_Record
|
||||
*/
|
||||
public function getRecord() {
|
||||
$key = $this->getIdentifier();
|
||||
|
||||
if( ! is_array($key))
|
||||
$key = array($key);
|
||||
|
||||
|
||||
foreach($key as $k) {
|
||||
if( ! isset($this->data[$k]))
|
||||
throw new Doctrine_Exception("No primary key found");
|
||||
|
||||
$id[] = $this->data[$k];
|
||||
}
|
||||
$id = implode(' ', $id);
|
||||
|
||||
if(isset($this->identityMap[$id]))
|
||||
$record = $this->identityMap[$id];
|
||||
else {
|
||||
$record = new $this->name($this);
|
||||
$this->identityMap[$id] = $record;
|
||||
}
|
||||
$this->data = array();
|
||||
|
||||
return $record;
|
||||
}
|
||||
/**
|
||||
* @param $id database row id
|
||||
* @throws Doctrine_Find_Exception
|
||||
* @return DAOProxy a proxy for given identifier
|
||||
*/
|
||||
final public function getProxy($id = null) {
|
||||
if($id !== null) {
|
||||
$query = "SELECT ".implode(", ",$this->primaryKeys)." FROM ".$this->getTableName()." WHERE ".implode(" = ? && ",$this->primaryKeys)." = ?";
|
||||
$query = $this->applyInheritance($query);
|
||||
|
||||
$params = array_merge(array($id), array_values($this->inheritanceMap));
|
||||
|
||||
$this->data = $this->session->execute($query,$params)->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if($this->data === false)
|
||||
throw new Doctrine_Find_Exception();
|
||||
}
|
||||
return $this->getRecord();
|
||||
}
|
||||
/**
|
||||
* getTableDescription
|
||||
* @return Doctrine_Table_Description
|
||||
*/
|
||||
final public function getTableDescription() {
|
||||
return $this->columns;
|
||||
}
|
||||
/**
|
||||
* @return Doctrine_Query a Doctrine_Query object
|
||||
*/
|
||||
public function getQueryObject() {
|
||||
$graph = new Doctrine_Query($this->getSession());
|
||||
$graph->load($this->getComponentName());
|
||||
return $graph;
|
||||
}
|
||||
/**
|
||||
* execute
|
||||
* @param string $query
|
||||
* @param array $array
|
||||
* @param integer $limit
|
||||
* @param integer $offset
|
||||
*/
|
||||
public function execute($query, array $array = array(), $limit = null, $offset = null) {
|
||||
$coll = new Doctrine_Collection($this);
|
||||
$query = $this->session->modifyLimitQuery($query,$limit,$offset);
|
||||
if( ! empty($array)) {
|
||||
$stmt = $this->session->getDBH()->prepare($query);
|
||||
$stmt->execute($array);
|
||||
} else {
|
||||
$stmt = $this->session->getDBH()->query($query);
|
||||
}
|
||||
$data = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
$stmt->closeCursor();
|
||||
|
||||
foreach($data as $row) {
|
||||
$this->data = $row;
|
||||
$record = $this->getRecord();
|
||||
$coll->add($record);
|
||||
}
|
||||
return $coll;
|
||||
}
|
||||
/**
|
||||
* @return integer
|
||||
*/
|
||||
final public function getColumnCount() {
|
||||
return $this->columnCount;
|
||||
}
|
||||
/**
|
||||
* returns all columns and their definitions
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
final public function getColumns() {
|
||||
return $this->columns;
|
||||
}
|
||||
/**
|
||||
* returns an array containing all the column names
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getColumnNames() {
|
||||
return array_keys($this->columns);
|
||||
}
|
||||
/**
|
||||
* setData
|
||||
* doctrine uses this function internally
|
||||
* users are strongly discouraged to use this function
|
||||
*
|
||||
* @param array $data internal data
|
||||
* @return void
|
||||
*/
|
||||
public function setData(array $data) {
|
||||
$this->data = $data;
|
||||
}
|
||||
/**
|
||||
* returns the maximum primary key value
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
final public function getMaxIdentifier() {
|
||||
$sql = "SELECT MAX(".$this->getIdentifier().") FROM ".$this->getTableName();
|
||||
$stmt = $this->session->getDBH()->query($sql);
|
||||
$data = $stmt->fetch(PDO::FETCH_NUM);
|
||||
return isset($data[0])?$data[0]:1;
|
||||
}
|
||||
/**
|
||||
* return whether or not a newly created object is new or not
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
final public function isNewEntry() {
|
||||
return $this->isNewEntry;
|
||||
}
|
||||
/**
|
||||
* returns simple cached query
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
final public function getQuery() {
|
||||
return $this->query;
|
||||
}
|
||||
/**
|
||||
* returns internal data, used by Doctrine_Record instances
|
||||
* when retrieving data from database
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
final public function getData() {
|
||||
return $this->data;
|
||||
}
|
||||
/**
|
||||
* returns a string representation of this object
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString() {
|
||||
return Doctrine_Lib::getTableAsString($this);
|
||||
}
|
||||
}
|
||||
?>
|
186
Doctrine/Validator.php
Normal file
186
Doctrine/Validator.php
Normal file
@ -0,0 +1,186 @@
|
||||
<?php
|
||||
/**
|
||||
* Doctrine_Validator
|
||||
* Doctrine_Session uses this class for transaction validation
|
||||
*
|
||||
* @package Doctrine ORM
|
||||
* @url www.phpdoctrine.com
|
||||
* @license LGPL
|
||||
*/
|
||||
class Doctrine_Validator {
|
||||
/**
|
||||
* ERROR CONSTANTS
|
||||
*/
|
||||
|
||||
/**
|
||||
* constant for length validation error
|
||||
*/
|
||||
const ERR_LENGTH = 0;
|
||||
/**
|
||||
* constant for type validation error
|
||||
*/
|
||||
const ERR_TYPE = 1;
|
||||
/**
|
||||
* constant for general validation error
|
||||
*/
|
||||
const ERR_VALID = 2;
|
||||
/**
|
||||
* constant for unique validation error
|
||||
*/
|
||||
const ERR_UNIQUE = 3;
|
||||
/**
|
||||
* constant for blank validation error
|
||||
*/
|
||||
const ERR_BLANK = 4;
|
||||
/**
|
||||
* constant for date validation error
|
||||
*/
|
||||
const ERR_DATE = 5;
|
||||
/**
|
||||
* constant for null validation error
|
||||
*/
|
||||
const ERR_NULL = 6;
|
||||
/**
|
||||
* constant for enum validation error
|
||||
*/
|
||||
const ERR_ENUM = 7;
|
||||
/**
|
||||
* constant for range validation error
|
||||
*/
|
||||
const ERR_RANGE = 8;
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @var array $stack error stack
|
||||
*/
|
||||
private $stack = array();
|
||||
/**
|
||||
* @var array $validators an array of validator objects
|
||||
*/
|
||||
private static $validators = array();
|
||||
/**
|
||||
* returns a validator object
|
||||
*
|
||||
* @param string $name
|
||||
* @return Doctrine_Validator_Interface
|
||||
*/
|
||||
public static function getValidator($name) {
|
||||
if( ! isset(self::$validators[$name])) {
|
||||
$class = "Doctrine_Validator_".ucwords(strtolower($name));
|
||||
if(class_exists($class)) {
|
||||
self::$validators[$name] = new $class;
|
||||
} elseif(class_exists($name."Validator")) {
|
||||
self::$validators[$name] = new $name."Validator";
|
||||
} else
|
||||
throw new Doctrine_Exception("Validator named '$name' not availible.");
|
||||
}
|
||||
return self::$validators[$name];
|
||||
}
|
||||
/**
|
||||
* validates a given record and saves possible errors
|
||||
* in Doctrine_Validator::$stack
|
||||
*
|
||||
* @param Doctrine_Record $record
|
||||
* @return void
|
||||
*/
|
||||
public function validateRecord(Doctrine_Record $record) {
|
||||
$modified = $record->getModified();
|
||||
$columns = $record->getTable()->getColumns();
|
||||
$name = $record->getTable()->getComponentName();
|
||||
|
||||
$err = array();
|
||||
foreach($modified as $key => $value) {
|
||||
$column = $columns[$key];
|
||||
|
||||
if(strlen($value) > $column[1]) {
|
||||
$err[$key] = Doctrine_Validator::ERR_LENGTH;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(self::gettype($value) !== $column[0]) {
|
||||
$err[$key] = Doctrine_Validator::ERR_TYPE;
|
||||
continue;
|
||||
}
|
||||
|
||||
$e = explode("|",$column[2]);
|
||||
|
||||
foreach($e as $k => $arg) {
|
||||
if(empty($arg) || $arg == "primary" || $arg == "protected" || $arg == "autoincrement")
|
||||
continue;
|
||||
|
||||
$args = explode(":",$arg);
|
||||
if( ! isset($args[1]))
|
||||
$args[1] = '';
|
||||
|
||||
$validator = self::getValidator($args[0]);
|
||||
if( ! $validator->validate($record, $key, $value, $args[1])) {
|
||||
switch(strtolower($args[0])):
|
||||
case "unique":
|
||||
$err[$key] = Doctrine_Validator::ERR_UNIQUE;
|
||||
break;
|
||||
case "notnull":
|
||||
$err[$key] = Doctrine_Validator::ERR_NULL;
|
||||
break;
|
||||
case "notblank":
|
||||
$err[$key] = Doctrine_Validator::ERR_BLANK;
|
||||
break;
|
||||
case "enum":
|
||||
$err[$key] = Doctrine_Validator::ERR_VALID;
|
||||
break;
|
||||
default:
|
||||
$err[$key] = Doctrine_Validator::ERR_VALID;
|
||||
break;
|
||||
endswitch;
|
||||
}
|
||||
|
||||
// errors found quit validation looping for this column
|
||||
if(isset($err[$key]))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( ! empty($err)) {
|
||||
$this->stack[$name][] = $err;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* whether or not this validator has errors
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasErrors() {
|
||||
return (count($this->stack) > 0);
|
||||
}
|
||||
/**
|
||||
* returns the error stack
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getErrorStack() {
|
||||
return $this->stack;
|
||||
}
|
||||
/**
|
||||
* returns the type of loosely typed variable
|
||||
*
|
||||
* @param mixed $var
|
||||
* @return string
|
||||
*/
|
||||
public static function gettype($var) {
|
||||
$type = gettype($var);
|
||||
switch($type):
|
||||
case "string":
|
||||
if(preg_match("/^[0-9]+$/",$var)) return "integer";
|
||||
elseif(is_numeric($var)) return "float";
|
||||
else return $type;
|
||||
break;
|
||||
default:
|
||||
return $type;
|
||||
endswitch;
|
||||
}
|
||||
}
|
||||
?>
|
Loading…
x
Reference in New Issue
Block a user