Skip to content

Commit

Permalink
continue implementations
Browse files Browse the repository at this point in the history
  • Loading branch information
Dennis Eichhorn committed Jan 12, 2024
1 parent ea0b033 commit 560f8a2
Show file tree
Hide file tree
Showing 10 changed files with 79 additions and 47 deletions.
12 changes: 0 additions & 12 deletions Autoloader.php
Original file line number Diff line number Diff line change
Expand Up @@ -183,18 +183,6 @@ public static function defaultAutoloader(string $class) : void

return;
}

/*
if (!isset($valid[$subclass])) {
foreach (self::$classmap as $map => $path) {
if (\str_starts_with($class, $map)) {
include_once $path . $class . '.php';
return;
}
}
}
*/
}

foreach (self::$paths as $path) {
Expand Down
3 changes: 3 additions & 0 deletions DataStorage/Database/GrammarAbstract.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

use phpOMS\Contract\SerializableInterface;
use phpOMS\DataStorage\Database\Query\Column;
use phpOMS\DataStorage\Database\Query\ColumnName;
use phpOMS\DataStorage\Database\Query\Parameter;

/**
Expand Down Expand Up @@ -299,6 +300,8 @@ protected function compileValue(BuilderAbstract $query, mixed $value) : string
return \rtrim(\rtrim(\number_format($value, 5, '.', ''), '0'), '.');
} elseif ($value instanceof Column) {
return '(' . \rtrim($this->compileColumnQuery($value), ';') . ')';
} elseif ($value instanceof ColumnName) {
return $this->compileSystem($value->name);
} elseif ($value instanceof BuilderAbstract) {
return '(' . \rtrim($value->toSql(), ';') . ')';
} elseif ($value instanceof \JsonSerializable) {
Expand Down
8 changes: 0 additions & 8 deletions DataStorage/Database/Mapper/DataMapperFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -108,14 +108,6 @@ class DataMapperFactory
*/
public const TABLE = '';

/**
* Parent column.
*
* @var class-string
* @since 1.0.0
*/
public const PARENT = '';

/**
* Model to use by the mapper.
*
Expand Down
46 changes: 27 additions & 19 deletions DataStorage/Database/Mapper/ReadMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,6 @@ public function executeGet(Builder $query = null) : mixed

$value = $row[$this->mapper::PRIMARYFIELD . '_d' . $this->depth];
$obj[$value] = $this->mapper::createBaseModel($row);

$obj[$value] = $this->populateAbstract($row, $obj[$value]);

$ids[] = $value;
Expand All @@ -293,14 +292,16 @@ public function executeGet(Builder $query = null) : mixed
// BUT the relation data is not available in the object itself meaning after retrieving the object
// it cannot get assigned to the correct parent object.
// Other relation types are easy because either the parent or child object contain the relation info.
$this->loadHasManyRelations($obj[$value]);
// One solution could be to always pass an array
if (!empty($this->with)) {
$this->loadHasManyRelations($obj[$value]);
}
}

$countResulsts = \count($obj);

if ($countResulsts === 0) {
$countResults = \count($obj);
if ($countResults === 0) {
return $this->mapper::createNullModel();
} elseif ($countResulsts === 1) {
} elseif ($countResults === 1) {
return \reset($obj);
}

Expand Down Expand Up @@ -329,7 +330,10 @@ public function executeGetYield(Builder $query = null)
foreach ($this->executeGetRawYield($query) as $row) {
$obj = $this->mapper::createBaseModel($row);
$obj = $this->populateAbstract($row, $obj);
$this->loadHasManyRelations($obj);

if (!empty($this->with)) {
$this->loadHasManyRelations($obj);
}

yield $obj;
}
Expand Down Expand Up @@ -565,7 +569,7 @@ public function getQuery(Builder $query = null, array $columns = []) : Builder
$query->fromAs($this->mapper::TABLE, $this->mapper::TABLE . '_d' . $this->depth);
}

// Join tables manually without using "with()" (NOT has many/owns one etc.)
// Join tables manually without using "with()" (NOT hasMany/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
Expand All @@ -577,7 +581,7 @@ public function getQuery(Builder $query = null, array $columns = []) : Builder
/* variable in model */
// @todo join handling is extremely ugly, needs to be refactored
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
// @todo the hasMany, 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;
}
Expand Down Expand Up @@ -649,12 +653,12 @@ public function getQuery(Builder $query = null, array $columns = []) : Builder
/* variable in model */
$previous = null;
foreach ($values as $where) {
// @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
// @todo the hasMany, 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 ($where['child'] !== '') {
continue;
}

$comparison = \is_array($where['value']) && \count($where['value']) > 1 ? 'in' : $where['logic'];
$comparison = \is_array($where['value']) && \count($where['value']) > 1 ? 'IN' : $where['logic'];
if ($where['comparison'] === 'ALT') {
// This uses an alternative value if the previous value(s) in the where clause don't exist (e.g. for localized results where you allow a user language, alternatively a primary language, and then alternatively any language if the first two don't exist).

Expand Down Expand Up @@ -759,6 +763,7 @@ public function getQuery(Builder $query = null, array $columns = []) : Builder
$query->orderBy($this->mapper::TABLE . '_d' . $this->depth . '.' . $column, $sort['order']);

break; // there is only one root element (one element with child === '')
// @todo Is this true? sort can have multiple sort components!!!
}
}

Expand Down Expand Up @@ -846,7 +851,7 @@ public function populateAbstract(array $result, object $obj) : object

$value = $this->populateOwnsOne($def['internal'], $result, $default);

// loads has many relations. other relations are loaded in the populateOwnsOne
// loads hasMany relations. other relations are loaded in the populateOwnsOne
if (\is_object($value) && isset($this->mapper::OWNS_ONE[$def['internal']]['mapper'])) {
$this->mapper::OWNS_ONE[$def['internal']]['mapper']::reader(db: $this->db)->loadHasManyRelations($value);
}
Expand All @@ -865,7 +870,7 @@ public function populateAbstract(array $result, object $obj) : object

$value = $this->populateBelongsTo($def['internal'], $result, $default);

// loads has many relations. other relations are loaded in the populateBelongsTo
// loads hasMany relations. other relations are loaded in the populateBelongsTo
if (\is_object($value) && isset($this->mapper::BELONGS_TO[$def['internal']]['mapper'])) {
$this->mapper::BELONGS_TO[$def['internal']]['mapper']::reader(db: $this->db)->loadHasManyRelations($value);
}
Expand Down Expand Up @@ -916,7 +921,7 @@ public function populateAbstract(array $result, object $obj) : object
}
}

// @todo How is this allowed? at the bottom we set $obj->hasMany = value. A has many should be always an array?!
// @todo How is this allowed? at the bottom we set $obj->hasMany = value. A hasMany should be always an array?!
foreach ($this->mapper::HAS_MANY as $member => $def) {
if (!isset($this->with[$member])
|| !isset($def['column']) // @todo is this required? The code below indicates that this might be stupid
Expand Down Expand Up @@ -1063,7 +1068,7 @@ public function populateOwnsOne(string $member, array $result, mixed $default =
* @return mixed
*
* @todo in the future we could pass not only the $id ref but all of the data as a join!!! and save an additional select!!!
* @todo only the belongs to model gets populated the children of the belongsto model are always null models. either this function needs to call the get for the children, it should call get for the belongs to right away like the has many, or i find a way to recursevily load the data for all sub models and then populate that somehow recursively, probably too complex.
* @todo only the belongs to model gets populated the children of the belongsto model are always null models. either this function needs to call the get for the children, it should call get for the belongs to right away like the hasMany, or i find a way to recursevily load the data for all sub models and then populate that somehow recursively, probably too complex.
*
* @since 1.0.0
*/
Expand Down Expand Up @@ -1129,6 +1134,9 @@ public function loadHasManyRelations(object $obj) : void
return;
}

// @todo only accept array and then perform this work on the array here
// this allows us to better load data for all objects at the same time!

$primaryKey = $this->mapper::getObjectId($obj);
if (empty($primaryKey)) {
return;
Expand All @@ -1137,7 +1145,7 @@ public function loadHasManyRelations(object $obj) : void
$refClass = null;

// @todo check if there are more cases where the relation is already loaded with joins etc.
// there can be pseudo has many elements like localizations. They are has manies but these are already loaded with joins!
// there can be pseudo hasMany elements like localizations. They are hasMany but these are already loaded with joins!
foreach ($this->with as $member => $withData) {
if (isset($this->mapper::HAS_MANY[$member])) {
$many = $this->mapper::HAS_MANY[$member];
Expand Down Expand Up @@ -1174,12 +1182,12 @@ public function loadHasManyRelations(object $obj) : void
$refProp = $refClass->getProperty($member);
$refProp->setValue($obj, !\is_array($objects) && ($many['conditional'] ?? false) === false
? [$many['mapper']::getObjectId($objects) => $objects]
: $objects // if conditional === true the obj will be assigned (e.g. has many localizations but only one is loaded for the model)
: $objects // if conditional === true the obj will be assigned (e.g. hasMany localizations but only one is loaded for the model)
);
} else {
$obj->{$member} = !\is_array($objects) && ($many['conditional'] ?? false) === false
? [$many['mapper']::getObjectId($objects) => $objects]
: $objects; // if conditional === true the obj will be assigned (e.g. has many localizations but only one is loaded for the model)
: $objects; // if conditional === true the obj will be assigned (e.g. hasMany localizations but only one is loaded for the model)
}

continue;
Expand Down Expand Up @@ -1235,7 +1243,7 @@ public function hasManyRelations(object $obj) : bool
$refClass = null;

// @todo check if there are more cases where the relation is already loaded with joins etc.
// there can be pseudo has many elements like localizations. They are has manies but these are already loaded with joins!
// there can be pseudo hasMany elements like localizations. They are has manies but these are already loaded with joins!
foreach ($this->with as $member => $withData) {
if (isset($this->mapper::HAS_MANY[$member])) {
$many = $this->mapper::HAS_MANY[$member];
Expand Down
10 changes: 5 additions & 5 deletions DataStorage/Database/Mapper/WriteMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -286,12 +286,10 @@ private function createHasMany(object $obj, mixed $objId, \ReflectionClass &$ref

/** @var class-string<DataMapperFactory> $mapper */
$mapper = $this->mapper::HAS_MANY[$propertyName]['mapper'];
$internalName = isset($mapper::COLUMNS[$this->mapper::HAS_MANY[$propertyName]['self']])
? $mapper::COLUMNS[$this->mapper::HAS_MANY[$propertyName]['self']]['internal']
: 'ERROR';
$internalName = $mapper::COLUMNS[$this->mapper::HAS_MANY[$propertyName]['self']]['internal'] ?? 'ERROR-BAD-SELF';

// @todo this or $isRelPrivate is wrong, don't know which one.
$isInternalPrivate =$mapper::COLUMNS[$this->mapper::HAS_MANY[$propertyName]['self']]['private'] ?? false;
$isInternalPrivate = $mapper::COLUMNS[$this->mapper::HAS_MANY[$propertyName]['self']]['private'] ?? false;

if (\is_object($values)) {
// conditionals
Expand All @@ -306,7 +304,9 @@ private function createHasMany(object $obj, mixed $objId, \ReflectionClass &$ref

$mapper::create(db: $this->db)->execute($values);
continue;
} elseif (!\is_array($values)) {
}

if (!\is_array($values)) {
// @todo conditionals???
continue;
}
Expand Down
2 changes: 2 additions & 0 deletions DataStorage/Database/Query/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,8 @@ class Builder extends BuilderAbstract
'similar to',
'not similar to',
'in',
'exists',
'not exists',
];

/**
Expand Down
33 changes: 33 additions & 0 deletions DataStorage/Database/Query/ColumnName.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php
/**
* Jingga
*
* PHP Version 8.1
*
* @package phpOMS\DataStorage\Database\Query
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);

namespace phpOMS\DataStorage\Database\Query;

/**
* Database query builder.
*
* @package phpOMS\DataStorage\Database\Query
* @license OMS License 2.0
* @link https://jingga.app
* @since 1.0.0
*/
final class ColumnName
{
public string $name = '';

public function __construct(string $name)
{
$this->name = $name;
}
}
4 changes: 3 additions & 1 deletion DataStorage/Database/Query/Grammar/Grammar.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
use phpOMS\DataStorage\Database\BuilderAbstract;
use phpOMS\DataStorage\Database\GrammarAbstract;
use phpOMS\DataStorage\Database\Query\Builder;
use phpOMS\DataStorage\Database\Query\ColumnName;
use phpOMS\DataStorage\Database\Query\From;
use phpOMS\DataStorage\Database\Query\QueryType;
use phpOMS\DataStorage\Database\Query\Where;
Expand Down Expand Up @@ -273,7 +274,7 @@ protected function compileWheres(Builder $query, array $wheres, bool $first = tr
*
* @param array $element Element data
* @param Builder $query Query builder
* @param bool $first Is first element (usefull for nesting)
* @param bool $first Is first element (useful for nesting)
*
* @return string
*
Expand Down Expand Up @@ -459,6 +460,7 @@ protected function compileOnElement(array $element, Builder $query, bool $first
}

// @todo on doesn't allow string values as value (only table column names). This is bad and needs to be fixed!
// Solution could be to use ColumnName as internal object and then pass it to compileValue in all cases
// Other types such as int etc. are kind of possible
if (isset($element['value'])) {
$expression .= ' ' . \strtoupper($element['operator']) . ' '
Expand Down
4 changes: 4 additions & 0 deletions Localization/RegionEnum.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,8 @@ class RegionEnum extends Enum
public const ANTARCTICA = 'Antarctica';

public const CONTINENTS = 'Continents';

public const DOMESTIC = 'Domestic';

public const EXPORT = 'Export';
}
4 changes: 2 additions & 2 deletions Math/Parser/Evaluator.php
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ private static function shuntingYard(string $equation) : array
return $n !== '';
});

foreach ($equation as $i => $token) {
foreach ($equation as $token) {
if (\is_numeric($token)) {
$output[] = $token;
} elseif (\strpbrk($token, '^*/+-') !== false) {
Expand All @@ -140,7 +140,7 @@ private static function shuntingYard(string $equation) : array
/*|| ($operators[$o1]['order'] === 1 && $operators[$o1]['precedence'] < $operators[$o2]['precedence'])*/)
) {
// The commented part above is always FALSE because this equation always compares 4 < 2|3|4.
// Only uncomment if the opperators array changes.
// Only uncomment if the operators array changes.
$output[] = \array_pop($stack);
$o2 = \end($stack);
}
Expand Down

0 comments on commit 560f8a2

Please sign in to comment.