mirror of
https://github.com/Karaka-Management/phpOMS.git
synced 2026-01-11 17:58:41 +00:00
creating join
This commit is contained in:
parent
2e442acc3d
commit
9745efa7d5
|
|
@ -95,6 +95,14 @@ abstract class DataMapperAbstract
|
|||
*/
|
||||
protected array $where = [];
|
||||
|
||||
/**
|
||||
* Join conditions
|
||||
*
|
||||
* @var array
|
||||
* @since 1.0.0
|
||||
*/
|
||||
protected array $join = [];
|
||||
|
||||
/**
|
||||
* Base query which is merged with the query in the mapper
|
||||
*
|
||||
|
|
@ -307,6 +315,86 @@ abstract class DataMapperAbstract
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the joining data
|
||||
*
|
||||
* @param string $member Property name to filter by
|
||||
* @param string $mapper Mapper
|
||||
* @param mixed $value Filter value
|
||||
* @param string $logic Comparison logic (e.g. =, in, ...)
|
||||
* @param string $type Join type (e.g. left, right, inner)
|
||||
*
|
||||
* @return static
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function join(string $member, string $mapper, mixed $value, string $logic = '=', string $type = 'left') : self
|
||||
{
|
||||
$split = \explode('/', $member);
|
||||
$memberSplit = \array_shift($split);
|
||||
|
||||
$this->join[$memberSplit][] = [
|
||||
'child' => \implode('/', $split),
|
||||
'mapper' => $mapper,
|
||||
'value' => $value,
|
||||
'logic' => $logic,
|
||||
'type' => $type,
|
||||
];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the joining data
|
||||
*
|
||||
* @param string $member Property name to filter by
|
||||
* @param string $mapper Mapper
|
||||
* @param mixed $value Filter value
|
||||
* @param string $logic Comparison logic (e.g. =, in, ...)
|
||||
*
|
||||
* @return static
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function leftJoin(string $member, string $mapper, mixed $value, string $logic = '=') : self
|
||||
{
|
||||
return $this->join($member, $mapper, $value, $logic, 'left');
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the joining data
|
||||
*
|
||||
* @param string $member Property name to filter by
|
||||
* @param string $mapper Mapper
|
||||
* @param mixed $value Filter value
|
||||
* @param string $logic Comparison logic (e.g. =, in, ...)
|
||||
*
|
||||
* @return static
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function rightJoin(string $member, string $mapper, mixed $value, string $logic = '=') : self
|
||||
{
|
||||
return $this->join($member, $mapper, $value, $logic, 'right');
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the joining data
|
||||
*
|
||||
* @param string $member Property name to filter by
|
||||
* @param string $mapper Mapper
|
||||
* @param mixed $value Filter value
|
||||
* @param string $logic Comparison logic (e.g. =, in, ...)
|
||||
*
|
||||
* @return static
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function innerJoin(string $member, string $mapper, mixed $value, string $logic = '=') : self
|
||||
{
|
||||
return $this->join($member, $mapper, $value, $logic, 'inner');
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate a mapper (e.g. child mapper, relation mapper) based on the current mapper information.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -173,7 +173,6 @@ final class ReadMapper extends DataMapperAbstract
|
|||
{
|
||||
$primaryKeys = [];
|
||||
$memberOfPrimaryField = $this->mapper::COLUMNS[$this->mapper::PRIMARYFIELD]['internal'];
|
||||
$emptyWhere = empty($this->where);
|
||||
|
||||
if (isset($this->where[$memberOfPrimaryField])) {
|
||||
$keys = $this->where[$memberOfPrimaryField][0]['value'];
|
||||
|
|
@ -184,16 +183,14 @@ final class ReadMapper extends DataMapperAbstract
|
|||
$obj = [];
|
||||
|
||||
// Get remaining objects (not available in memory cache) or remaining where clauses.
|
||||
if (!empty($primaryKeys) || (!empty($this->where) || $emptyWhere)) {
|
||||
$dbData = $this->executeGetRaw($query);
|
||||
$dbData = $this->executeGetRaw($query);
|
||||
|
||||
foreach ($dbData as $row) {
|
||||
$value = $row[$this->mapper::PRIMARYFIELD . '_d' . $this->depth];
|
||||
$obj[$value] = $this->mapper::createBaseModel();
|
||||
foreach ($dbData as $row) {
|
||||
$value = $row[$this->mapper::PRIMARYFIELD . '_d' . $this->depth];
|
||||
$obj[$value] = $this->mapper::createBaseModel();
|
||||
|
||||
$obj[$value] = $this->populateAbstract($row, $obj[$value]);
|
||||
$this->loadHasManyRelations($obj[$value]);
|
||||
}
|
||||
$obj[$value] = $this->populateAbstract($row, $obj[$value]);
|
||||
$this->loadHasManyRelations($obj[$value]);
|
||||
}
|
||||
|
||||
$countResulsts = \count($obj);
|
||||
|
|
@ -322,6 +319,31 @@ final class ReadMapper extends DataMapperAbstract
|
|||
$query->fromAs($this->mapper::TABLE, $this->mapper::TABLE . '_d' . $this->depth);
|
||||
}
|
||||
|
||||
// Join tables manually without using "with()" (NOT has many/owns one etc.)
|
||||
// This is necessary for special cases, e.g. when joining in the other direction
|
||||
// Example: Show all profiles who have written a news article.
|
||||
// "with()" only allows to go from articles to accounts but we want to go the other way
|
||||
foreach ($this->join as $member => $values) {
|
||||
if (($col = $this->mapper::getColumnByMember($member)) !== null) {
|
||||
/* variable in model */
|
||||
foreach ($values as $join) {
|
||||
// @todo: the has many, etc. if checks only work if it is a relation on the first level, if we have a deeper where condition nesting this fails
|
||||
if ($join['child'] !== '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$query->join($join['mapper']::TABLE, $join['type'], $join['mapper']::TABLE . '_d' . ($this->depth + 1))
|
||||
->on(
|
||||
$this->mapper::TABLE . '_d' . $this->depth . '.' . $col,
|
||||
'=',
|
||||
$join['mapper']::TABLE . '_d' . ($this->depth + 1) . '.' . $join['mapper']::getColumnByMember($join['value']),
|
||||
'and',
|
||||
$join['mapper']::TABLE . '_d' . ($this->depth + 1)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// where
|
||||
foreach ($this->where as $member => $values) {
|
||||
// handle where query
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user