Skip to content

Commit

Permalink
Merge pull request #752 from jails/pr11
Browse files Browse the repository at this point in the history
Fix `data\source\Database::read()` hack.
  • Loading branch information
nateabele committed Dec 19, 2012
2 parents 16969a8 + 82f60be commit 832578a
Show file tree
Hide file tree
Showing 5 changed files with 164 additions and 13 deletions.
34 changes: 30 additions & 4 deletions data/model/Query.php
Expand Up @@ -98,7 +98,7 @@ class Query extends \lithium\core\Object {
protected $_alias = array();

/**
* Map the generated aliases to their corresponding relation path
* Map beetween generated aliases and corresponding relation paths
*
* @see lithium\data\model\Query::alias()
*
Expand All @@ -107,7 +107,16 @@ class Query extends \lithium\core\Object {
protected $_paths = array();

/**
* Map the generated aliases to their corresponding model
* Map beetween relation paths and their corresponding fieldname paths
*
* @see lithium\data\model\Query::alias()
*
* @var array
*/
protected $_relationNames = array();

/**
* Map beetween generated aliases and corresponding models.
*
* @see lithium\data\model\Query::alias()
*
Expand Down Expand Up @@ -720,23 +729,40 @@ public function alias($alias = true, $relpath = null) {
}

$this->_paths[$alias] = $relpath;
$fieldname = array();
foreach ($paths as $path) {
if (!$relation = $model::relations($path)) {
$model = null;
break;
}
$fieldname[] = $relation->fieldName();
$model = $relation->to();
}
$this->_models[$alias] = $model;
$this->_relationNames[$relpath] = join('.', $fieldname);
return $alias;
}

/**
* Return the relation paths mapped to their corredponding fieldname paths.
*
* @param object $source Instance of the data source (`lithium\data\Source`) to use for
* conversion.
* @return array Map between relation paths and their corresponding fieldname paths.
*/
public function relationNames(Source $source = null) {
if ($source) {
$this->applyStrategy($source);
}
return $this->_relationNames;
}

/**
* Return the generated aliases mapped to their relation path
*
* @param object $source Instance of the data source (`lithium\data\Source`) to use for
* conversion.
* @return array Map between alias and their corresponding dotted relation
* @return array Map between aliases and their corresponding dotted relation paths.
*/
public function paths(Source $source = null) {
if ($source) {
Expand All @@ -750,7 +776,7 @@ public function paths(Source $source = null) {
*
* @param object $source Instance of the data source (`lithium\data\Source`) to use for
* conversion.
* @return array Map between alias and their corresponding model
* @return array Map between aliases and their corresponding fully-namespaced model names.
*/
public function models(Source $source = null) {
if ($source) {
Expand Down
30 changes: 21 additions & 9 deletions data/source/Database.php
Expand Up @@ -465,18 +465,30 @@ public function read($query, array $options = array()) {
return $result;
case 'array':
$columns = $args['schema'] ?: $self->schema($query, $result);
$records = array();
if (is_array(reset($columns))) {
$columns = reset($columns);

if (!isset($columns['']) || !is_array($columns[''])) {
$columns = array('' => $columns);
}
while ($data = $result->next()) {
// @hack: Fix this to support relationships
if (count($columns) != count($data) && is_array(current($columns))) {
$columns = current($columns);

$relationNames = is_object($query) ? $query->relationNames($self) : array();
$i = 0;
$records = array();
foreach ($result as $data) {
$offset = 0;
$records[$i] = array();
foreach ($columns as $path => $cols) {
$len = count($cols);
$values = array_combine($cols, array_slice($data, $offset, $len));
if ($path) {
$records[$i][$relationNames[$path]] = $values;
} else {
$records[$i] += $values;
}
$offset += $len;
}
$records[] = array_combine($columns, $data);
$i++;
}
return $records;
return Set::expand($records);
case 'item':
return $self->item($query->model(), array(), compact('query', 'result') + array(
'class' => 'set'
Expand Down
21 changes: 21 additions & 0 deletions tests/cases/data/model/QueryTest.php
Expand Up @@ -633,6 +633,27 @@ public function testModels() {
$this->assertEqual($expected, $query->models($this->db));
}

public function testRelationNames() {
$model = 'lithium\tests\mocks\data\model\MockQueryPost';
$query = new Query(compact('model'));
$query->alias(null, 'MockQueryComment');

$expected = array(
'MockQueryComment' => 'mock_query_comments'
);
$this->assertEqual($expected, $query->relationNames($this->db));

$query->alias('Post');
$query->alias('Comment', 'MockQueryComment');
$query->alias('Post2', 'MockQueryComment.MockQueryPost');

$expected = array(
'MockQueryComment' => 'mock_query_comments',
'MockQueryComment.MockQueryPost' => 'mock_query_comments.mock_query_post'
);
$this->assertEqual($expected, $query->relationNames($this->db));
}

public function testExportWithJoinedStrategy() {
$query = new Query(array(
'alias' => 'MyAlias',
Expand Down
80 changes: 80 additions & 0 deletions tests/cases/data/source/DatabaseTest.php
Expand Up @@ -16,6 +16,7 @@
use lithium\tests\mocks\data\model\MockDatabaseComment;
use lithium\tests\mocks\data\model\MockDatabaseTagging;
use lithium\tests\mocks\data\model\MockDatabasePostRevision;
use lithium\tests\mocks\data\model\mock_database\MockResult;

class DatabaseTest extends \lithium\test\Unit {

Expand All @@ -42,6 +43,7 @@ public function setUp() {

public function tearDown() {
$this->db->logs = array();
$this->db->return = array();
}

public function testDefaultConfig() {
Expand Down Expand Up @@ -1498,6 +1500,84 @@ public function testCustomField() {
$this->assertEqual($expected, $this->db->sql);
$this->assertEqual($map, $query->map());
}

public function testReturnArrayOnReadWithString() {
$data = new MockResult(array('records' => array(
array ('id', 'int(11)', 'NO', 'PRI', null, 'auto_increment'),
array ('name', 'varchar(256)', 'YES', '', null, '')
)));
$this->db->return = array(
'schema' => array('field', 'type', 'null', 'key', 'default', 'extra'),
'_execute' => $data
);
$result = $this->db->read('DESCRIBE {table};', array('return' => 'array'));
$expected = array(
array(
'field' => 'id',
'type' => 'int(11)',
'null' => 'NO',
'key' => 'PRI',
'default' => null,
'extra' => 'auto_increment',
),
array(
'field' => 'name',
'type' => 'varchar(256)',
'null' => 'YES',
'key' => '',
'default' => null,
'extra' => '',
)
);
$this->assertEqual($expected, $result);
}

public function testReturnArrayOnReadWithQuery() {
$data = new MockResult(array('records' => array(array(
'1',
'2',
'Post title',
'2012-12-17 17:04:00',
'3',
'1',
'2',
'Very good post',
'2012-12-17 17:05:00',
'1',
'2',
'Post title',
'2012-12-17 17:04:00',
))));
$this->db->return = array(
'_execute' => $data
);
$query = new Query(array(
'type' => 'read',
'model' => $this->_model,
'with' => array('MockDatabaseComment.MockDatabasePost')
));
$result = $this->db->read($query, array('return' => 'array'));
$expected = array(array(
'id' => '1',
'author_id' => '2',
'title' => 'Post title',
'created' => '2012-12-17 17:04:00',
'mock_database_comments' => array(
'id' => '3',
'post_id' => '1',
'author_id' => '2',
'body' => 'Very good post',
'created' => '2012-12-17 17:05:00',
'mock_database_post' => array(
'id' => '1',
'author_id' => '2',
'title' => 'Post title',
'created' => '2012-12-17 17:04:00',
)
)
));
$this->assertEqual($expected, $result);
}
}

?>
12 changes: 12 additions & 0 deletions tests/mocks/data/model/MockDatabase.php
Expand Up @@ -41,6 +41,8 @@ class MockDatabase extends \lithium\data\source\Database {

public $log = false;

public $return = array();

protected $_quotes = array('{', '}');

public function __construct(array $config = array()) {
Expand Down Expand Up @@ -94,9 +96,19 @@ protected function _execute($sql) {
if ($this->log) {
$this->logs[] = $sql;
}
if (isset($this->return['_execute'])) {
return $this->return['_execute'];
}
return new MockResult();
}

public function schema($query, $resource = null, $context = null) {
if (isset($this->return['schema'])) {
return $this->return['schema'];
}
return parent::schema($query, $resource = null, $context = null);
}

protected function _insertId($query) {
$query = $query->export($this);
ksort($query);
Expand Down

0 comments on commit 832578a

Please sign in to comment.