Skip to content

Commit 695968e

Browse files
committed
fixed autopivot case: first draft
1 parent 594fed4 commit 695968e

File tree

6 files changed

+87
-26
lines changed

6 files changed

+87
-26
lines changed

src/AbstractTDBMObject.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -383,14 +383,14 @@ protected function setRelationships(string $pivotTableName, array $remoteBeans):
383383
*
384384
* @return \SplObjectStorage
385385
*/
386-
private function retrieveRelationshipsStorage(string $pivotTableName): \SplObjectStorage
386+
private function retrieveRelationshipsStorage(string $pivotTableName, ?string $from = null, ?string $where = null): \SplObjectStorage
387387
{
388388
$storage = $this->getRelationshipStorage($pivotTableName);
389389
if ($this->status === TDBMObjectStateEnum::STATE_DETACHED || $this->status === TDBMObjectStateEnum::STATE_NEW || (isset($this->loadedRelationships[$pivotTableName]) && $this->loadedRelationships[$pivotTableName])) {
390390
return $storage;
391391
}
392392

393-
$beans = $this->tdbmService->_getRelatedBeans($pivotTableName, $this);
393+
$beans = $this->tdbmService->_getRelatedBeans($pivotTableName, $this, $from, $where);
394394
$this->loadedRelationships[$pivotTableName] = true;
395395

396396
foreach ($beans as $bean) {
@@ -414,9 +414,9 @@ private function retrieveRelationshipsStorage(string $pivotTableName): \SplObjec
414414
*
415415
* @return AbstractTDBMObject[]
416416
*/
417-
public function _getRelationships(string $pivotTableName): array
417+
public function _getRelationships(string $pivotTableName, ?string $from = null, ?string $where = null): array
418418
{
419-
return $this->relationshipStorageToArray($this->retrieveRelationshipsStorage($pivotTableName));
419+
return $this->relationshipStorageToArray($this->retrieveRelationshipsStorage($pivotTableName, $from, $where));
420420
}
421421

422422
/**

src/TDBMService.php

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1436,21 +1436,28 @@ private function fromCache(string $key, callable $closure)
14361436
*
14371437
* @return AbstractTDBMObject[]|ResultIterator
14381438
*/
1439-
public function _getRelatedBeans(string $pivotTableName, AbstractTDBMObject $bean): ResultIterator
1439+
public function _getRelatedBeans(string $pivotTableName, AbstractTDBMObject $bean, ?string $from = null, ?string $where = null): ResultIterator
14401440
{
14411441
list($localFk, $remoteFk) = $this->getPivotTableForeignKeys($pivotTableName, $bean);
14421442
/* @var $localFk ForeignKeyConstraint */
14431443
/* @var $remoteFk ForeignKeyConstraint */
14441444
$remoteTable = $remoteFk->getForeignTableName();
14451445

14461446
$primaryKeys = $this->getPrimaryKeyValues($bean);
1447-
$columnNames = array_map(function ($name) use ($pivotTableName) {
1448-
return $pivotTableName.'.'.$name;
1449-
}, $localFk->getUnquotedLocalColumns());
14501447

1451-
$filter = SafeFunctions::arrayCombine($columnNames, $primaryKeys);
1448+
if ($from && $where) {
1449+
$where .= $primaryKeys[0];
14521450

1453-
return $this->findObjects($remoteTable, $filter);
1451+
return $this->findObjectsFromSql($remoteTable, $from, $where);
1452+
} else {
1453+
1454+
$columnNames = array_map(function ($name) use ($pivotTableName) {
1455+
return $pivotTableName.'.'.$name;
1456+
}, $localFk->getUnquotedLocalColumns());
1457+
1458+
$filter = SafeFunctions::arrayCombine($columnNames, $primaryKeys);
1459+
return $this->findObjects($remoteTable, $filter);
1460+
}
14541461
}
14551462

14561463
/**

src/Utils/BeanDescriptor.php

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -372,15 +372,17 @@ private function getPivotTableDescriptors(): array
372372
// There are exactly 2 FKs since this is a pivot table.
373373
$fks = array_values($table->getForeignKeys());
374374

375+
//todo auto pivot case?
375376
if ($fks[0]->getForeignTableName() === $this->table->getName()) {
376377
list($localFk, $remoteFk) = $fks;
377-
} elseif ($fks[1]->getForeignTableName() === $this->table->getName()) {
378+
$descs[] = new PivotTableMethodsDescriptor($table, $localFk, $remoteFk, $this->namingStrategy, $this->beanNamespace, $this->annotationParser);
379+
}
380+
if ($fks[1]->getForeignTableName() === $this->table->getName()) {
378381
list($remoteFk, $localFk) = $fks;
379-
} else {
380-
continue;
382+
$descs[] = new PivotTableMethodsDescriptor($table, $localFk, $remoteFk, $this->namingStrategy, $this->beanNamespace, $this->annotationParser);
381383
}
382384

383-
$descs[] = new PivotTableMethodsDescriptor($table, $localFk, $remoteFk, $this->namingStrategy, $this->beanNamespace, $this->annotationParser);
385+
384386
}
385387

386388
return $descs;

src/Utils/PivotTableMethodsDescriptor.php

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,7 @@ public function useAlternativeName(): void
8585
*/
8686
public function getName() : string
8787
{
88-
if (!$this->useAlternateName) {
89-
return 'get'.TDBMDaoGenerator::toCamelCase($this->remoteFk->getForeignTableName());
90-
} else {
91-
return 'get'.TDBMDaoGenerator::toCamelCase($this->remoteFk->getForeignTableName()).'By'.TDBMDaoGenerator::toCamelCase($this->pivotTable->getName());
92-
}
88+
return 'get'.$this->getPluralName();
9389
}
9490

9591
/**
@@ -109,11 +105,14 @@ public function getBeanClassName(): string
109105
*/
110106
private function getPluralName() : string
111107
{
112-
if (!$this->useAlternateName) {
113-
return TDBMDaoGenerator::toCamelCase($this->remoteFk->getForeignTableName());
108+
if($this->isAutoPivot()) {
109+
$name = $this->remoteFk->getForeignTableName().'By_'.$this->pivotTable->getName().'Via_'.implode('And_',$this->localFk->getUnquotedLocalColumns());
110+
} else if (!$this->useAlternateName) {
111+
$name = $this->remoteFk->getForeignTableName();
114112
} else {
115-
return TDBMDaoGenerator::toCamelCase($this->remoteFk->getForeignTableName()).'By'.TDBMDaoGenerator::toCamelCase($this->pivotTable->getName());
113+
$name = $this->remoteFk->getForeignTableName().'By_'.$this->pivotTable->getName();
116114
}
115+
return TDBMDaoGenerator::toCamelCase($name);
117116
}
118117

119118
/**
@@ -123,13 +122,39 @@ private function getPluralName() : string
123122
*/
124123
private function getSingularName() : string
125124
{
126-
if (!$this->useAlternateName) {
127-
return TDBMDaoGenerator::toCamelCase(TDBMDaoGenerator::toSingular($this->remoteFk->getForeignTableName()));
125+
if($this->isAutoPivot()) {
126+
$name = TDBMDaoGenerator::toSingular($this->remoteFk->getForeignTableName()).'By_'.$this->pivotTable->getName().'Via_'.implode('And_',$this->localFk->getUnquotedLocalColumns());
127+
} else if (!$this->useAlternateName) {
128+
$name = TDBMDaoGenerator::toSingular($this->remoteFk->getForeignTableName());
128129
} else {
129-
return TDBMDaoGenerator::toCamelCase(TDBMDaoGenerator::toSingular($this->remoteFk->getForeignTableName())).'By'.TDBMDaoGenerator::toCamelCase($this->pivotTable->getName());
130+
$name = TDBMDaoGenerator::toSingular($this->remoteFk->getForeignTableName()).'By_'.$this->pivotTable->getName();
130131
}
132+
return TDBMDaoGenerator::toCamelCase($name);
133+
}
134+
135+
private function isAutoPivot(): bool
136+
{
137+
return $this->localFk->getForeignTableName() === $this->remoteFk->getForeignTableName();
131138
}
132139

140+
141+
/**
142+
* return the list of couples tableName.columnName needed for the sql query
143+
*/
144+
private function getAutoPivotFrom(): string
145+
{
146+
$mainTable = $this->remoteFk->getForeignTableName();
147+
$pivotTable = $this->remoteFk->getLocalTableName();
148+
149+
return $mainTable.' JOIN '.$pivotTable.' pivot ON '.$mainTable.'.'.$this->remoteFk->getUnquotedForeignColumns()[0].' = pivot.'.$this->remoteFk->getUnquotedLocalColumns()[0];
150+
//.' JOIN '.$mainTable.' second ON pivot.'.$this->localFk->getUnquotedLocalColumns()[0].' = second.'.$this->localFk->getUnquotedForeignColumns()[0];
151+
152+
}
153+
private function getAutoPivotWhere(): string
154+
{
155+
return ' pivot.'.$this->localFk->getUnquotedLocalColumns()[0].' = ';
156+
157+
}
133158
/**
134159
* Returns the code of the method.
135160
*
@@ -148,7 +173,11 @@ public function getCode() : array
148173
$getter->setDocBlock(sprintf('Returns the list of %s associated to this bean via the %s pivot table.', $remoteBeanName, $this->pivotTable->getName()));
149174
$getter->getDocBlock()->setTag(new ReturnTag([ $fqcnRemoteBeanName.'[]' ]));
150175
$getter->setReturnType('array');
151-
$getter->setBody(sprintf('return $this->_getRelationships(%s);', var_export($this->remoteFk->getLocalTableName(), true)));
176+
if ($this->isAutoPivot()) {
177+
$getter->setBody(sprintf('return $this->_getRelationships(%s, %s, %s);', var_export($this->remoteFk->getLocalTableName(), true), var_export($this->getAutoPivotFrom(), true), var_export($this->getAutoPivotWhere(), true)));
178+
} else {
179+
$getter->setBody(sprintf('return $this->_getRelationships(%s);', var_export($this->remoteFk->getLocalTableName(), true)));
180+
}
152181

153182

154183
$adder = new MethodGenerator('add'.$singularName);

tests/TDBMAbstractServiceTest.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -689,6 +689,10 @@ private static function initSchema(Connection $connection): void
689689
'artist_id' => 1,
690690
'title' => 'Animals'
691691
]);
692+
self::insert($connection, 'artists_relations', [
693+
'parent_id' => 1,
694+
'child_id' => 2
695+
]);
692696

693697
$timeType = Type::getType(Type::TIME_IMMUTABLE);
694698

tests/TDBMDaoGeneratorTest.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1959,6 +1959,25 @@ public function testJsonCollection(): void
19591959
self::assertEquals('Roger Waters', $json['tracks'][0]['feat'][0]['name']);
19601960
}
19611961

1962+
public function testFloydHasNoParent(): void
1963+
{
1964+
$artists = new ArtistDao($this->tdbmService);
1965+
$pinkFloyd = $artists->getById(1);
1966+
$parents = $pinkFloyd->getArtistsByArtistsRelationsViaChildId();
1967+
1968+
$this->assertEquals([], $parents);
1969+
}
1970+
1971+
public function testFloydHasOneChild(): void
1972+
{
1973+
$artists = new ArtistDao($this->tdbmService);
1974+
$pinkFloyd = $artists->getById(1);
1975+
$children = $pinkFloyd->getArtistsByArtistsRelationsViaParentId();
1976+
1977+
$this->assertEquals(1, count($children));
1978+
$this->assertEquals(2, $children[0]->getId());
1979+
}
1980+
19621981
/**
19631982
* @depends testDaoGeneration
19641983
*/

0 commit comments

Comments
 (0)