Zend Framework, zachciało mi się HQL’a
Zend Framework – framework, o którym ostatnio sporo pisałem. HQL język używany w Hibernate, będący połączeniem ciemności świata relacji i światłości obiektów. HQL było inspiracją dla JPQL , dzięki czemu stanie się standardem przemysłowym.
HQL jest fajny, bo można pisać na przykład tak:
from Movie m where m.media.user.name='Antek';zamiast dłubać w SQL:
select m.* from movie v join media m on m.mediaid=v.mediaid join user u on u.userid=m.userid where user.name='Antek';Niestety, Zend Framework nie posiada czegoś takiego i nie zanosi się na to. Ja, jednak klepnąłem świniaka, dzięki któremu mogę pisać podobnie. Zmodyfikowałem klasę: Zend_Db_Table ^ JakubiakDbTable. Nowy kod to:
protected function _fetch($where = null, $order = null,
$count = null, $offset = null) {
$select = $this->_db->select();
$select->from($this->_name, $this->_cols);
$where = (array) $where;
foreach ($where as $key => $val) {
if (is_int($key)) {
$select->where($val);
} else {
// drobna modyfikacja rodzica
$key = $this->refJoin($select,$key);
$select->where($key, $val);
}
}
// dalej tak jak u rodzica[...]
}
public function refJoin($select, $where) {
foreach($this->_referenceMap as $key => $ref) {
$regExp = "#^$key\.#";
if (preg_match($regExp,$where)) {
$refDao = new $ref['refTableClass'];
$on = "";
foreach($ref['columns'] as $i => $colName){
if($i>0) $on .= ' and ';
$on .= ' ';
$on .= $this->getTableName() . '.' . $colName . '=';
$on .= $refDao->getTableName() . '.' .$ref['refColumns'][$i] . ' ';
}
$select->join($refDao->getTableName(), $on,array());
$where = preg_replace($regExp,"",$where);
return $refDao->refJoin($select,$where);
}
}
return $this->getTableName().'.'.$where;
}
public function getTableName() {
return $this->_name;
}
Kod powyżej działa, ale jest zły. Nie używaj go. Ja mogę go używać tak:
$movieTable = new MovieTable();
$movies = $movieTable->fetchAll(array("media.user.name=?"=>$_REQUEST['username']));
Czyli, prawie, prawie jak HQL.
Categories: ORM, PHP, Zend Framework
Mała poprawka do funkcji refJoin:
private function refJoin(Zend_Db_Select $select, $where) {
$tableName = $this->getTableName();
foreach($this->_referenceMap as $key => $ref) {
$regExp = “#^($tableName\.)?$key\.#”;
if (preg_match($regExp,$where)) {
// dolaczamy tabelka
$refDao = new $ref['refTableClass'];
$on = “”;
foreach($ref['columns'] as $i => $colName){
if($i>0){
$on .= ‘ and ‘;
}
$on .= ‘ ‘.$tableName.’.’.$colName.’=’.$refDao->getTableName().’.’.$ref['refColumns'][$i].’ ‘;
}
$select->join($refDao->getTableName(), $on,array());
// podmieniamy zapytanie
$where = preg_replace($regExp,”.$refDao->getTableName().’.',$where);
return $refDao->refJoin($select,$where);
}
}
return $where;
}