From 9992cf30fc78593ecf1879eeee1556517b15353e Mon Sep 17 00:00:00 2001 From: "Jonathan.Wage" Date: Fri, 21 Sep 2007 18:01:08 +0000 Subject: [PATCH] Fixes for Doctrine_Resource. --- lib/Doctrine/Resource.php | 8 +- lib/Doctrine/Resource/Client.php | 362 +-------------------- lib/Doctrine/Resource/Collection.php | 41 +++ lib/Doctrine/Resource/Exception.php | 4 + lib/Doctrine/Resource/Query.php | 449 +++++++++++++++++++++++++++ lib/Doctrine/Resource/Record.php | 65 ++++ lib/Doctrine/Resource/Server.php | 68 ++-- playground/models.php | 1 + 8 files changed, 615 insertions(+), 383 deletions(-) create mode 100644 lib/Doctrine/Resource/Collection.php create mode 100644 lib/Doctrine/Resource/Exception.php create mode 100644 lib/Doctrine/Resource/Query.php create mode 100644 lib/Doctrine/Resource/Record.php diff --git a/lib/Doctrine/Resource.php b/lib/Doctrine/Resource.php index 729000087..4f9b618ee 100644 --- a/lib/Doctrine/Resource.php +++ b/lib/Doctrine/Resource.php @@ -1,5 +1,11 @@ resourceUrl = $resourceUrl; + $this->config = $config; } - public function execute($dql = null) + public function newQuery() { - $request = array(); - - if ($dql === null) { - $request['parts'] = $this->parts; - } else { - $request['dql'] = $dql; - } - - $request['format'] = $this->format; - - - $ch = curl_init(); - curl_setopt($ch, CURLOPT_URL, $this->resourceUrl); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); - curl_setopt($ch, CURLOPT_POST, 1); - - curl_setopt($ch, CURLOPT_POSTFIELDS, $request); - $data = curl_exec($ch); - - return Doctrine_Parser::load($data, $this->format); + return new Doctrine_Resource_Query($this->config); } - - public function setFormat($format) - { - $this->format = $format; - - return $this; - } - - /** - * addSelect - * adds fields to the SELECT part of the query - * - * @param string $select Query SELECT part - * @return Doctrine_Query - */ - public function addSelect($select) - { - return $this->parseQueryPart('select', $select, true); - } - /** - * addFrom - * adds fields to the FROM part of the query - * - * @param string $from Query FROM part - * @return Doctrine_Query - */ - public function addFrom($from) - { - return $this->parseQueryPart('from', $from, true); - } - /** - * addWhere - * adds conditions to the WHERE part of the query - * - * @param string $where Query WHERE part - * @param mixed $params an array of parameters or a simple scalar - * @return Doctrine_Query - */ - public function addWhere($where, $params = array()) - { - if (is_array($params)) { - $this->_params['where'] = array_merge($this->_params['where'], $params); - } else { - $this->_params['where'][] = $params; - } - return $this->parseQueryPart('where', $where, true); - } - /** - * whereIn - * adds IN condition to the query WHERE part - * - * @param string $expr - * @param mixed $params an array of parameters or a simple scalar - * @return Doctrine_Query - */ - public function whereIn($expr, $params = array()) - { - $params = (array) $params; - $a = array(); - foreach ($params as $k => $value) { - if ($value instanceof Doctrine_Expression) { - $value = $value->getSql(); - unset($params[$k]); - } else { - $value = '?'; - } - $a[] = $value; - } - - $this->_params['where'] = array_merge($this->_params['where'], $params); - - $where = $expr . ' IN (' . implode(', ', $a) . ')'; - - return $this->parseQueryPart('where', $where, true); - } - /** - * addGroupBy - * adds fields to the GROUP BY part of the query - * - * @param string $groupby Query GROUP BY part - * @return Doctrine_Query - */ - public function addGroupBy($groupby) - { - return $this->parseQueryPart('groupby', $groupby, true); - } - /** - * addHaving - * adds conditions to the HAVING part of the query - * - * @param string $having Query HAVING part - * @param mixed $params an array of parameters or a simple scalar - * @return Doctrine_Query - */ - public function addHaving($having, $params = array()) - { - if (is_array($params)) { - $this->_params['having'] = array_merge($this->_params['having'], $params); - } else { - $this->_params['having'][] = $params; - } - return $this->parseQueryPart('having', $having, true); - } - /** - * addOrderBy - * adds fields to the ORDER BY part of the query - * - * @param string $orderby Query ORDER BY part - * @return Doctrine_Query - */ - public function addOrderBy($orderby) - { - return $this->parseQueryPart('orderby', $orderby, true); - } - /** - * select - * sets the SELECT part of the query - * - * @param string $select Query SELECT part - * @return Doctrine_Query - */ - public function select($select) - { - return $this->parseQueryPart('select', $select); - } - /** - * distinct - * Makes the query SELECT DISTINCT. - * - * @param bool $flag Whether or not the SELECT is DISTINCT (default true). - * @return Doctrine_Query - */ - public function distinct($flag = true) - { - $this->parts['distinct'] = (bool) $flag; - - return $this; - } - - /** - * forUpdate - * Makes the query SELECT FOR UPDATE. - * - * @param bool $flag Whether or not the SELECT is FOR UPDATE (default true). - * @return Doctrine_Query - */ - public function forUpdate($flag = true) - { - $this->parts[self::FOR_UPDATE] = (bool) $flag; - - return $this; - } - /** - * delete - * sets the query type to DELETE - * - * @return Doctrine_Query - */ - public function delete() - { - $this->type = self::DELETE; - - return $this; - } - /** - * update - * sets the UPDATE part of the query - * - * @param string $update Query UPDATE part - * @return Doctrine_Query - */ - public function update($update) - { - $this->type = self::UPDATE; - - return $this->parseQueryPart('from', $update); - } - /** - * set - * sets the SET part of the query - * - * @param string $update Query UPDATE part - * @return Doctrine_Query - */ - public function set($key, $value, $params = null) - { - if (is_array($key)) { - foreach ($key as $k => $v) { - $this->set($k, '?', array($v)); - } - } else { - if ($params !== null) { - if (is_array($params)) { - $this->_params['set'] = array_merge($this->_params['set'], $params); - } else { - $this->_params['set'][] = $params; - } - } - return $this->parseQueryPart('set', $key . ' = ' . $value, true); - } - } - /** - * from - * sets the FROM part of the query - * - * @param string $from Query FROM part - * @return Doctrine_Query - */ - public function from($from) - { - return $this->parseQueryPart('from', $from); - } - /** - * innerJoin - * appends an INNER JOIN to the FROM part of the query - * - * @param string $join Query INNER JOIN - * @return Doctrine_Query - */ - public function innerJoin($join) - { - return $this->parseQueryPart('from', 'INNER JOIN ' . $join, true); - } - /** - * leftJoin - * appends a LEFT JOIN to the FROM part of the query - * - * @param string $join Query LEFT JOIN - * @return Doctrine_Query - */ - public function leftJoin($join) - { - return $this->parseQueryPart('from', 'LEFT JOIN ' . $join, true); - } - /** - * groupBy - * sets the GROUP BY part of the query - * - * @param string $groupby Query GROUP BY part - * @return Doctrine_Query - */ - public function groupBy($groupby) - { - return $this->parseQueryPart('groupby', $groupby); - } - /** - * where - * sets the WHERE part of the query - * - * @param string $join Query WHERE part - * @param mixed $params an array of parameters or a simple scalar - * @return Doctrine_Query - */ - public function where($where, $params = array()) - { - $this->_params['where'] = array(); - if (is_array($params)) { - $this->_params['where'] = $params; - } else { - $this->_params['where'][] = $params; - } - - return $this->parseQueryPart('where', $where); - } - /** - * having - * sets the HAVING part of the query - * - * @param string $having Query HAVING part - * @param mixed $params an array of parameters or a simple scalar - * @return Doctrine_Query - */ - public function having($having, $params = array()) - { - $this->_params['having'] = array(); - if (is_array($params)) { - $this->_params['having'] = $params; - } else { - $this->_params['having'][] = $params; - } - - return $this->parseQueryPart('having', $having); - } - /** - * orderBy - * sets the ORDER BY part of the query - * - * @param string $orderby Query ORDER BY part - * @return Doctrine_Query - */ - public function orderBy($orderby) - { - return $this->parseQueryPart('orderby', $orderby); - } - /** - * limit - * sets the Query query limit - * - * @param integer $limit limit to be used for limiting the query results - * @return Doctrine_Query - */ - public function limit($limit) - { - return $this->parseQueryPart('limit', $limit); - } - /** - * offset - * sets the Query query offset - * - * @param integer $offset offset to be used for paginating the query - * @return Doctrine_Query - */ - public function offset($offset) - { - return $this->parseQueryPart('offset', $offset); - } - - /** - * parseQueryPart - * parses given DQL query part - * - * @param string $queryPartName the name of the query part - * @param string $queryPart query part to be parsed - * @return Doctrine_Query this object - */ - public function parseQueryPart($queryPartName, $queryPart) - { - $this->parts[$queryPartName][] = $queryPart; - - return $this; - } } \ No newline at end of file diff --git a/lib/Doctrine/Resource/Collection.php b/lib/Doctrine/Resource/Collection.php new file mode 100644 index 000000000..359e6b202 --- /dev/null +++ b/lib/Doctrine/Resource/Collection.php @@ -0,0 +1,41 @@ +data; + + return new ArrayIterator($data); + } + + public function save() + { + foreach ($data as $record) { + $record->save(); + } + } + + public function getFirst() + { + return $this->data[0]; + } + + public function toArray() + { + $array = array(); + foreach($this->data as $key => $record) { + $array[$key] = $record->toArray(); + } + + return $array; + } +} \ No newline at end of file diff --git a/lib/Doctrine/Resource/Exception.php b/lib/Doctrine/Resource/Exception.php new file mode 100644 index 000000000..d7ef6e270 --- /dev/null +++ b/lib/Doctrine/Resource/Exception.php @@ -0,0 +1,4 @@ +config = $config; + } + + public function query($dql, $params = array()) + { + $this->dql = $dql; + + return $this->execute($params); + } + + public function execute($params = array()) + { + $request = array(); + $request['dql'] = $this->getDql(); + $request['params'] = $params; + $request['format'] = $this->getFormat(); + $request['type'] = 'query'; + + $response = self::request($this->config['url'], $request); + + return $this->parseResponse($response); + } + + public function getDql() + { + if (!$this->dql && !empty($this->parts)) { + $q = ''; + $q .= ( ! empty($this->parts['select']))? 'SELECT ' . implode(', ', $this->parts['select']) : ''; + $q .= ( ! empty($this->parts['from']))? ' FROM ' . implode(' ', $this->parts['from']) : ''; + $q .= ( ! empty($this->parts['where']))? ' WHERE ' . implode(' AND ', $this->parts['where']) : ''; + $q .= ( ! empty($this->parts['groupby']))? ' GROUP BY ' . implode(', ', $this->parts['groupby']) : ''; + $q .= ( ! empty($this->parts['having']))? ' HAVING ' . implode(' AND ', $this->parts['having']) : ''; + $q .= ( ! empty($this->parts['orderby']))? ' ORDER BY ' . implode(', ', $this->parts['orderby']) : ''; + $q .= ( ! empty($this->parts['limit']))? ' LIMIT ' . implode(' ', $this->parts['limit']) : ''; + $q .= ( ! empty($this->parts['offset']))? ' OFFSET ' . implode(' ', $this->parts['offset']) : ''; + + return $q; + } else { + return $this->dql; + } + } + + public function parseResponse($response) + { + $array = Doctrine_Parser::load($response, $this->getFormat()); + + $hydrated = $this->hydrate($array); + + return $hydrated; + } + + public function buildUrl($array) + { + $url = ''; + + foreach ($array as $key => $value) { + if (is_array($value)) { + $url .= $this->buildUrl($value); + } else { + $url .= $key.'='.$value.'&'; + } + } + + return $url; + } + + public function hydrate(array $array, $passedKey = null) + { + $model = $passedKey ? $passedKey:$this->getModel(); + + $collection = new Doctrine_Resource_Collection(); + $collection->model = $model; + $collection->config = $this->config; + + foreach ($array as $record) { + $r = new Doctrine_Resource_Record(); + $r->config = $this->config; + $r->model = $model; + + foreach ($record as $key => $value) { + if (is_array($value)) { + $r->data[$key] = $this->hydrate($value, $key); + } else { + $r->data[$key] = $value; + } + } + + $collection->data[] = $r; + } + + return $collection; + } + + public function getModel() + { + $dql = $this->getDql(); + + $e = explode('FROM ', $dql); + $e = explode(' ', $e[1]); + + return $e[0]; + } + + public function setFormat($format) + { + $this->config['format'] = $format; + + return $this; + } + + public function getFormat() + { + return isset($this->config['format']) ? $this->config['format']:$this->defaultFormat; + } + + /** + * addSelect + * adds fields to the SELECT part of the query + * + * @param string $select Query SELECT part + * @return Doctrine_Query + */ + public function addSelect($select) + { + return $this->parseQueryPart('select', $select, true); + } + /** + * addFrom + * adds fields to the FROM part of the query + * + * @param string $from Query FROM part + * @return Doctrine_Query + */ + public function addFrom($from) + { + return $this->parseQueryPart('from', $from, true); + } + /** + * addWhere + * adds conditions to the WHERE part of the query + * + * @param string $where Query WHERE part + * @param mixed $params an array of parameters or a simple scalar + * @return Doctrine_Query + */ + public function addWhere($where, $params = array()) + { + if (is_array($params)) { + $this->_params['where'] = array_merge($this->_params['where'], $params); + } else { + $this->_params['where'][] = $params; + } + return $this->parseQueryPart('where', $where, true); + } + /** + * whereIn + * adds IN condition to the query WHERE part + * + * @param string $expr + * @param mixed $params an array of parameters or a simple scalar + * @return Doctrine_Query + */ + public function whereIn($expr, $params = array()) + { + $params = (array) $params; + $a = array(); + foreach ($params as $k => $value) { + if ($value instanceof Doctrine_Expression) { + $value = $value->getSql(); + unset($params[$k]); + } else { + $value = '?'; + } + $a[] = $value; + } + + $this->_params['where'] = array_merge($this->_params['where'], $params); + + $where = $expr . ' IN (' . implode(', ', $a) . ')'; + + return $this->parseQueryPart('where', $where, true); + } + /** + * addGroupBy + * adds fields to the GROUP BY part of the query + * + * @param string $groupby Query GROUP BY part + * @return Doctrine_Query + */ + public function addGroupBy($groupby) + { + return $this->parseQueryPart('groupby', $groupby, true); + } + /** + * addHaving + * adds conditions to the HAVING part of the query + * + * @param string $having Query HAVING part + * @param mixed $params an array of parameters or a simple scalar + * @return Doctrine_Query + */ + public function addHaving($having, $params = array()) + { + if (is_array($params)) { + $this->_params['having'] = array_merge($this->_params['having'], $params); + } else { + $this->_params['having'][] = $params; + } + return $this->parseQueryPart('having', $having, true); + } + /** + * addOrderBy + * adds fields to the ORDER BY part of the query + * + * @param string $orderby Query ORDER BY part + * @return Doctrine_Query + */ + public function addOrderBy($orderby) + { + return $this->parseQueryPart('orderby', $orderby, true); + } + /** + * select + * sets the SELECT part of the query + * + * @param string $select Query SELECT part + * @return Doctrine_Query + */ + public function select($select) + { + return $this->parseQueryPart('select', $select); + } + /** + * distinct + * Makes the query SELECT DISTINCT. + * + * @param bool $flag Whether or not the SELECT is DISTINCT (default true). + * @return Doctrine_Query + */ + public function distinct($flag = true) + { + $this->parts['distinct'] = (bool) $flag; + + return $this; + } + + /** + * forUpdate + * Makes the query SELECT FOR UPDATE. + * + * @param bool $flag Whether or not the SELECT is FOR UPDATE (default true). + * @return Doctrine_Query + */ + public function forUpdate($flag = true) + { + $this->parts[self::FOR_UPDATE] = (bool) $flag; + + return $this; + } + /** + * delete + * sets the query type to DELETE + * + * @return Doctrine_Query + */ + public function delete() + { + $this->type = self::DELETE; + + return $this; + } + /** + * update + * sets the UPDATE part of the query + * + * @param string $update Query UPDATE part + * @return Doctrine_Query + */ + public function update($update) + { + $this->type = self::UPDATE; + + return $this->parseQueryPart('from', $update); + } + /** + * set + * sets the SET part of the query + * + * @param string $update Query UPDATE part + * @return Doctrine_Query + */ + public function set($key, $value, $params = null) + { + if (is_array($key)) { + foreach ($key as $k => $v) { + $this->set($k, '?', array($v)); + } + } else { + if ($params !== null) { + if (is_array($params)) { + $this->_params['set'] = array_merge($this->_params['set'], $params); + } else { + $this->_params['set'][] = $params; + } + } + return $this->parseQueryPart('set', $key . ' = ' . $value, true); + } + } + /** + * from + * sets the FROM part of the query + * + * @param string $from Query FROM part + * @return Doctrine_Query + */ + public function from($from) + { + return $this->parseQueryPart('from', $from); + } + /** + * innerJoin + * appends an INNER JOIN to the FROM part of the query + * + * @param string $join Query INNER JOIN + * @return Doctrine_Query + */ + public function innerJoin($join) + { + return $this->parseQueryPart('from', 'INNER JOIN ' . $join, true); + } + /** + * leftJoin + * appends a LEFT JOIN to the FROM part of the query + * + * @param string $join Query LEFT JOIN + * @return Doctrine_Query + */ + public function leftJoin($join) + { + return $this->parseQueryPart('from', 'LEFT JOIN ' . $join, true); + } + /** + * groupBy + * sets the GROUP BY part of the query + * + * @param string $groupby Query GROUP BY part + * @return Doctrine_Query + */ + public function groupBy($groupby) + { + return $this->parseQueryPart('groupby', $groupby); + } + /** + * where + * sets the WHERE part of the query + * + * @param string $join Query WHERE part + * @param mixed $params an array of parameters or a simple scalar + * @return Doctrine_Query + */ + public function where($where, $params = array()) + { + $this->_params['where'] = array(); + if (is_array($params)) { + $this->_params['where'] = $params; + } else { + $this->_params['where'][] = $params; + } + + return $this->parseQueryPart('where', $where); + } + /** + * having + * sets the HAVING part of the query + * + * @param string $having Query HAVING part + * @param mixed $params an array of parameters or a simple scalar + * @return Doctrine_Query + */ + public function having($having, $params = array()) + { + $this->_params['having'] = array(); + if (is_array($params)) { + $this->_params['having'] = $params; + } else { + $this->_params['having'][] = $params; + } + + return $this->parseQueryPart('having', $having); + } + /** + * orderBy + * sets the ORDER BY part of the query + * + * @param string $orderby Query ORDER BY part + * @return Doctrine_Query + */ + public function orderBy($orderby) + { + return $this->parseQueryPart('orderby', $orderby); + } + /** + * limit + * sets the Query query limit + * + * @param integer $limit limit to be used for limiting the query results + * @return Doctrine_Query + */ + public function limit($limit) + { + return $this->parseQueryPart('limit', $limit); + } + /** + * offset + * sets the Query query offset + * + * @param integer $offset offset to be used for paginating the query + * @return Doctrine_Query + */ + public function offset($offset) + { + return $this->parseQueryPart('offset', $offset); + } + + /** + * parseQueryPart + * parses given DQL query part + * + * @param string $queryPartName the name of the query part + * @param string $queryPart query part to be parsed + * @return Doctrine_Query this object + */ + public function parseQueryPart($queryPartName, $queryPart) + { + $this->parts[$queryPartName][] = $queryPart; + + return $this; + } +} \ No newline at end of file diff --git a/lib/Doctrine/Resource/Record.php b/lib/Doctrine/Resource/Record.php new file mode 100644 index 000000000..41d7b5c09 --- /dev/null +++ b/lib/Doctrine/Resource/Record.php @@ -0,0 +1,65 @@ +data[$get])) { + $this->data[$get] = null; + } + + return $this->data[$get]; + } + + public function set($set, $value) + { + $this->data[$set] = $value; + + $this->changes[$set] = $value; + } + + public function count() + { + return count($this->data); + } + + public function getIterator() + { + $data = $this->data; + + return new ArrayIterator($data); + } + + public function save() + { + $request = array(); + $request['format'] = $this->config['format']; + $request['type'] = 'save'; + $request['model'] = $this->model; + $request['data'] = $this->data; + $request['changes'] = $this->changes; + + $response = Doctrine_Resource::request($this->config['url'], $request); + + $array = Doctrine_Parser::load($response, $request['format']); + } + + public function toArray() + { + $array = array(); + + foreach ($this->data as $key => $value) { + if ($value instanceof Doctrine_Resource_Collection) { + $array[$key] = $value->toArray(); + } else { + $array[$key] = $value; + } + } + + return $array; + } +} \ No newline at end of file diff --git a/lib/Doctrine/Resource/Server.php b/lib/Doctrine/Resource/Server.php index f7fec564b..2e73f8b80 100644 --- a/lib/Doctrine/Resource/Server.php +++ b/lib/Doctrine/Resource/Server.php @@ -1,40 +1,58 @@ config = array_merge($config, $this->config); + } + public function execute($request) { - if (isset($request['dql'])) { - $query = new Doctrine_Query(); - $result = $query->query($request['dql']); - } else { - $result = $this->buildDql($request['parts']); - } - - $data = array(); - foreach ($result as $recordKey => $record) { - $array = $record->toArray(); - - $recordKey = get_class($record). '_' .($recordKey + 1); - - foreach ($array as $valueKey => $value) { - $data[get_class($record)][$recordKey][$valueKey] = $value; - } + if (!isset($request['type'])) { + throw new Doctrine_Resource_Exception('You must specify a request type: query or save'); } $format = isset($request['format']) ? $request['format']:'xml'; - return Doctrine_Parser::dump($data, $format); + if ($request['type'] == 'query') { + if (isset($request['dql']) && $request['dql']) { + $dql = $request['dql']; + $params = isset($request['params']) ? $request['params']:array(); + + $conn = Doctrine_Manager::connection(); + $result = $conn->query($dql, $params, Doctrine::FETCH_ARRAY); + } else { + throw new Doctrine_Resource_Exception('You must specify a dql query'); + } + } else if ($request['type'] == 'save') { + $table = Doctrine_Manager::getInstance()->getTable($request['model']); + $pks = (array) $table->getIdentifier(); + $pks = array_flip($pks); + + foreach (array_keys($pks) as $key) { + $pks[$key] = $request['data'][$key]; + } + + $record = $table->find($pks); + + $changes = $request['changes']; + + foreach ($changes as $key => $value) { + $record->$key = $value; + } + + $record->save(); + + $result = array('success' => true); + } + + return Doctrine_Parser::dump($result, $format); } - public function buildDql($parts) + public function run($request) { - - } - - public function run() - { - $request = $_REQUEST; - echo $this->execute($request); } } \ No newline at end of file diff --git a/playground/models.php b/playground/models.php index 7abc98d35..78a7b6a4b 100644 --- a/playground/models.php +++ b/playground/models.php @@ -12,6 +12,7 @@ $tables = array('Entity', 'Group', 'User', 'Album', + 'Book', 'Song', 'Element', 'Error',