/** * add a virtual field that counts occurring relations * @param $key */ public function countRel($key) { if (isset($this->fieldConf[$key])) { // one-to-one, one-to-many if ($this->fieldConf[$key]['relType'] == 'belongs-to-one') { if ($this->dbsType == 'sql') { $this->mapper->set('count_' . $key, 'count(' . $key . ')'); $this->grp_stack = !$this->grp_stack ? $key : $this->grp_stack . ',' . $key; } elseif ($this->dbsType == 'mongo') { $this->_mongo_addGroup(array('keys' => array($key => 1), 'reduce' => 'prev.count_' . $key . '++;', "initial" => array("count_" . $key => 0))); } else { trigger_error('Cannot add direct relational counter.'); } } elseif ($this->fieldConf[$key]['relType'] == 'has-many') { $relConf = $this->fieldConf[$key]['has-many']; if ($relConf['hasRel'] == 'has-many') { // many-to-many if ($this->dbsType == 'sql') { $mmTable = $this->mmTable($relConf, $key); $filter = array($mmTable . '.' . $relConf['relField'] . ' = ' . $this->table . '.' . $this->primary); $from = $mmTable; if (array_key_exists($key, $this->relFilter) && !empty($this->relFilter[$key][0])) { $options = array(); $from = $mmTable . ' ' . $this->_sql_left_join($key, $mmTable, $relConf['relPK'], $relConf['relTable']); $relFilter = $this->relFilter[$key]; $this->_sql_mergeRelCondition($relFilter, $relConf['relTable'], $filter, $options); } $filter = $this->queryParser->prepareFilter($filter, $this->dbsType, $this->db, $this->fieldConf); $crit = array_shift($filter); if (count($filter) > 0) { $this->preBinds += $filter; } $this->mapper->set('count_' . $key, '(select count(' . $mmTable . '.' . $relConf['relField'] . ') from ' . $from . ' where ' . $crit . ' group by ' . $mmTable . '.' . $relConf['relField'] . ')'); } else { // count rel $this->countFields[] = $key; } } elseif ($this->fieldConf[$key]['has-many']['hasRel'] == 'belongs-to-one') { // many-to-one if ($this->dbsType == 'sql') { $fConf = $relConf[0]::resolveConfiguration(); $fTable = $fConf['table']; $rKey = $relConf[1]; $crit = $fTable . '.' . $rKey . ' = ' . $this->table . '.' . $this->primary; $filter = $this->mergeWithRelFilter($key, array($crit)); $filter = $this->queryParser->prepareFilter($filter, $this->dbsType, $this->db, $this->fieldConf); $crit = array_shift($filter); if (count($filter) > 0) { $this->preBinds += $filter; } $this->mapper->set('count_' . $key, '(select count(' . $fTable . '.' . $fConf['primary'] . ') from ' . $fTable . ' where ' . $crit . ' group by ' . $fTable . '.' . $rKey . ')'); } else { // count rel $this->countFields[] = $key; } } } } }
/** * Count records that match criteria * @param null $filter * @param int $ttl * @return mixed */ public function count($filter = NULL, $ttl = 0) { $filter = $this->queryParser->prepareFilter($filter, $this->dbsType); return $this->mapper->count($filter, $ttl); }