Skip to content

Commit

Permalink
Merge pull request #675 from jails/pr46
Browse files Browse the repository at this point in the history
Close #673
  • Loading branch information
nateabele committed Nov 9, 2012
2 parents 96bb832 + 2cdaed1 commit dc210f6
Show file tree
Hide file tree
Showing 2 changed files with 115 additions and 95 deletions.
103 changes: 8 additions & 95 deletions data/collection/MultiKeyRecordSet.php
Expand Up @@ -8,7 +8,7 @@

namespace lithium\data\collection;

class MultiKeyRecordSet extends \lithium\data\Collection {
class MultiKeyRecordSet extends \lithium\data\collection\RecordSet {

/**
* An array containing each record's unique key. This allows, for example, lookups of records
Expand Down Expand Up @@ -57,8 +57,9 @@ protected function _init() {
* @return boolean Returns true if the record's ID is found in the set, otherwise false.
*/
public function offsetExists($offset) {
$offset = (!$offset || $offset === true) ? 0 : $offset;
$this->offsetGet($offset);
if (in_array($offset, $this->_index, true)) {
if (in_array($offset, $this->_index)) {
return true;
}
return false;
Expand All @@ -81,7 +82,8 @@ public function offsetExists($offset) {
* value of `$offset`, otheriwse returns `null`.
*/
public function offsetGet($offset) {
if ($offset !== null && in_array($offset, $this->_index, true)) {
$offset = (!$offset || $offset === true) ? 0 : $offset;
if (in_array($offset, $this->_index)) {
return $this->_data[array_search($offset, $this->_index)];
}
if ($this->closed()) {
Expand All @@ -108,6 +110,7 @@ public function offsetGet($offset) {
* @return mixed The value which was set.
*/
public function offsetUnset($offset) {
$offset = (!$offset || $offset === true) ? 0 : $offset;
$this->offsetGet($offset);
unset($this->_index[$index = array_search($offset, $this->_index)]);
prev($this->_data);
Expand Down Expand Up @@ -239,13 +242,14 @@ protected function _set($data = null, $offset = null, $options = array()) {
$key = $offset;
}

if (!$key) {
if ($key === array() || $key === null || is_bool($key)) {
$key = count($this->_data);
}

if (is_array($key)) {
$key = count($key) === 1 ? reset($key) : $key;
}

if (in_array($key, $this->_index)) {
$index = array_search($key, $this->_index);
$this->_data[$index] = $data;
Expand All @@ -255,97 +259,6 @@ protected function _set($data = null, $offset = null, $options = array()) {
$this->_index[] = $key;
return $data;
}

protected function _mapRecord($data) {
$options = array('exists' => true);
$relationships = array();
$primary = $this->_model;
$conn = $primary::connection();

if (!$this->_query) {
return $conn->item($primary, $data, $options + compact('relationships'));
}

$dataMap = array();
$relMap = $this->_query->relationships();
$main = null;

do {
$offset = 0;

foreach ($this->_columns as $name => $fields) {
$fieldCount = count($fields);
$record = array_combine($fields, array_slice($data, $offset, $fieldCount));
$offset += $fieldCount;

if ($name === 0) {
if ($main && $main != $record) {
$this->_result->prev();
break 2;
}
$main = $record;
continue;
}

if ($relMap[$name]['type'] != 'hasMany') {
$dataMap[$name] = $record;
continue;
}

if (array_filter($record)) {
$dataMap[$name][] = $record;
}
}
} while ($data = $this->_result->next());

foreach (array_filter(array_keys($this->_columns)) as $name) {
if (!array_key_exists($name, $dataMap)) {
$dataMap[$name] = array();
}
}

foreach ($dataMap as $name => $rel) {
$field = $relMap[$name]['fieldName'];
$relModel = $relMap[$name]['model'];

if ($relMap[$name]['type'] == 'hasMany') {
foreach ($rel as &$data) {
$data = $conn->item($relModel, $data, $options);
}
$opts = array('class' => 'set');
$relationships[$field] = $conn->item($relModel, $rel, $options + $opts);
continue;
}
$relationships[$field] = $conn->item($relModel, $rel, $options);
}
return $conn->item($primary, $main, $options + compact('relationships'));
}

protected function _columnMap() {
if ($this->_query && $map = $this->_query->map()) {
if (isset($map[$this->_query->alias()])) {
$map = array($map[$this->_query->alias()]) + $map;
unset($map[$this->_query->alias()]);
} else {
$map = array(array_shift($map)) + $map;
}
return $map;
}
if (!($model = $this->_model)) {
return array();
}
if (!is_object($this->_query) || !$this->_query->join()) {
$map = $model::connection()->schema($this->_query, $this->_result, $this);
return array_values($map);
}

$model = $this->_model;
$map = $model::connection()->schema($this->_query, $this->_result, $this);
$map = array($map[$this->_query->alias()]) + $map;
unset($map[$this->_query->alias()]);

return $map;
}
}

?>
107 changes: 107 additions & 0 deletions tests/cases/data/collection/MultiKeyRecordSetTest.php
Expand Up @@ -103,6 +103,42 @@ public function testOffsetExists() {
$this->assertTrue($this->_objectRecordSet->offsetExists(3));
$this->assertTrue($this->_objectRecordSet->offsetExists(4));
$this->assertTrue(isset($this->_objectRecordSet[3]));

$data = array(array(
'client_id' => 1,
'invoice_id' => 4,
'title' => 'Payment1'
), array(
'client_id' => 2,
'invoice_id' => 5,
'title' => 'Payment2'
), array(
'client_id' => 3,
'invoice_id' => 6,
'title' => 'Payment3'
));

$payments = new MockMultiKeyRecordSet(array('data' => $data, 'model' => $this->_model2));
$this->assertTrue(isset($payments[array('client_id' => 1,'invoice_id' => 4)]));
$this->assertTrue(isset($payments[array('invoice_id' => 4, 'client_id' => 1)]));
$this->assertFalse(isset($payments[0]));
$this->assertFalse(isset($payments[true]));
$this->assertFalse(isset($payments[false]));
$this->assertFalse(isset($payments[null]));
$this->assertFalse(isset($payments['string']));

$records = new MockMultiKeyRecordSet();
$records[0] = array('title' => 'Record0');
$records[1] = array('title' => 'Record1');
$this->assertTrue(isset($records[true]));
$this->assertTrue(isset($records[null]));
$this->assertTrue(isset($records[false]));
$this->assertTrue(isset($records[array()]));
$this->assertTrue(isset($records[0]));
$this->assertTrue(isset($records['0']));
$this->assertTrue(isset($records[1]));
$this->assertTrue(isset($records['1']));
$this->assertFalse(isset($records[2]));
}

public function testOffsetGet() {
Expand Down Expand Up @@ -278,6 +314,51 @@ public function testOffsetUnset() {
$result = $this->_objectRecordSet[4];
$this->assertEqual(4, $result->id);
$this->assertEqual('data4', $result->data);

$data = array(array(
'client_id' => 1,
'invoice_id' => 4,
'title' => 'Payment1'
), array(
'client_id' => 2,
'invoice_id' => 5,
'title' => 'Payment2'
), array(
'client_id' => 3,
'invoice_id' => 6,
'title' => 'Payment3'
));

$payments = new MockMultiKeyRecordSet(array('data' => $data, 'model' => $this->_model2));

$expected = array(array(
'client_id' => 2,
'invoice_id' => 5,
'title' => 'Payment2'
), array(
'client_id' => 3,
'invoice_id' => 6,
'title' => 'Payment3'
));

unset($payments[array('client_id' => 1,'invoice_id' => 4)]);
$this->assertEqual($expected, array_values($payments->data()));

$payments = new MockMultiKeyRecordSet(array('data' => $data, 'model' => $this->_model2));
unset($payments[array('invoice_id' => 4, 'client_id' => 1)]);
$this->assertEqual($expected, array_values($payments->data()));

unset($payments[true]);
$this->assertEqual($expected, array_values($payments->data()));

unset($payments[false]);
$this->assertEqual($expected, array_values($payments->data()));

unset($payments[null]);
$this->assertEqual($expected, array_values($payments->data()));

unset($payments['string']);
$this->assertEqual($expected, array_values($payments->data()));
}

public function testRewind() {
Expand Down Expand Up @@ -732,6 +813,32 @@ public function testRecordWithCombinedPk() {
$this->assertEqual($data[1], $payments[array('client_id' => 2, 'invoice_id' => 5)]->data());
}

public function testKeyCastingManagment() {
$payments = new MockMultiKeyRecordSet();
$payments[true] = array('title' => 'Payment1');
$payments[null] = array('title' => 'Payment2');
$payments[false] = array('title' => 'Payment3');
$payments[array()] = array('title' => 'Payment4');

$expected = array(
0 => array('title' => 'Payment1'),
1 => array('title' => 'Payment2'),
2 => array('title' => 'Payment3'),
3 => array('title' => 'Payment4')
);

$this->assertEqual($expected, $payments->data());

$expected = array('title' => 'Payment1 updated');
$payments[0] = $expected;
$this->assertEqual($expected, $payments[0]);

$expected = array('title' => 'Payment1 updated 2');
$payments['0'] = $expected;
$this->assertEqual($expected, $payments['0']);
$this->assertEqual($expected, $payments[0]);
}

public function testRecordWithCombinedPkAndLazyLoading() {

$records = array(
Expand Down

0 comments on commit dc210f6

Please sign in to comment.