public function testApplyReplationDeepInheretence() { //test has_one relation $newDQ = new DataQuery('DataQueryTest_E'); //apply a relation to a relation from an ancestor class $newDQ->applyRelation('TestA'); $this->assertTrue($newDQ->query()->isJoinedTo('DataQueryTest_C')); $this->assertContains('"DataQueryTest_A"."ID" = "DataQueryTest_C"."TestAID"', $newDQ->sql($params)); //test many_many relation //test many_many with separate inheritance $newDQ = new DataQuery('DataQueryTest_C'); $baseDBTable = DataObject::getSchema()->baseDataTable('DataQueryTest_C'); $newDQ->applyRelation('ManyTestAs'); //check we are "joined" to the DataObject's table (there is no distinction between FROM or JOIN clauses) $this->assertTrue($newDQ->query()->isJoinedTo($baseDBTable)); //check we are explicitly selecting "FROM" the DO's table $this->assertContains("FROM \"{$baseDBTable}\"", $newDQ->sql()); //test many_many with shared inheritance $newDQ = new DataQuery('DataQueryTest_E'); $baseDBTable = DataObject::getSchema()->baseDataTable('DataQueryTest_E'); //check we are "joined" to the DataObject's table (there is no distinction between FROM or JOIN clauses) $this->assertTrue($newDQ->query()->isJoinedTo($baseDBTable)); //check we are explicitly selecting "FROM" the DO's table $this->assertContains("FROM \"{$baseDBTable}\"", $newDQ->sql(), 'The FROM clause is missing from the query'); $newDQ->applyRelation('ManyTestGs'); //confirm we are still joined to the base table $this->assertTrue($newDQ->query()->isJoinedTo($baseDBTable)); //double check it is the "FROM" clause $this->assertContains("FROM \"{$baseDBTable}\"", $newDQ->sql(), 'The FROM clause has been removed from the query'); //another (potentially less crude check) for checking "FROM" clause $fromTables = $newDQ->query()->getFrom(); $this->assertEquals('"' . $baseDBTable . '"', $fromTables[$baseDBTable]); }
/** * Return an array of the actual items that this DataList contains at this stage. * This is when the query is actually executed. * * @return array */ public function toArray() { $query = $this->dataQuery->query(); $rows = $query->execute(); $results = array(); foreach ($rows as $row) { $results[] = $this->createDataObject($row); } return $results; }
/** * Loads all the stub fields that an initial lazy load didn't load fully. * * @param string $class Class to load the values from. Others are joined as required. * Not specifying a tableClass will load all lazy fields from all tables. * @return bool Flag if lazy loading succeeded */ protected function loadLazyFields($class = null) { if (!$this->isInDB() || !is_numeric($this->ID)) { return false; } if (!$class) { $loaded = array(); foreach ($this->record as $key => $value) { if (strlen($key) > 5 && substr($key, -5) == '_Lazy' && !array_key_exists($value, $loaded)) { $this->loadLazyFields($value); $loaded[$value] = $value; } } return false; } $dataQuery = new DataQuery($class); // Reset query parameter context to that of this DataObject if ($params = $this->getSourceQueryParams()) { foreach ($params as $key => $value) { $dataQuery->setQueryParam($key, $value); } } // Limit query to the current record, unless it has the Versioned extension, // in which case it requires special handling through augmentLoadLazyFields() $schema = static::getSchema(); $baseIDColumn = $schema->sqlColumnForField($this, 'ID'); $dataQuery->where([$baseIDColumn => $this->record['ID']])->limit(1); $columns = array(); // Add SQL for fields, both simple & multi-value // TODO: This is copy & pasted from buildSQL(), it could be moved into a method $databaseFields = $schema->databaseFields($class, false); foreach ($databaseFields as $k => $v) { if (!isset($this->record[$k]) || $this->record[$k] === null) { $columns[] = $k; } } if ($columns) { $query = $dataQuery->query(); $this->extend('augmentLoadLazyFields', $query, $dataQuery, $this); $this->extend('augmentSQL', $query, $dataQuery); $dataQuery->setQueriedColumns($columns); $newData = $dataQuery->execute()->record(); // Load the data into record if ($newData) { foreach ($newData as $k => $v) { if (in_array($k, $columns)) { $this->record[$k] = $v; $this->original[$k] = $v; unset($this->record[$k . '_Lazy']); } } // No data means that the query returned nothing; assign 'null' to all the requested fields } else { foreach ($columns as $k) { $this->record[$k] = null; $this->original[$k] = null; unset($this->record[$k . '_Lazy']); } } } return true; }