1
0
mirror of synced 2024-12-13 14:56:01 +03:00

Tweaks to everything, refactoring hydrating.

This commit is contained in:
Jonathan.Wage 2007-09-25 21:39:38 +00:00
parent d4e34979d1
commit 8c8d8187a5
12 changed files with 398 additions and 254 deletions

View File

@ -1134,7 +1134,9 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
}
if ($deep) {
foreach ($this->_references as $key => $relation) {
$a[$key] = $relation->toArray($deep, $prefixKey);
if (!$relation instanceof Doctrine_Null) {
$a[$key] = $relation->toArray($deep, $prefixKey);
}
}
}
return array_merge($a, $this->_values);

View File

@ -31,110 +31,5 @@
* @link www.phpdoctrine.com
* @since 1.0
*/
class Doctrine_Resource_Access implements ArrayAccess
{
/**
* setArray
*
* @param array $array an array of key => value pairs
* @since 1.0
* @return Doctrine_Access
*/
public function setArray(array $array)
{
foreach ($array as $k=>$v) {
$this->set($k,$v);
}
return $this;
}
/**
* __set an alias of set()
*
* @see set, offsetSet
* @param $name
* @param $value
* @since 1.0
* @return void
*/
public function __set($name,$value)
{
$this->set($name,$value);
}
/**
* __get -- an alias of get()
*
* @see get, offsetGet
* @param mixed $name
* @since 1.0
* @return mixed
*/
public function __get($name)
{
return $this->get($name);
}
/**
* __isset()
*
* @param string $name
* @since 1.0
* @return boolean whether or not this object contains $name
*/
public function __isset($name)
{
return $this->contains($name);
}
/**
* __unset()
*
* @param string $name
* @since 1.0
* @return void
*/
public function __unset($name)
{
return $this->remove($name);
}
/**
* @param mixed $offset
* @return boolean whether or not this object contains $offset
*/
public function offsetExists($offset)
{
return $this->contains($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)
{
return $this->remove($offset);
}
}
class Doctrine_Resource_Access extends Doctrine_Access
{ }

View File

@ -64,7 +64,7 @@ class Doctrine_Resource_Client extends Doctrine_Resource
$path = '/tmp/' . md5(serialize($this->getConfig()));
$classesPath = $path.'.classes.php';
if (!file_exists($path)) {
if (file_exists($path)) {
$schema = file_get_contents($path);
} else {
$request = new Doctrine_Resource_Request();
@ -74,7 +74,7 @@ class Doctrine_Resource_Client extends Doctrine_Resource
$schema = $request->execute();
if ($schema) {
file_put_contents($path, $schema);
file_put_contents($path, Doctrine_Parser::dump($schema, $this->getConfig()->get('format')));
}
}
@ -86,6 +86,8 @@ class Doctrine_Resource_Client extends Doctrine_Resource
$build = "<?php\n";
foreach ($schema['schema'] as $className => $details) {
$build .= "class " . $className . " extends Doctrine_Resource_Record { protected \$_model = '".$className."'; public function __construct(\$loadRelations = true) { parent::__construct(\$this->_model, \$loadRelations); } }\n";
$schema['schema'][$className]['relations'] = isset($schema['relations'][$className]) ? $schema['relations'][$className]:array();
}
file_put_contents($classesPath, $build);
@ -99,6 +101,64 @@ class Doctrine_Resource_Client extends Doctrine_Resource
public function getTable($table)
{
return new Doctrine_Resource_Table($table);
static $instance;
if(!isset($instance[$table])) {
$instance[$table] = new Doctrine_Resource_Table($table);
}
return $instance[$table];
}
public function printSchema()
{
$schema = $this->getConfig('schema');
echo '<h2>Schema</h2>';
echo '<ul>';
foreach ($schema['schema'] as $className => $info) {
echo '<a name="'.$className.'"></a>';
echo '<li><h3>'.$className.'</h3></li>';
echo '<ul>';
echo '<li>Columns';
echo '<ul>';
foreach ($info['columns'] as $columnName => $column)
{
echo '<li>' . $columnName;
echo '<ul>';
foreach ($column as $key => $value) {
if ($value) {
echo '<li>'.$key.': '.$value.'</li>';
}
}
echo '</ul>';
echo '</li>';
}
echo '</ul>';
echo '</li>';
echo '</ul>';
if (isset($info['relations']) && !empty($info['relations'])) {
echo '<ul>';
echo '<li>Relations';
echo '<ul>';
foreach ($info['relations'] as $relationName => $relation)
{
echo '<li><a href="#'.$relation['class'].'">' . $relationName . '</a></li>';
}
echo '</ul>';
echo '</li>';
echo '</ul>';
}
}
echo '</ul>';
exit;
}
}

View File

@ -36,12 +36,18 @@ class Doctrine_Resource_Collection extends Doctrine_Resource_Access implements C
protected $_data = array();
protected $_config = array();
protected $_model = null;
protected $_parent = null;
public function __construct($model)
{
$this->_model = $model;
}
public function setParent($parent)
{
$this->_parent = $parent;
}
public function getConfig($key = null)
{
return Doctrine_Resource_Client::getInstance()->getConfig($key);
@ -52,16 +58,24 @@ class Doctrine_Resource_Collection extends Doctrine_Resource_Access implements C
return count($this->_data);
}
public function get($get)
public function get($key)
{
if (isset($this->_data[$get])) {
return $this->_data[$get];
if (!$key || !isset($this->_data[$key])) {
return $this->add();
} else {
return $this->_data[$key];
}
}
public function set($set, $value)
public function set($key, $value)
{
$this->_data[$set] = $value;
if (!$key || !isset($this->_data[$key])) {
$this->_data[$key] = $value;
} else {
$val = $this->add();
$val->_data[$key] = $value;
}
}
public function add($value = null)
@ -69,7 +83,19 @@ class Doctrine_Resource_Collection extends Doctrine_Resource_Access implements C
if (!$value) {
$model = $this->_model;
$value = new $model();
$value = new $model(false);
$table = $value->getTable();
$relation = $table->getRelationByClassName(get_class($this->_parent));
$alias = $relation['alias'];
if ($relation['type'] === Doctrine_Relation::ONE) {
$value->set($alias, $this->_parent);
} else {
$collection = new Doctrine_Resource_Collection($relation['class']);
$collection[] = $this->_parent;
$value->set($alias, $collection);
}
}
$this->_data[] = $value;
@ -87,13 +113,13 @@ class Doctrine_Resource_Collection extends Doctrine_Resource_Access implements C
return isset($this->_data[0]) ? $this->_data[0]:null;
}
public function toArray()
public function toArray($deep = false)
{
$array = array();
foreach ($this->_data as $key => $record) {
if ($record->exists() || $record->hasChanges()) {
$array[$this->_model . '_' .$key] = $record->toArray();
$array[$this->_model . '_' .$key] = $record->toArray($deep);
}
}

View File

@ -57,17 +57,22 @@ class Doctrine_Resource_Query
$request->set('params', $params);
$request->set('format', $this->getConfig()->get('format'));
$request->set('type', 'query');
$request->set('model', $this->getModel());
$response = $request->execute();
// If we have a response then lets parse it and hydrate it
if ($response) {
$array = Doctrine_Parser::load($response, $this->getConfig()->get('format'));
return $request->hydrate($array, $this->getModel());
if (!empty($response)) {
return $request->hydrate($response, $this->getModel());
// Otherwise lets return an empty collection for the queried for model
} else {
return new Doctrine_Resource_Collection($this->getModel());
$model = $this->getModel();
$collection = new Doctrine_Resource_Collection($this->getModel());
$collection[] = new $model(false);
return $collection;
}
}

View File

@ -35,13 +35,11 @@ class Doctrine_Resource_Record extends Doctrine_Resource_Access implements Count
{
protected $_data = array();
protected $_model = null;
protected $_table = null;
protected $_changes = array();
public function __construct($model, $loadRelations = true)
{
$this->_model = $model;
$this->_table = Doctrine_Resource_Client::getInstance()->getTable($model);
$this->initialize($loadRelations);
}
@ -74,6 +72,7 @@ class Doctrine_Resource_Record extends Doctrine_Resource_Access implements Count
$this->_data[$relation['alias']] = new $relation['class'](false);
} else {
$this->_data[$relation['alias']] = new Doctrine_Resource_Collection($relation['class']);
$this->_data[$relation['alias']]->setParent($this);
}
}
}
@ -86,18 +85,65 @@ class Doctrine_Resource_Record extends Doctrine_Resource_Access implements Count
public function get($key)
{
if (!$key) {
return;
}
if (!isset($this->_data[$key]) && $this->getTable()->hasRelation($key)) {
$this->_data[$key] = $this->createRelation($key);
}
if (!array_key_exists($key, $this->_data)) {
throw new Doctrine_Resource_Exception('Unknown property / related component: '.$key);
}
return $this->_data[$key];
}
public function set($key, $value)
{
if ($this->_data[$key] != $value) {
if (!$key) {
return;
}
if (!isset($this->_data[$key]) && $this->getTable()->hasRelation($key)) {
$this->_data[$key] = $this->createRelation($key);
}
if (!array_key_exists($key, $this->_data)) {
throw new Doctrine_Resource_Exception('Unknown property / related component: '.$key);
}
if ($this->_data[$key] != $value && !$value instanceof Doctrine_Resource_Record && !$value instanceof Doctrine_Resource_Collection) {
$this->_changes[$key] = $value;
}
$this->_data[$key] = $value;
}
public function createRelation($key)
{
$relation = $this->getTable()->getRelation($key);
$class = $relation['class'];
if ($relation['type'] === Doctrine_Relation::ONE) {
$return = new $class(false);
$table = $return->getTable();
$returnRelation = $table->getRelationByClassName(get_class($this));
if ($returnRelation) {
$returnClass = new $returnRelation['class'](false);
$return->set($returnRelation['alias'], $returnClass);
}
} else {
$return = new Doctrine_Resource_Collection($class);
$return->setParent($this);
}
return $return;
}
public function count()
{
return count($this->_data);
@ -108,8 +154,45 @@ class Doctrine_Resource_Record extends Doctrine_Resource_Access implements Count
return new ArrayIterator($this->_data);
}
public function sameAs(Doctrine_Resource_Record $record)
{
// If we have same class name
if (get_class($this) == get_class($record)) {
// If we have 2 records that exist and are persistant
if ($record->exists() && $this->exists()) {
if ($record->identifier() === $this->identifier()) {
return true;
} else {
return false;
}
// If we have unsaved records then lets compare the data
} else {
if ($record->toArray(false) === $this->toArray(false)) {
return true;
} else {
return false;
}
}
} else {
return false;
}
}
public function getChanges()
{
global $gotten;
if (!$gotten) {
$gotten = array();
}
$md5Hash = $this->getMd5Hash();
if (!in_array($md5Hash, $gotten)) {
$gotten[] = $md5Hash;
}
$array = array();
foreach ($this->_data as $key => $value) {
@ -117,13 +200,13 @@ class Doctrine_Resource_Record extends Doctrine_Resource_Access implements Count
$relation = $this->getTable()->getRelation($key);
if ($relation['type'] === Doctrine_Relation::ONE) {
if ($this->_data[$key]->hasChanges()) {
$array[$key] = $this->_data[$key]->getChanges();
if ($value instanceof Doctrine_Resource_Record) {
if ($value->hasChanges() && !in_array($value->getMd5Hash(), $gotten)) {
$array[$key] = $value->getChanges();
}
} else {
foreach ($this->_data[$key] as $key2 => $record) {
if ($record->hasChanges()) {
} else if($value instanceof Doctrine_Resource_Collection) {
foreach ($value as $key2 => $record) {
if ($record->hasChanges() && !in_array($record->getMd5Hash(), $gotten)) {
$array[$key][$record->getModel() . '_' .$key2] = $record->getChanges();
}
}
@ -160,9 +243,9 @@ class Doctrine_Resource_Record extends Doctrine_Resource_Access implements Count
$response = $request->execute();
$array = Doctrine_Parser::load($response, $format);
$this->_data = $request->hydrate(array($response), $this->_model, array($this))->getFirst()->_data;
$this->_data = $request->hydrate(array($array), $this->_model)->getFirst()->_data;
$this->clearChanges();
}
public function delete()
@ -180,7 +263,9 @@ class Doctrine_Resource_Record extends Doctrine_Resource_Access implements Count
public function getTable()
{
return $this->_table;
$model = $this->_model;
return Doctrine_Resource_Client::getInstance()->getTable($model);
}
public function getModel()
@ -219,19 +304,37 @@ class Doctrine_Resource_Record extends Doctrine_Resource_Access implements Count
return true;
}
public function toArray()
public function toArray($deep = false)
{
global $gotten;
if (!$gotten) {
$gotten = array();
}
$md5Hash = $this->getMd5Hash();
if (!in_array($md5Hash, $gotten)) {
$gotten[] = $md5Hash;
}
$array = array();
foreach ($this->_data as $key => $value) {
if ($this->getTable()->hasRelation($key) && $value instanceof Doctrine_Resource_Collection) {
if ($value->count() > 0) {
$array[$key] = $value->toArray();
}
} else if ($this->getTable()->hasRelation($key) && $value instanceof Doctrine_Resource_Record) {
if ($value->exists() || $value->hasChanges()) {
$array[$key] = $value->toArray();
if ($deep && $this->getTable()->hasRelation($key)) {
if ($value instanceof Doctrine_Resource_Collection) {
if ($value->count() > 0) {
foreach ($value as $key2 => $record) {
if (($record->exists() || $record->hasChanges()) && !in_array($record->getMd5Hash(), $gotten)) {
$array[$key][get_class($record) . '_' . $key2] = $record->toArray($deep);
}
}
}
} else if ($value instanceof Doctrine_Resource_Record) {
if (($value->exists() || $value->hasChanges()) && !in_array($value->getMd5Hash(), $gotten)) {
$array[$key] = $value->toArray($deep);
}
}
} else if (!$this->getTable()->hasRelation($key) && $this->getTable()->hasColumn($key)) {
$array[$key] = $value;
@ -240,4 +343,9 @@ class Doctrine_Resource_Record extends Doctrine_Resource_Access implements Count
return $array;
}
public function getMd5Hash()
{
return md5(serialize($this->_data));
}
}

View File

@ -59,28 +59,67 @@ class Doctrine_Resource_Request extends Doctrine_Resource_Params
curl_close($ch);
return $response;
}
$array = array();
public function hydrate(array $array, $model, $passedKey = null)
{
if (empty($array)) {
return false;
if ($response) {
$array = Doctrine_Parser::load($response, $this->getConfig()->get('format'));
}
if (isset($array['error'])) {
throw new Doctrine_Resource_Exception($array['error']);
}
return $array;
}
public function hydrate(array $array, $model, $records = array())
{
$collection = new Doctrine_Resource_Collection($model);
foreach ($array as $record) {
$r = new $model();
foreach ($array as $recordKey => $record) {
if (isset($records[$recordKey])) {
$r = $records[$recordKey];
} else {
$r = new $model(false);
}
foreach ($record as $key => $value) {
if ($r->getTable()->hasRelation($key) && !empty($value)) {
$relation = $r->getTable()->getRelation($key);
if ($relation['type'] === Doctrine_Relation::MANY) {
$r->set($key, $this->hydrate($value, $relation['class'], $key));
$relationCollection = $this->hydrate($value, $relation['class']);
$relationCollection->setParent($r);
foreach ($relationCollection as $relationRecord) {
$relationTable = $relationRecord->getTable();
if ($relation = $relationTable->getRelationByClassName($model)) {
if ($relation['type'] === Doctrine_Relation::ONE) {
$relationRecord->set($relation['alias'], $r);
$relationRecord->clearChanges();
} else {
$coll = new Doctrine_Resource_Collection($relation['class']);
$coll[] = $r;
$relationRecord->set($relation['alias'], $coll);
}
$relationRecord->clearChanges();
}
}
$r->set($key, $relationCollection);
} else {
$r->set($key, $this->hydrate(array($value), $relation['class'], $key)->getFirst());
$relationRecord = $this->hydrate(array($value), $relation['class'])->getFirst();
$relationTable = $relationRecord->getTable();
if ($relation = $relationTable->getRelationByClassName($model)) {
$relationRecord->set($relation['alias'], $r);
$relationRecord->clearChanges();
}
$r->set($key, $relationRecord);
}
} else if($r->getTable()->hasColumn($key)) {
$r->set($key, $value);

View File

@ -141,12 +141,25 @@ class Doctrine_Resource_Server extends Doctrine_Resource
if ($result) {
return Doctrine_Parser::dump($result, $format);
} else {
return false;
return null;
}
}
public function run($request)
{
echo $this->execute($request);
try {
$result = $this->execute($request);
echo $result;
} catch(Exception $e) {
echo $this->exception($e);
}
}
public function exception($e)
{
$error = array('error' => $e->getMessage());
return Doctrine_Parser::dump($error);
}
}

View File

@ -48,6 +48,7 @@ class Doctrine_Resource_Table
if (isset($schema['relations'][$model]) && $schema['relations'][$model]) {
$this->_schema['relations'] = $schema['relations'][$model];
$this->_schema['schema']['relations'] = $this->_schema['relations'];
}
}
@ -61,6 +62,11 @@ class Doctrine_Resource_Table
return $this->_schema['relations'];
}
public function getColumns()
{
return $this->_schema['columns'];
}
public function getConfig($key = null)
{
return Doctrine_Resource_Client::getInstance()->getConfig($key);
@ -85,7 +91,9 @@ class Doctrine_Resource_Table
$query = new Doctrine_Resource_Query();
$query->from($model)->where($where)->limit(1);
return $query->execute()->getFirst();
$result = $query->execute();
return $result->getFirst();
}
public function hasColumn($name)
@ -111,4 +119,35 @@ class Doctrine_Resource_Table
return $this->_schema['relations'][$name];
}
}
public function getRelationByClassName($name)
{
$relations = $this->getRelations();
foreach ($relations as $relation) {
if ($relation['class'] === $name) {
return $relation;
}
}
return false;
}
public function getIdentifier()
{
$identifier = array();
$schema = $this->getSchema();
$columns = $schema['columns'];
if (isset($columns) && is_array($columns)) {
foreach ($columns as $name => $column) {
if ($column['primary'] == true) {
$identifier[$name] = $name;
}
}
}
return $identifier;
}
}

View File

@ -16,6 +16,11 @@ class User extends Entity
'foreign' => 'address_id',
'refClass' => 'EntityAddress',
));
$this->hasMany('Address as Addresses', array(
'local' => 'user_id',
'foreign' => 'address_id',
'refClass' => 'EntityAddress',
));
$this->hasMany('Album', array('local' => 'id', 'foreign' => 'user_id'));
$this->hasMany('Book', array('local' => 'id', 'foreign' => 'user_id'));
$this->hasMany('Group', array(

View File

@ -16,6 +16,8 @@ $users[0]->name = 'zYne';
$users[0]['Email']->address = 'zYne@example.com';
$users[0]['Phonenumber'][0]->phonenumber = '123 123';
$users[0]['Address'][0]->address = '112 2nd ave';
$users[1]->name = 'Arnold Schwarzenegger';
$users[1]->Email->address = 'arnold@example.com';
$users[1]['Phonenumber'][0]->phonenumber = '123 123';

View File

@ -21,104 +21,54 @@ if ($action == 'server') {
// Instantiate a new client
$client = Doctrine_Resource_Client::getInstance($url, $config);
$query = new Doctrine_Resource_Query();
$users = $query->from('User u, u.Group g')->execute();
print_r($users->toArray(true));
/*
$group = new Group();
$group->name = 'Jon';
$group->save();
print_r($group->toArray());
*/
//$client->printSchema();
/*
// Retrieve a models table object
$table = $client->getTable('User');
// Find record by identifier
$user = $table->find(4);
// 2 ways to create queries
$query = new Doctrine_Resource_Query();
$query->from('User u, u.Phonenumber p')->limit(2);
// returns users
$users = $query->execute();
print_r($users->toArray());
/*
Array
(
[User_0] => Array
(
[id] => 4
[name] => zYne
[loginname] =>
[password] =>
[type] => 0
[created] =>
[updated] =>
[email_id] => 1
[Phonenumber] => Array
(
[Phonenumber_0] => Array
(
[id] => 2
[phonenumber] => 123 123
[entity_id] => 4
)
)
)
[User_1] => Array
(
[id] => 5
[name] => Arnold Schwarzenegger
[loginname] =>
[password] =>
[type] => 0
[created] =>
[updated] =>
[email_id] => 2
[Phonenumber] => Array
(
[Phonenumber_0] => Array
(
[id] => 3
[phonenumber] => 123 123
[entity_id] => 5
)
[Phonenumber_1] => Array
(
[id] => 4
[phonenumber] => 456 456
[entity_id] => 5
)
[Phonenumber_2] => Array
(
[id] => 5
[phonenumber] => 789 789
[entity_id] => 5
)
)
)
)
*/
$user = new User();
$user->name = 'Jonathan H. Wage';
$user->name = 'Jon Wage';
$user->Email->address = 'jonwage@gmail.com';
$phone = $user->Phonenumber[0];
$phone->phonenumber = '555-5555';
$phone = $user->Phonenumber[1];
$phone->phonenumber = '555-55555';
$user->Phonenumber[2]->phonenumber = '555';
$user->Account->amount = 50.00;
$user->Account->amount = 25.25;
$address = $user->Address[0];
$address->address = '112 2nd Ave North';
$album = $user->Album[0];
$album->name = 'test album';
$song = $album->Song[0];
$song->title = 'test author';
$user->save();
print_r($user->toArray());
/*
Array
(
[id] => 12
[name] => Jonathan H. Wage
[loginname] =>
[password] =>
[type] => 0
[created] =>
[updated] =>
[email_id] =>
)
print_r($user->toArray(true));
*/
}