mirror of
https://github.com/Karaka-Management/phpOMS.git
synced 2026-01-18 12:48:41 +00:00
continue implementations
This commit is contained in:
parent
ea0b033e1c
commit
560f8a2796
|
|
@ -183,18 +183,6 @@ final class Autoloader
|
|||
|
||||
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) {
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ namespace phpOMS\DataStorage\Database;
|
|||
|
||||
use phpOMS\Contract\SerializableInterface;
|
||||
use phpOMS\DataStorage\Database\Query\Column;
|
||||
use phpOMS\DataStorage\Database\Query\ColumnName;
|
||||
use phpOMS\DataStorage\Database\Query\Parameter;
|
||||
|
||||
/**
|
||||
|
|
@ -299,6 +300,8 @@ abstract class GrammarAbstract
|
|||
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) {
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -282,7 +282,6 @@ final class ReadMapper extends DataMapperAbstract
|
|||
|
||||
$value = $row[$this->mapper::PRIMARYFIELD . '_d' . $this->depth];
|
||||
$obj[$value] = $this->mapper::createBaseModel($row);
|
||||
|
||||
$obj[$value] = $this->populateAbstract($row, $obj[$value]);
|
||||
|
||||
$ids[] = $value;
|
||||
|
|
@ -293,14 +292,16 @@ final class ReadMapper extends DataMapperAbstract
|
|||
// 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);
|
||||
}
|
||||
|
||||
|
|
@ -329,7 +330,10 @@ final class ReadMapper extends DataMapperAbstract
|
|||
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;
|
||||
}
|
||||
|
|
@ -565,7 +569,7 @@ 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.)
|
||||
// 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
|
||||
|
|
@ -577,7 +581,7 @@ final class ReadMapper extends DataMapperAbstract
|
|||
/* 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;
|
||||
}
|
||||
|
|
@ -649,12 +653,12 @@ final class ReadMapper extends DataMapperAbstract
|
|||
/* 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).
|
||||
|
||||
|
|
@ -759,6 +763,7 @@ final class ReadMapper extends DataMapperAbstract
|
|||
$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!!!
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -846,7 +851,7 @@ final class ReadMapper extends DataMapperAbstract
|
|||
|
||||
$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);
|
||||
}
|
||||
|
|
@ -865,7 +870,7 @@ final class ReadMapper extends DataMapperAbstract
|
|||
|
||||
$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);
|
||||
}
|
||||
|
|
@ -916,7 +921,7 @@ final class ReadMapper extends DataMapperAbstract
|
|||
}
|
||||
}
|
||||
|
||||
// @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
|
||||
|
|
@ -1063,7 +1068,7 @@ final class ReadMapper extends DataMapperAbstract
|
|||
* @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
|
||||
*/
|
||||
|
|
@ -1129,6 +1134,9 @@ final class ReadMapper extends DataMapperAbstract
|
|||
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;
|
||||
|
|
@ -1137,7 +1145,7 @@ final class ReadMapper extends DataMapperAbstract
|
|||
$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];
|
||||
|
|
@ -1174,12 +1182,12 @@ final class ReadMapper extends DataMapperAbstract
|
|||
$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;
|
||||
|
|
@ -1235,7 +1243,7 @@ final class ReadMapper extends DataMapperAbstract
|
|||
$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];
|
||||
|
|
|
|||
|
|
@ -286,12 +286,10 @@ final class WriteMapper extends DataMapperAbstract
|
|||
|
||||
/** @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
|
||||
|
|
@ -306,7 +304,9 @@ final class WriteMapper extends DataMapperAbstract
|
|||
|
||||
$mapper::create(db: $this->db)->execute($values);
|
||||
continue;
|
||||
} elseif (!\is_array($values)) {
|
||||
}
|
||||
|
||||
if (!\is_array($values)) {
|
||||
// @todo conditionals???
|
||||
continue;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -231,6 +231,8 @@ class Builder extends BuilderAbstract
|
|||
'similar to',
|
||||
'not similar to',
|
||||
'in',
|
||||
'exists',
|
||||
'not exists',
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
|
|||
33
DataStorage/Database/Query/ColumnName.php
Normal file
33
DataStorage/Database/Query/ColumnName.php
Normal file
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -17,6 +17,7 @@ namespace phpOMS\DataStorage\Database\Query\Grammar;
|
|||
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;
|
||||
|
|
@ -273,7 +274,7 @@ class Grammar extends GrammarAbstract
|
|||
*
|
||||
* @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
|
||||
*
|
||||
|
|
@ -459,6 +460,7 @@ class Grammar extends GrammarAbstract
|
|||
}
|
||||
|
||||
// @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']) . ' '
|
||||
|
|
|
|||
|
|
@ -89,4 +89,8 @@ class RegionEnum extends Enum
|
|||
public const ANTARCTICA = 'Antarctica';
|
||||
|
||||
public const CONTINENTS = 'Continents';
|
||||
|
||||
public const DOMESTIC = 'Domestic';
|
||||
|
||||
public const EXPORT = 'Export';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ final class Evaluator
|
|||
return $n !== '';
|
||||
});
|
||||
|
||||
foreach ($equation as $i => $token) {
|
||||
foreach ($equation as $token) {
|
||||
if (\is_numeric($token)) {
|
||||
$output[] = $token;
|
||||
} elseif (\strpbrk($token, '^*/+-') !== false) {
|
||||
|
|
@ -140,7 +140,7 @@ final class Evaluator
|
|||
/*|| ($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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user