Skip to content

Commit

Permalink
Adding composite key support to loadInto()
Browse files Browse the repository at this point in the history
  • Loading branch information
lorenzo committed Jun 28, 2015
1 parent 803ac99 commit 86700ed
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 3 deletions.
2 changes: 1 addition & 1 deletion src/Database/Dialect/TupleComparisonTranslatorTrait.php
Expand Up @@ -79,7 +79,7 @@ protected function _transformTupleComparison(TupleComparison $expression, $query

foreach ($value as $tuple) {
$surrogate->orWhere(function ($exp) use ($fields, $tuple) {
foreach ($tuple as $i => $value) {
foreach (array_values($tuple) as $i => $value) {
$exp->add([$fields[$i] => $value]);
}
return $exp;
Expand Down
18 changes: 16 additions & 2 deletions src/ORM/Table.php
Expand Up @@ -2202,7 +2202,16 @@ public function loadInto($objects, array $contain)
$query = $this
->find()
->where(function ($exp) use ($primaryKey, $keys) {
return $exp->in($this->aliasField($this->primaryKey()), $keys->toList());
if (is_array($primaryKey) && count($primaryKey) === 1) {
$primaryKey = current($primaryKey);
}

if (is_string($primaryKey)) {
return $exp->in($this->aliasField($primaryKey), $keys->toList());
}

$primaryKey = array_map([$this, 'aliasField'], $primaryKey);
return new \Cake\Database\Expression\TupleComparison($primaryKey, $keys->toList());
})
->contain($contain);

Expand All @@ -2216,8 +2225,13 @@ public function loadInto($objects, array $contain)
->toArray();

$contain = $query->contain();
$results = $query->indexBy($primaryKey)->toArray();
$primaryKey = (array)$primaryKey;
$results = $query
->indexBy(function ($e) use ($primaryKey) {
return implode(';', $e->extract($primaryKey));
})
->toArray();

$objects = $objects
->map(function ($object) use ($results, $contain, $properties, $primaryKey) {
$key = implode(';', $object->extract($primaryKey));
Expand Down
46 changes: 46 additions & 0 deletions tests/TestCase/ORM/CompositeKeysTest.php
Expand Up @@ -672,6 +672,52 @@ public function testFindThreadedCompositeKeys()
$this->assertEquals($expected, $formatter($items)->toArray());
}

/**
* Tets that loadInto() is capable of handling composite primary keys
*
* @return void
*/
public function testLoadInto()
{
$table = TableRegistry::get('SiteAuthors');
$tags = TableRegistry::get('SiteTags');
$table->hasMany('SiteArticles', [
'foreignKey' => ['author_id', 'site_id'],
]);

$author = $table->get([1, 1]);
$result = $table->loadInto($author, ['SiteArticles']);
$this->assertSame($author, $result);

$expected = $table->get([1, 1], ['contain' => ['SiteArticles']]);
$this->assertEquals($expected, $result);
}

/**
* Tets that loadInto() is capable of handling composite primary keys
* when loading into multiple entities
*
* @return void
*/
public function testLoadIntoMany()
{
$table = TableRegistry::get('SiteAuthors');
$tags = TableRegistry::get('SiteTags');
$table->hasMany('SiteArticles', [
'foreignKey' => ['author_id', 'site_id'],
]);

$authors = $table->find()->toList();
$result = $table->loadInto($authors, ['SiteArticles']);

foreach ($authors as $k => $v) {
$this->assertSame($result[$k], $v);
}

$expected = $table->find('all', ['contain' => ['SiteArticles']])->toList();
$this->assertEquals($expected, $result);
}

/**
* Helper method to skip tests when connection is SQLite.
*
Expand Down

0 comments on commit 86700ed

Please sign in to comment.