From: Chuck Hagenbuch Date: Sat, 10 Jan 2009 16:57:39 +0000 (-0500) Subject: basic horde_rdo functionality works on top of horde_db X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=bb52b6b7606fdf8d175d4eae645e7a848062f9b8;p=horde.git basic horde_rdo functionality works on top of horde_db --- diff --git a/framework/Rdo/lib/Horde/Rdo/List.php b/framework/Rdo/lib/Horde/Rdo/List.php index b8b56adfc..212878ee1 100644 --- a/framework/Rdo/lib/Horde/Rdo/List.php +++ b/framework/Rdo/lib/Horde/Rdo/List.php @@ -1,7 +1,7 @@ _sql, $this->_bindParams) = $mapper->adapter->dml->getQuery($query); + list($this->_sql, $this->_bindParams) = $query->getQuery(); } elseif (is_string($query)) { // Straight SQL query, empty bind parameters array. $this->_sql = $query; diff --git a/framework/Rdo/lib/Horde/Rdo/Mapper.php b/framework/Rdo/lib/Horde/Rdo/Mapper.php index 9ad1208f7..e386c2e16 100644 --- a/framework/Rdo/lib/Horde/Rdo/Mapper.php +++ b/framework/Rdo/lib/Horde/Rdo/Mapper.php @@ -3,7 +3,7 @@ * Rdo Mapper base class. * * @category Horde - * @package Horde_Rdo + * @package Horde_Rdo */ /** @@ -20,10 +20,10 @@ * the main table of this entity. * * @category Horde - * @package Horde_Rdo + * @package Horde_Rdo */ -abstract class Horde_Rdo_Mapper implements Countable { - +abstract class Horde_Rdo_Mapper implements Countable +{ /** * If this is true and fields named created and updated are * present, Rdo will automatically set creation and last updated @@ -130,9 +130,11 @@ abstract class Horde_Rdo_Mapper implements Countable { return $this->table; case 'tableDefinition': + $this->tableDefinition = $this->adapter->table($this->table); + return $this->tableDefinition; case 'fields': - $this->fields = array_diff($this->model->listFields(), $this->_lazyFields); + $this->fields = array_diff($this->tableDefinition->getColumnNames(), $this->_lazyFields); return $this->fields; case 'lazyFields': @@ -219,8 +221,8 @@ abstract class Horde_Rdo_Mapper implements Countable { } } - if (isset($relationships[$m->model->table])) { - $o->$relationship = $m->map($relationships[$m->model->table]); + if (isset($relationships[$m->table])) { + $o->$relationship = $m->map($relationships[$m->table]); } } } @@ -283,8 +285,8 @@ abstract class Horde_Rdo_Mapper implements Countable { $query = Horde_Rdo_Query::create($query, $this); $query->setFields('COUNT(*)') ->clearSort(); - list($sql, $bindParams) = $this->adapter->dml->getCount($query); - return $this->adapter->selectOne($sql, $bindParams); + list($sql, $bindParams) = $query->getQuery(); + return $this->adapter->selectValue($sql, $bindParams); } /** @@ -300,8 +302,8 @@ abstract class Horde_Rdo_Mapper implements Countable { $query = Horde_Rdo_Query::create($query, $this); $query->setFields(1) ->clearSort(); - list($sql, $bindParams) = $this->adapter->dml->getQuery($query); - return (bool)$this->adapter->selectOne($sql, $bindParams); + list($sql, $bindParams) = $query->getQuery(); + return (bool)$this->adapter->selectValue($sql, $bindParams); } /** @@ -323,7 +325,7 @@ abstract class Horde_Rdo_Mapper implements Countable { } // Filter out any extra fields. - $fields = array_intersect_key($fields, $this->model->getFields()); + $fields = array_intersect_key($fields, $this->tableDefinition->getColumnNames()); if (!$fields) { throw new Horde_Rdo_Exception('create() requires at least one field value.'); @@ -342,7 +344,7 @@ abstract class Horde_Rdo_Mapper implements Countable { $id = $this->adapter->insert($sql, $bindParams); - return $this->map(array_merge(array($this->model->key => $id), + return $this->map(array_merge(array($this->tableDefinition->getPrimaryKey() => $id), $fields)); } @@ -361,7 +363,7 @@ abstract class Horde_Rdo_Mapper implements Countable { public function update($object, $fields = null) { if ($object instanceof Horde_Rdo_Base) { - $key = $this->model->key; + $key = $this->tableDefinition->getPrimaryKey(); $id = $object->$key; $fields = iterator_to_array($object); @@ -380,7 +382,7 @@ abstract class Horde_Rdo_Mapper implements Countable { } // Filter out any extra fields. - $fields = array_intersect_key($fields, $this->model->getFields()); + $fields = array_intersect_key($fields, $this->tableDefinition->getColumnNames()); if (!$fields) { // Nothing to change. @@ -393,7 +395,7 @@ abstract class Horde_Rdo_Mapper implements Countable { $sql .= ' ' . $this->adapter->quoteColumnName($field) . ' = ?,'; $bindParams[] = $value; } - $sql = substr($sql, 0, -1) . ' WHERE ' . $this->model->key . ' = ?'; + $sql = substr($sql, 0, -1) . ' WHERE ' . $this->tableDefinition->getPrimaryKey() . ' = ?'; $bindParams[] = $id; return $this->adapter->update($sql, $bindParams); @@ -411,13 +413,13 @@ abstract class Horde_Rdo_Mapper implements Countable { public function delete($object) { if ($object instanceof Horde_Rdo_Base) { - $key = $this->model->key; + $key = $this->tableDefinition->getPrimaryKey(); $id = $object->$key; $query = array($key => $id); } elseif ($object instanceof Horde_Rdo_Query) { $query = $object; } else { - $key = $this->model->key; + $key = $this->tableDefinition->getPrimaryKey(); $query = array($key => $object); } @@ -467,7 +469,7 @@ abstract class Horde_Rdo_Mapper implements Countable { if (is_numeric(key($arg))) { // Numerically indexed arrays are assumed to be an array of // primary keys. - $key = $this->model->key; + $key = $this->tableDefinition->getPrimaryKey(); $query = new Horde_Rdo_Query(); $query->combineWith('OR'); foreach ($argv[0] as $id) { @@ -505,7 +507,7 @@ abstract class Horde_Rdo_Mapper implements Countable { if (is_null($arg)) { $query = null; } elseif (is_scalar($arg)) { - $query = array($this->model->key => $arg); + $query = array($this->tableDefinition->getPrimaryKey() => $arg); } else { $query = $arg; } diff --git a/framework/Rdo/lib/Horde/Rdo/Query.php b/framework/Rdo/lib/Horde/Rdo/Query.php index 5ed2353b9..558778c1b 100644 --- a/framework/Rdo/lib/Horde/Rdo/Query.php +++ b/framework/Rdo/lib/Horde/Rdo/Query.php @@ -3,15 +3,15 @@ * Represent a single query or a tree of many query elements uniformly to clients. * * @category Horde - * @package Horde_Rdo + * @package Horde_Rdo */ /** * @category Horde - * @package Horde_Rdo + * @package Horde_Rdo */ -class Horde_Rdo_Query { - +class Horde_Rdo_Query +{ /** * @var Horde_Rdo_Mapper */ @@ -77,7 +77,7 @@ class Horde_Rdo_Query { $q = new Horde_Rdo_Query($mapper); if (is_scalar($query)) { - $q->addTest($mapper->model->key, '=', $query); + $q->addTest($mapper->tableDefinition->getPrimaryKey(), '=', $query); } elseif ($query) { $q->combineWith('AND'); foreach ($query as $key => $value) { @@ -110,7 +110,7 @@ class Horde_Rdo_Query { $this->mapper = $mapper; // Fetch all non-lazy-loaded fields for the mapper. - $this->setFields($mapper->fields, $mapper->model->table . '.'); + $this->setFields($mapper->fields, $mapper->table . '.'); if (!is_null($mapper)) { // Add all non-lazy relationships. @@ -125,7 +125,7 @@ class Horde_Rdo_Query { } // Add the fields for this relationship to the query. - $this->addFields($m->fields, $m->model->table . '.@'); + $this->addFields($m->fields, $m->table . '.@'); switch ($rel['type']) { case Horde_Rdo::ONE_TO_ONE: @@ -133,7 +133,7 @@ class Horde_Rdo_Query { if (isset($rel['query'])) { $query = $this->_fillJoinPlaceholders($m, $mapper, $rel['query']); } else { - $query = array($mapper->model->table . '.' . $rel['foreignKey'] => new Horde_Rdo_Query_Literal($m->model->table . '.' . $m->model->key)); + $query = array($mapper->table . '.' . $rel['foreignKey'] => new Horde_Rdo_Query_Literal($m->table . '.' . $m->tableDefinition->getPrimaryKey())); } $this->addRelationship($relationship, array('mapper' => $m, 'type' => $rel['type'], @@ -203,7 +203,7 @@ class Horde_Rdo_Query { throw new InvalidArgumentException('Relationships must contain a Horde_Rdo_Mapper object.'); } if (!isset($args['table'])) { - $args['table'] = $args['mapper']->model->table; + $args['table'] = $args['mapper']->table; } if (!isset($args['type'])) { $args['type'] = Horde_Rdo::MANY_TO_MANY; @@ -277,6 +277,138 @@ class Horde_Rdo_Query { } /** + * Query generator. + * + * @return array A two-element array of the SQL query and an array + * of bind parameters. + */ + public function getQuery() + { + $bindParams = array(); + $sql = ''; + + $this->_select($sql, $bindParams); + $this->_from($sql, $bindParams); + $this->_join($sql, $bindParams); + $this->_where($sql, $bindParams); + $this->_orderBy($sql, $bindParams); + $this->_limit($sql, $bindParams); + + return array($sql, $bindParams); + } + + /** + */ + protected function _select(&$sql, &$bindParams) + { + $fields = array(); + foreach ($this->fields as $field) { + $parts = explode('.@', $field, 2); + if (count($parts) == 1) { + $fields[] = $field; + } else { + $fields[] = str_replace('.@', '.', $field) . ' AS ' . $this->mapper->adapter->quoteColumnName($parts[0] . '@' . $parts[1]); + } + } + + $sql = 'SELECT ' . implode(', ', $fields); + } + + /** + */ + protected function _from(&$sql, &$bindParams) + { + $sql .= ' FROM ' . $this->mapper->table; + } + + /** + */ + protected function _join(&$sql, &$bindParams) + { + foreach ($this->relationships as $relationship) { + $relsql = array(); + foreach ($relationship['query'] as $key => $value) { + if ($value instanceof Horde_Rdo_Query_Literal) { + $relsql[] = $key . ' = ' . (string)$value; + } else { + $relsql[] = $key . ' = ?'; + $bindParams[] = $value; + } + } + + $sql .= ' ' . $relationship['join_type'] . ' ' . $relationship['table'] . ' ON ' . implode(' AND ', $relsql); + } + } + + /** + */ + protected function _where(&$sql, &$bindParams) + { + $clauses = array(); + foreach ($this->tests as $test) { + if (strpos($test['field'], '@') !== false) { + list($rel, $field) = explode('@', $test['field']); + if (!isset($this->relationships[$rel])) { + continue; + } + $clause = $this->relationships[$rel]['table'] . '.' . $field . ' ' . $test['test']; + } else { + $clause = $this->mapper->table . '.' . $this->mapper->adapter->quoteColumnName($test['field']) . ' ' . $test['test']; + } + + if ($test['value'] instanceof Horde_Rdo_Query_Literal) { + $clauses[] = $clause . ' ' . (string)$test['value']; + } else { + if ($test['test'] == 'IN' && is_array($test['value'])) { + $clauses[] = $clause . '(?' . str_repeat(',?', count($test['value']) - 1) . ')'; + $bindParams = array_merge($bindParams, array_values($test['value'])); + } else { + $clauses[] = $clause . ' ?'; + $bindParams[] = $test['value']; + } + } + } + + if ($clauses) { + $sql .= ' WHERE ' . implode(' ' . $this->conjunction . ' ', $clauses); + } + } + + /** + */ + protected function _orderBy(&$sql, &$bindParams) + { + if ($this->sortby) { + $sql .= ' ORDER BY'; + foreach ($this->sortby as $sort) { + if (strpos($sort, '@') !== false) { + /* @TODO parse these placeholders out, or drop them */ + list($field, $direction) = $sort; + list($rel, $field) = explode('@', $field); + if (!isset($this->relationships[$rel])) { + continue; + } + $sql .= ' ' . $this->relationships[$rel]['table'] . '.' . $field . ' ' . $direction . ','; + } else { + $sql .= " $sort,"; + } + } + + $sql = substr($sql, 0, -1); + } + } + + /** + */ + protected function _limit(&$sql, &$bindParams) + { + if ($this->limit) { + $opts = array('limit' => $this->limit, 'offset' => $this->limitOffset); + $sql = $this->mapper->adapter->addLimitOffset($sql, $opts); + } + } + + /** * Callback for array_walk to prefix all elements of an array with * a given prefix. */ @@ -301,9 +433,9 @@ class Horde_Rdo_Query { foreach (array_keys($query) as $field) { $value = $query[$field]; if (preg_match('/^@(.*)@$/', $value, $matches)) { - $q[$m1->model->table . '.' . $field] = new Horde_Rdo_Query_Literal($m2->model->table . '.' . $matches[1]); + $q[$m1->table . '.' . $field] = new Horde_Rdo_Query_Literal($m2->table . '.' . $matches[1]); } else { - $q[$m1->model->table . '.' . $field] = $value; + $q[$m1->table . '.' . $field] = $value; } } diff --git a/framework/Rdo/lib/Horde/Rdo/Query/Builder.php b/framework/Rdo/lib/Horde/Rdo/Query/Builder.php deleted file mode 100644 index 1623e06fd..000000000 --- a/framework/Rdo/lib/Horde/Rdo/Query/Builder.php +++ /dev/null @@ -1,172 +0,0 @@ -getQuery($query); - } - - /** - * Query generator. - * - * @param Horde_Rdo_Query $query The query object to turn into SQL. - * - * @return array A two-element array of the SQL query and an array - * of bind parameters. - */ - public function getQuery($query) - { - if ($query instanceof Horde_Rdo_Query_Literal) { - return array((string)$query, array()); - } - - $bindParams = array(); - $sql = ''; - - $this->_select($query, $sql, $bindParams); - $this->_from($query, $sql, $bindParams); - $this->_join($query, $sql, $bindParams); - $this->_where($query, $sql, $bindParams); - $this->_orderBy($query, $sql, $bindParams); - $this->_limit($query, $sql, $bindParams); - - return array($sql, $bindParams); - } - - /** - * Return the database-specific version of a test. - * - * @param string $test The test to "localize" - */ - public function getTest($test) - { - return $test; - } - - /** - */ - protected function _select($query, &$sql, &$bindParams) - { - $fields = array(); - foreach ($query->fields as $field) { - $parts = explode('.@', $field, 2); - if (count($parts) == 1) { - $fields[] = $field; - } else { - $fields[] = str_replace('.@', '.', $field) . ' AS ' . $query->mapper->adapter->quoteColumnName($parts[0] . '@' . $parts[1]); - } - } - - $sql = 'SELECT ' . implode(', ', $fields); - } - - /** - */ - protected function _from($query, &$sql, &$bindParams) - { - $sql .= ' FROM ' . $query->mapper->model->table; - } - - /** - */ - protected function _join($query, &$sql, &$bindParams) - { - foreach ($query->relationships as $relationship) { - $relsql = array(); - foreach ($relationship['query'] as $key => $value) { - if ($value instanceof Horde_Rdo_Query_Literal) { - $relsql[] = $key . ' = ' . (string)$value; - } else { - $relsql[] = $key . ' = ?'; - $bindParams[] = $value; - } - } - - $sql .= ' ' . $relationship['join_type'] . ' ' . $relationship['table'] . ' ON ' . implode(' AND ', $relsql); - } - } - - /** - */ - protected function _where($query, &$sql, &$bindParams) - { - $clauses = array(); - foreach ($query->tests as $test) { - if (strpos($test['field'], '@') !== false) { - list($rel, $field) = explode('@', $test['field']); - if (!isset($query->relationships[$rel])) { - continue; - } - $clause = $query->relationships[$rel]['table'] . '.' . $field . ' ' . $this->getTest($test['test']); - } else { - $clause = $query->mapper->model->table . '.' . $query->mapper->adapter->quoteColumnName($test['field']) . ' ' . $this->getTest($test['test']); - } - - if ($test['value'] instanceof Horde_Rdo_Query_Literal) { - $clauses[] = $clause . ' ' . (string)$test['value']; - } else { - if ($test['test'] == 'IN' && is_array($test['value'])) { - $clauses[] = $clause . '(?' . str_repeat(',?', count($test['value']) - 1) . ')'; - $bindParams = array_merge($bindParams, array_values($test['value'])); - } else { - $clauses[] = $clause . ' ?'; - $bindParams[] = $test['value']; - } - } - } - - if ($clauses) { - $sql .= ' WHERE ' . implode(' ' . $query->conjunction . ' ', $clauses); - } - } - - /** - */ - protected function _orderBy($query, &$sql, &$bindParams) - { - if ($query->sortby) { - $sql .= ' ORDER BY'; - foreach ($query->sortby as $sort) { - if (strpos($sort, '@') !== false) { - /*@TODO parse these placeholders out, or drop them*/ - list($field, $direction) = $sort; - list($rel, $field) = explode('@', $field); - if (!isset($query->relationships[$rel])) { - continue; - } - $sql .= ' ' . $query->relationships[$rel]['table'] . '.' . $field . ' ' . $direction . ','; - } else { - $sql .= " $sort,"; - } - } - - $sql = substr($sql, 0, -1); - } - } - - /** - */ - protected function _limit($query, &$sql, &$bindParams) - { - if ($query->limit) { - $sql .= ' LIMIT ' . $query->limit; - if (!is_null($query->limitOffset)) { - $sql .= ' OFFSET ' . $query->limitOffset; - } - } - } - -} diff --git a/framework/Rdo/lib/Horde/Rdo/Query/Literal.php b/framework/Rdo/lib/Horde/Rdo/Query/Literal.php index 1703e7742..035a4f833 100644 --- a/framework/Rdo/lib/Horde/Rdo/Query/Literal.php +++ b/framework/Rdo/lib/Horde/Rdo/Query/Literal.php @@ -1,7 +1,7 @@ mapper) { - return $this; + if ($mapper !== $this->mapper) { + $this->mapper = $mapper; } - - $this->mapper = $mapper; } } diff --git a/framework/Rdo/package.xml b/framework/Rdo/package.xml index 5ca5fa398..0c77330a4 100644 --- a/framework/Rdo/package.xml +++ b/framework/Rdo/package.xml @@ -33,7 +33,6 @@ http://pear.php.net/dtd/package-2.0.xsd"> - @@ -59,7 +58,6 @@ http://pear.php.net/dtd/package-2.0.xsd"> -