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 = ClassInfo::baseDataClass('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 = ClassInfo::baseDataClass('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]); }
public function testApplyReplationDeepInheretence() { $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)); }
/** * 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 than an initial lazy load didn't load fully. * * @param tableClass Base table to load the values from. Others are joined as required. */ protected function loadLazyFields($tableClass = null) { // Smarter way to work out the tableClass? Should the functionality in toMap and getField be moved into here? if (!$tableClass) { $tableClass = $this->ClassName; } $dataQuery = new DataQuery($tableClass); // TableField sets the record ID to "new" on new row data, so don't try doing anything in that case if (!is_numeric($this->record['ID'])) { return false; } $dataQuery->where("\"{$tableClass}\".\"ID\" = {$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 = self::database_fields($tableClass); if ($databaseFields) { foreach ($databaseFields as $k => $v) { if (!isset($this->record[$k]) || $this->record[$k] === null) { $columns[] = $k; } } } if ($columns) { $query = $dataQuery->query(); // eh? $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']); } } } }
/** * Loads all the stub fields that an initial lazy load didn't load fully. * * @param tableClass Base table to load the values from. Others are joined as required. * Not specifying a tableClass will load all lazy fields from all tables. */ protected function loadLazyFields($tableClass = null) { if (!$tableClass) { $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; } $dataQuery = new DataQuery($tableClass); // Reset query parameter context to that of this DataObject if ($params = $this->getSourceQueryParams()) { foreach ($params as $key => $value) { $dataQuery->setQueryParam($key, $value); } } // TableField sets the record ID to "new" on new row data, so don't try doing anything in that case if (!is_numeric($this->record['ID'])) { return false; } // Limit query to the current record, unless it has the Versioned extension, // in which case it requires special handling through augmentLoadLazyFields() if (!$this->hasExtension('Versioned')) { $dataQuery->where("\"{$tableClass}\".\"ID\" = {$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 = self::database_fields($tableClass); if ($databaseFields) { 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']); } } } }