Beispiel #1
0
 /**
  * If the $method is one of the MySQL.
  * 
  * @see KObject::__call()
  */
 public function __call($method, $arguments)
 {
     if (isset($arguments[0]) && $this->_parent_query->getRepository()->getDescription()->getProperty($method)) {
         $condition = isset($arguments[1]) ? $arguments[1] : 'AND';
         $this->where($method, '=', $arguments[0], $condition);
         return $this;
     }
     return parent::__call($method, $arguments);
 }
Beispiel #2
0
 /**
  * Summerize a story query.
  *
  * @param AnDomainQuery $query  Query object
  * @param array         $config Summerization configuration
  * 
  * @return AnDomainEntityset
  */
 protected function _buildAggregateQuery($query, $config)
 {
     $cases = array();
     $config = KConfig::unbox($config);
     $config[] = array('WHEN @col(name) LIKE "avatar_edit"  THEN IF(@col(subject.id) = @col(target.id), "", @col(id))', 'WHEN @col(name) LIKE "actor_follow" THEN @col(subject.id)');
     foreach ($config as $component => $keys) {
         foreach ($keys as $name => $key) {
             if (!is_numeric($name)) {
                 $names = explode(',', $name);
                 $keys = explode(',', $key);
                 foreach ($keys as $i => $key) {
                     $keys[$i] = '@col(' . $key . '.id)';
                 }
                 foreach ($names as $name) {
                     $cases[] = 'WHEN CONCAT(@col(name),@col(component)) LIKE \'' . $name . $component . '\' THEN CONCAT(' . implode(',', $keys) . ')';
                 }
             } else {
                 $cases[] = $key;
             }
         }
     }
     $cases = array_unique($cases);
     $keys = array();
     //always group by date, name and component
     $date = '@col(name),@col(component),DATE(@col(creationTime))';
     $keys[] = $date;
     if (!empty($cases)) {
         $case = 'CASE TRUE ';
         $case .= implode(' ', $cases) . ' ';
         $case .= 'ELSE CONCAT(@col(target.id),@col(subject.id),@col(object.id)) ';
         $case .= 'END';
         $keys[] = $case;
     } else {
         $keys[] = '@col(target.id),@col(subject.id),@col(object.id)';
     }
     $keys = implode(',', $keys);
     $comment_if = "IF(@col(comment.id) IS NOT NULL AND @col(object.id) IS NOT NULL , CONCAT_WS(',',{$date}, @col(object.id)), CONCAT_WS(',',{$keys}))";
     //don't group if a story has a body or it has directly been commented on
     $bundle = "IF (@col(body) <> '' AND @col(body) IS NOT NULL,@col(id),{$comment_if}) AS bundle_key";
     $query->select($bundle);
     $query->select('GROUP_CONCAT(DISTINCT @col(id)) AS ids');
     $query->select('GROUP_CONCAT(DISTINCT @col(owner.id))  AS  owner_ids');
     $query->select('GROUP_CONCAT(DISTINCT @col(target.id)) AS   target_ids');
     $query->select('GROUP_CONCAT(DISTINCT @col(comment.id)) AS  comment_ids');
     $query->select('GROUP_CONCAT(DISTINCT @col(object.id)) AS  object_ids');
     $query->select('GROUP_CONCAT(DISTINCT @col(subject.id)) AS subject_ids');
     $query->select(array('id' => 'MAX(@col(id))'));
     $query->select(array('creationTime' => 'MAX(@col(creationTime))'));
     $query->select(array('updateTime' => 'MAX(@col(updateTime))'));
     $viewer = get_viewer();
     $query->group('bundle_key');
     $query->order = array();
     $query->order('modified_on', 'DESC');
 }
Beispiel #3
0
 /**
  * Delete record identified by $keys in the $resources
  *
  * @param  AnDomainRepositoryAbstract $repository
  * @param  array $keys
  * @return boolean
  */
 public function delete($repository, $keys)
 {
     $context = $this->getCommandContext();
     $context->repository = $repository;
     $context->keys = $keys;
     $context->query = AnDomainQuery::getInstance($repository, $keys)->delete();
     if ($this->getCommandChain()->run('before.delete', $context) !== false) {
         $context->result = $this->execute($context->query);
         $this->getCommandChain()->run('after.delete', $context);
     }
     return $context->result;
 }
Beispiel #4
0
 /**
  * Adds a relationship to query.
  *
  * @param AnDomainQuery $query        Query Object
  * @param string        $relationship Relationship name
  */
 public static function addRelationship($query, $relationship)
 {
     $property = $query->getRepository()->getDescription()->getProperty($relationship);
     switch (true) {
         case $property->isManyToOne():
             return self::_parseManyToOne($query, $property);
         case $property->isManyToMany():
             return self::_parseManyToMany($query, $property);
         case $property->isOneToMany():
             return self::_parseOneToMany($query, $property);
     }
 }
Beispiel #5
0
 /**
  * Builds a query into a final query statement.
  * 
  * @param AnDomainQuery $query  Query object
  * @param string        $string A String object
  * 
  * @return string
  */
 public function parseMethods($query, $string)
 {
     //replaces any @col(\w+) pattern with the correct column name
     if (strpos($string, '@col(')) {
         $matches = array();
         if (preg_match_all('/@col\\((.*?)\\)/', $string, $matches)) {
             $description = $query->getRepository()->getDescription();
             $replaces = array();
             foreach ($matches[1] as $match) {
                 $result = AnDomainQueryHelper::parseColumn($query, $match);
                 if (empty($result['columns'])) {
                     $replaces[] = $match;
                 } else {
                     $replaces[] = (string) $result['columns'];
                 }
             }
             $string = str_replace($matches[0], $replaces, $string);
         }
     }
     if (strpos($string, '@quote(')) {
         $matches = array();
         $replaces = array();
         if (preg_match_all('/@quote\\((.*?)\\)/', $string, $matches)) {
             foreach ($matches[1] as $match) {
                 $replaces[] = $this->_store->quoteValue($match);
             }
             $string = str_replace($matches[0], $replaces, $string);
         }
     }
     if (strpos($string, '@instanceof(')) {
         $matches = array();
         $replaces = array();
         if (preg_match_all('/\\!?@instanceof\\((.*?)\\)/', $string, $matches)) {
             foreach ($matches[1] as $i => $match) {
                 $operand = '';
                 if ($matches[0][$i][0] == '!') {
                     $operand = 'NOT ';
                 }
                 $type_col = $query->getRepository()->getDescription()->getInheritanceColumn();
                 $classes = explode(',', $match);
                 $statements = array();
                 foreach ($classes as $class) {
                     $class = $this->_store->quoteValue($class);
                     $statements[] = $operand . "FIND_IN_SET({$class},{$type_col})";
                 }
                 if ($operand == 'NOT ') {
                     $operand = ' AND ';
                 } else {
                     $operand = ' OR ';
                 }
                 if (count($statements) == 1) {
                     $statements = implode($operand, $statements);
                 } else {
                     $statements = '(' . implode($operand, $statements) . ')';
                 }
                 $replaces[] = $statements;
             }
             $string = str_replace($matches[0], $replaces, $string);
         }
     }
     if (strpos($string, '@remove_from_set(')) {
         $matches = array();
         $replaces = array();
         if (preg_match_all('/@remove_from_set\\((.*?)\\)/', $string, $matches)) {
             foreach ($matches[1] as $i => $match) {
                 list($set, $item) = explode(',', $match);
                 $set = trim($set);
                 $item = trim($item);
                 $replaces[] = "TRIM(BOTH ',' FROM REPLACE(concat(',',{$set},','),CONCAT(',',{$item},','),','))";
             }
             $string = str_replace($matches[0], $replaces, $string);
         }
     }
     if (strpos($string, '@set_length(')) {
         $matches = array();
         $replaces = array();
         if (preg_match_all('/@set_length\\((.*?)\\)/', $string, $matches)) {
             foreach ($matches[1] as $i => $match) {
                 $replaces[] = "LENGTH({$match}) - LENGTH(REPLACE({$match}, ',', '')) + 1";
             }
             $string = str_replace($matches[0], $replaces, $string);
         }
     }
     return $string;
 }
Beispiel #6
0
 /**
  * Count Data.
  *
  * @param booelan $load If the flag is set to on. If the qurey is set, it will
  *                      perform a count query instead of loading all the objects
  *
  * @return int
  */
 public function count($load = true)
 {
     //if query is set, and the data is not loaded
     //lets use the query to get the count
     if (isset($this->_query) && !$this->isLoaded() && !$load) {
         $query = AnDomainQuery::getInstance($this->getRepository(), $this->_query);
         return $query->fetchValue('count(*)');
     } else {
         $this->_loadData();
         $result = parent::count();
     }
     return $result;
 }
Beispiel #7
0
 /**
  * Fetch an entity. The condition can be a query object, an associative array or an id
  * of an entity.
  *
  * @param mixed $condition The condition for fetching data
  * @param int   $mode      The mode of fetching data. Can be single entity, entity set, value, etc
  *
  * @return mixed
  */
 public function fetch($condition = null, $mode = AnDomain::FETCH_ENTITY)
 {
     $query = AnDomainQuery::getInstance($this, $condition);
     $context = $this->getCommandContext();
     $context->operation = AnDomain::OPERATION_FETCH;
     $context->query = $query;
     $context->mode = $mode;
     $query->fetch_mode = $mode;
     if ($mode & AnDomain::FETCH_ITEM) {
         $context->query->limit(1);
     }
     $disable_chain = $query->disable_chain;
     if ($disable_chain) {
         $this->getCommandChain()->disable();
     }
     if ($this->getCommandChain()->run('before.fetch', $context) !== false) {
         $result = $context->result ? $context['result'] : $this->_fetchResult($context->query, $mode);
         $context->result = $result;
         switch ($mode) {
             case AnDomain::FETCH_ENTITY:
                 $context->data = $result ? $this->_createEntity($result) : $result;
                 break;
             case AnDomain::FETCH_ENTITY_SET:
             case AnDomain::FETCH_ENTITY_LIST:
                 $list = array();
                 foreach ($result as $data) {
                     $list[] = $this->_createEntity($data);
                 }
                 if ($mode == AnDomain::FETCH_ENTITY_SET) {
                     $list = $this->getService($this->_entityset, array('repository' => $this, 'query' => $context->query, 'data' => $list));
                 }
                 $context->data = $list;
                 break;
             default:
                 $context->data = $result;
         }
         $this->getCommandChain()->run('after.fetch', $context);
     }
     if ($disable_chain) {
         $this->getCommandChain()->enable();
     }
     return KConfig::unbox($context->data);
 }
Beispiel #8
0
 /**
  * Validates and apply delete rules for an entity
  *
  * @param $entity
  */
 protected function _validateDelete($entity)
 {
     $relationships = $entity->getEntityDescription()->getRelationships();
     foreach ($relationships as $name => $relationship) {
         if ($relationship->isManyToOne() || $relationship->isManyToMany()) {
             continue;
         }
         if ($relationship->getDeleteRule() == AnDomain::DELETE_CASCADE || $relationship->getDeleteRule() == AnDomain::DELETE_DESTROY) {
             $property = $relationship->getName();
             $entities = $entity->getData($property);
             if (!$entities) {
                 continue;
             }
             //someone else is responsible for deleteing the relations
             //good for mass deletion. i.e. node and edges
             if ($relationship->getDeleteRule() == AnDomain::DELETE_IGNORE) {
                 continue;
             } else {
                 if ($relationship->getDeleteRule() == AnDomain::DELETE_DESTROY) {
                     if ($relationship->isOneToOne()) {
                         $query = AnDomainQuery::getInstance($relationship->getChildRepository(), $entities->getIdentityId());
                     } else {
                         $query = $entities->getQuery();
                     }
                     $relationship->getChildRepository()->destroy($query);
                     continue;
                 } else {
                     if ($relationship->isOneToOne()) {
                         $entities = array($entities);
                     }
                     foreach ($entities as $entity) {
                         //if the cascading fails for the related entities then
                         //nullify the property in the failed entity
                         if (!$entity->delete() && $entity->getObject()) {
                             $entity->set($relationship->getChildKey(), null);
                         }
                     }
                 }
             }
         } else {
             if ($relationship->getDeleteRule() == AnDomain::DELETE_DENY) {
                 //don't state change if there at least one entity left
                 $count = $entity->getData($relationship->getName())->limit(0, 0)->getTotal();
                 if ($count > 0) {
                     $entity->reset();
                     return false;
                 }
             } else {
                 if ($relationship->getDeleteRule() == AnDomain::DELETE_NULLIFY) {
                     //@TODO you should set the values to null directly rather
                     //then instantiating them
                     $entities = $entity->getData($relationship->getName())->fetchSet();
                     $property = $relationship->getChildKey();
                     foreach ($entities as $entity) {
                         $entity->set($property, null);
                     }
                 }
             }
         }
     }
     return true;
 }