public function testSelfReferentialCRUD()
{
R::nuke();
$buddies = R::dispense('buddy', 4);
$buddies[0]->name = 'A';
$buddies[1]->name = 'B';
$buddies[2]->name = 'C';
$buddies[3]->name = 'D';
$buddies[0]->sharedBuddyList = array($buddies[1], $buddies[2]);
$buddies[3]->sharedBuddyList = array($buddies[2]);
R::storeAll($buddies);
$buddies[0] = $buddies[0]->fresh();
asrt(count($buddies[0]->sharedBuddyList), 2);
//does this yield valid combinations - cross relations / self ref n-m
//need to symmetric....
$names = R::gatherLabels($buddies[0]->sharedBuddyList);
sort($names);
$names = implode(',', $names);
asrt($names, 'B,C');
unset($buddies[0]->sharedBuddy);
R::storeAll($buddies);
$buddies[0] = $buddies[0]->fresh();
asrt(count($buddies[0]->sharedBuddyList), 2);
$buddies[3] = $buddies[3]->fresh();
asrt(count($buddies[3]->sharedBuddyList), 1);
$names = R::gatherLabels($buddies[3]->sharedBuddyList);
sort($names);
$names = implode(',', $names);
asrt($names, 'C');
$buddies[2] = $buddies[2]->fresh();
asrt(count($buddies[2]->sharedBuddyList), 2);
$names = R::gatherLabels($buddies[2]->sharedBuddyList);
sort($names);
$names = implode(',', $names);
asrt($names, 'A,D');
$buddies[1] = $buddies[1]->fresh();
asrt(count($buddies[1]->sharedBuddyList), 1);
$names = R::gatherLabels($buddies[1]->sharedBuddyList);
sort($names);
$names = implode(',', $names);
asrt($names, 'A');
//Can we add one?
$buddies[1]->sharedBuddyList[] = R::dispense('buddy')->setAttr('name', 'E');
R::store($buddies[1]);
$buddies[0] = $buddies[0]->fresh();
asrt(count($buddies[0]->sharedBuddyList), 2);
$names = R::gatherLabels($buddies[0]->sharedBuddyList);
sort($names);
$names = implode(',', $names);
asrt($names, 'B,C');
$buddies[1] = $buddies[1]->fresh();
asrt(count($buddies[1]->sharedBuddyList), 2);
$names = R::gatherLabels($buddies[1]->sharedBuddyList);
sort($names);
$names = implode(',', $names);
asrt($names, 'A,E');
$all = R::find('buddy');
asrt(count($all), 5);
foreach ($buddies[1]->sharedBuddy as $buddy) {
if ($buddy->name === 'E') {
$buddyE = $buddy;
}
}
asrt(isset($buddyE), TRUE);
asrt($buddyE->name, 'E');
//can we update?
foreach ($buddies[0]->sharedBuddy as $buddy) {
if ($buddy->name === 'C') {
$buddy->name = 'C2';
}
}
R::store($buddies[0]);
$buddies[0] = $buddies[0]->fresh();
asrt(count($buddies[0]->sharedBuddyList), 2);
$names = R::gatherLabels($buddies[0]->sharedBuddyList);
sort($names);
$names = implode(',', $names);
asrt($names, 'B,C2');
$buddies[2] = $buddies[2]->fresh();
asrt(count($buddies[2]->sharedBuddyList), 2);
$names = R::gatherLabels($buddies[2]->sharedBuddyList);
sort($names);
$names = implode(',', $names);
asrt($names, 'A,D');
//can we delete?
foreach ($buddies[0]->sharedBuddyList as $id => $buddy) {
if ($buddy->name === 'B') {
unset($buddies[0]->sharedBuddyList[$id]);
}
}
R::store($buddies[0]);
$buddies[0] = $buddies[0]->fresh();
asrt(count($buddies[0]->sharedBuddyList), 1);
$names = R::gatherLabels($buddies[0]->sharedBuddyList);
sort($names);
$names = implode(',', $names);
asrt($names, 'C2');
$buddies[1] = $buddies[1]->fresh();
asrt(count($buddies[1]->sharedBuddyList), 1);
$names = R::gatherLabels($buddies[1]->sharedBuddyList);
sort($names);
$names = implode(',', $names);
asrt($names, 'E');
asrt(R::count('buddy'), 5);
asrt(R::count('buddyBuddy'), 3);
$buddies[3] = $buddies[3]->fresh();
asrt(count($buddies[3]->sharedBuddyList), 1);
$names = R::gatherLabels($buddies[3]->sharedBuddyList);
sort($names);
$names = implode(',', $names);
asrt($names, 'C2');
$buddies[2] = $buddies[2]->fresh();
asrt(count($buddies[2]->sharedBuddyList), 2);
$names = R::gatherLabels($buddies[2]->sharedBuddyList);
sort($names);
$names = implode(',', $names);
asrt($names, 'A,D');
$buddyE = $buddyE->fresh();
asrt(count($buddyE->sharedBuddyList), 1);
$names = R::gatherLabels($buddyE->sharedBuddyList);
sort($names);
$names = implode(',', $names);
asrt($names, 'B');
//can we access linked_by -- o dear mysql again! cant have alias in WHERE!
if ($this->currentlyActiveDriverID === 'mysql') {
$buddyE = $buddyE->fresh();
asrt(count($buddyE->with(' HAVING linked_by > 0 ')->sharedBuddyList), 1);
$buddyE = $buddyE->fresh();
asrt(count($buddyE->with(' HAVING linked_by < 0 ')->sharedBuddyList), 0);
}
//even postgres sucks. Only SQLite knows how to handle this.
//I dont give a fuck whether it's an SQL standard or not, it should just work.
if ($this->currentlyActiveDriverID === 'sqlite') {
$buddyE = $buddyE->fresh();
asrt(count($buddyE->withCondition(' linked_by > 0 ')->sharedBuddyList), 1);
$buddyE = $buddyE->fresh();
asrt(count($buddyE->withCondition(' linked_by < 0 ')->sharedBuddyList), 0);
}
$buddyE = $buddyE->fresh();
asrt(count($buddyE->withCondition(' buddy_buddy.buddy_id > 0 AND buddy_buddy.buddy2_id > 0 ')->sharedBuddyList), 1);
$buddyE = $buddyE->fresh();
asrt(count($buddyE->withCondition(' buddy_buddy.buddy_id < 0 AND buddy_buddy.buddy2_id < 0 ')->sharedBuddyList), 0);
}