示例#1
0
 /**
  * {@inheritdoc}
  */
 public function count($column = self::DEFAULT_COUNTING_FIELD)
 {
     if ($column == self::DEFAULT_COUNTING_FIELD && !empty($this->loader->getPrimaryKey())) {
         $column = 'DISTINCT(' . $this->loader->getPrimaryKey() . ')';
     }
     return parent::count($column);
 }
示例#2
0
 /**
  * {@inheritdoc}
  */
 public function configureSelector(RecordSelector $selector)
 {
     if (empty($this->loaders) && empty($this->joiners)) {
         //No need to create any column aliases
         return;
     }
     parent::configureSelector($selector);
 }
 /**
  * Execute query and every related query to compile records data in tree form - every relation
  * data will be included as sub key.
  *
  * Attention, Selector will cache compiled data tree and not query itself to keep data integrity
  * and to skip data compilation on second query.
  *
  * @return array
  */
 public function fetchData()
 {
     //Pagination!
     $this->applyPagination();
     //Generating statement
     $statement = $this->sqlStatement();
     if (!empty($this->cacheLifetime)) {
         $cacheKey = $this->cacheKey ?: md5(serialize([$statement, $this->getParameters()]));
         if (empty($this->cacheStore)) {
             $this->cacheStore = $this->orm->container()->get(CacheInterface::class)->store();
         }
         if ($this->cacheStore->has($cacheKey)) {
             $this->logger()->debug("Selector result were fetched from cache.");
             //We are going to store parsed result, not queries
             return $this->cacheStore->get($cacheKey);
         }
     }
     //We are bypassing run() method here to prevent query caching, we will prefer to cache
     //parsed data rather that database response
     $result = $this->database->query($statement, $this->getParameters());
     //In many cases (too many inloads, too complex queries) parsing can take significant amount
     //of time, so we better profile it
     $benchmark = $this->benchmark('parseResult', $statement);
     //Here we are feeding selected data to our primary loaded to parse it and and create
     //data tree for our records
     $this->loader->parseResult($result, $rowsCount);
     $this->benchmark($benchmark);
     //Memory freeing
     $result->close();
     //This must force loader to execute all post loaders (including ODM and etc)
     $this->loader->loadData();
     //Now we can request our primary loader for compiled data
     $data = $this->loader->getResult();
     //Memory free! Attention, it will not reset columns aliases but only make possible to run
     //query again
     $this->loader->clean();
     if (!empty($this->cacheLifetime) && !empty($cacheKey)) {
         //We are caching full records tree, not queries
         $this->cacheStore->set($cacheKey, $data, $this->cacheLifetime);
     }
     return $data;
 }
示例#4
0
 /**
  * {@inheritdoc}
  */
 public function createSelector()
 {
     if (empty($selector = parent::createSelector())) {
         return null;
     }
     if (empty($this->parent)) {
         //No need for where conditions
         return $selector;
     }
     //Mounting where conditions
     $this->mountConditions($selector);
     //Aggregated keys (example: all parent ids)
     if (empty($aggregatedKeys = $this->parent->aggregatedKeys($this->getReferenceKey()))) {
         //Nothing to postload, no parents
         return null;
     }
     //Adding condition
     $selector->where($this->getKey(RecordEntity::OUTER_KEY), 'IN', $aggregatedKeys);
     return $selector;
 }
 /**
  * {@inheritdoc}
  *
  * We must parse pivot data.
  */
 protected function fetchData(array $row)
 {
     $data = parent::fetchData($row);
     $data[ORM::PIVOT_DATA] = array_combine($this->pivotColumns, array_slice($row, $this->pivotOffset, count($this->pivotColumns)));
     return $data;
 }
示例#6
0
 /**
  * Parse single result row to generate data tree. Must pass parsing to every nested loader.
  *
  * @param array $row
  * @return bool
  */
 private function parseRow(array $row)
 {
     if (!$this->isLoadable()) {
         //Nothing to parse, we are no waiting for any data
         return;
     }
     //Fetching only required part of resulted row
     $data = $this->fetchData($row);
     if (empty($this->parent)) {
         if ($this->deduplicate($data)) {
             //Yes, this is reference, i'm using this method to build data tree using nested parsers
             $this->result[] =& $data;
             //Registering references to simplify tree compilation for post and inner loaders
             $this->collectReferences($data);
         }
         $this->parseNested($row);
         return;
     }
     if (!($referenceCriteria = $this->fetchCriteria($data))) {
         //Relation not loaded
         return;
     }
     if ($this->deduplicate($data)) {
         //Registering references to simplify tree compilation for post and inner loaders
         $this->collectReferences($data);
     }
     //Mounting parsed data into parent under defined container
     $this->parent->mount($this->container, $this->getReferenceKey(), $referenceCriteria, $data, static::MULTIPLE);
     $this->parseNested($row);
 }
示例#7
0
 /**
  * Create delete statement based on WHERE statement provided by Selector.
  *
  * @param QueryCompiler $compiler
  * @return string
  */
 protected function deleteStatement(QueryCompiler $compiler = null)
 {
     $compiler = !empty($compiler) ? $compiler : $this->compiler->reset();
     $this->loader->configureSelector($this, false);
     return $compiler->delete($this->loader->getTable() . ' AS ' . $this->loader->getAlias(), $this->whereTokens);
 }