From d81bf80adac3a7be4ed0db05961a970f56fc3827 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sat, 14 Mar 2020 17:58:43 +0100 Subject: [PATCH] bug fixes after datamapper changes --- DataStorage/Database/DataMapperAbstract.php | 101 +++++++++++++----- DataStorage/Database/Query/Builder.php | 2 +- .../Database/Schema/Grammar/MysqlGrammar.php | 2 +- .../Database/DataMapperAbstractTest.php | 11 +- .../Database/TestModel/BaseModelMapper.php | 8 +- tests/Module/ModuleAbstractTest.php | 3 + 6 files changed, 93 insertions(+), 34 deletions(-) diff --git a/DataStorage/Database/DataMapperAbstract.php b/DataStorage/Database/DataMapperAbstract.php index 44cb06f8b..6067d8938 100644 --- a/DataStorage/Database/DataMapperAbstract.php +++ b/DataStorage/Database/DataMapperAbstract.php @@ -1910,7 +1910,7 @@ class DataMapperAbstract implements DataMapperInterface return []; } - $obj = $mapper::getInitialized($mapper, $result[$mapper::$primaryField . '_' . $depth]); + $obj = $mapper::getInitializedArray($mapper, $result[$mapper::$primaryField . '_' . $depth]); return $obj ?? $mapper::populateAbstractArray($result, [], $depth); } @@ -1941,7 +1941,7 @@ class DataMapperAbstract implements DataMapperInterface return $mapper::createNullModel(); } - $obj = $mapper::getInitializedArray($mapper, $result[$mapper::$primaryField . '_' . $depth]); + $obj = $mapper::getInitialized($mapper, $result[$mapper::$primaryField . '_' . $depth]); return $obj ?? $mapper::populateAbstract($result, $mapper::createBaseModel(), $depth); } @@ -1995,7 +1995,7 @@ class DataMapperAbstract implements DataMapperInterface foreach (static::$columns as $column => $def) { $alias = $column . '_' . $depth; - if (!isset($result[$alias])) { + if (!\array_key_exists($alias, $result)) { continue; } @@ -2078,7 +2078,7 @@ class DataMapperAbstract implements DataMapperInterface $column = $def['mapper']::getColumnByMember($member); $alias = $column . '_' . ($depth - 1); - if (!isset($result[$alias]) || !isset($def['column'])) { + if (!\array_key_exists($alias, $result) || !isset($def['column'])) { continue; } @@ -2153,11 +2153,15 @@ class DataMapperAbstract implements DataMapperInterface */ public static function populateAbstractArray(array $result, array $obj = [], int $depth = 3) : array { - foreach ($result as $column => $value) { - if (!isset(static::$columns[$column]['internal'])) { + foreach (static::$columns as $column => $def) { + $alias = $column . '_' . $depth; + + if (!\array_key_exists($alias, $result)) { continue; } + $value = $result[$alias]; + $path = static::$columns[$column]['internal']; if (\stripos($path, '/') !== false) { $path = \explode('/', $path); @@ -2166,9 +2170,17 @@ class DataMapperAbstract implements DataMapperInterface $path = \implode('/', $path); } - if (isset(static::$ownsOne[static::$columns[$column]['internal']])) { + if (isset(static::$ownsOne[$def['internal']])) { + if ($depth - 1 < 1) { + continue; + } + $value = self::populateOwnsOneArray(static::$columns[$column]['internal'], $result, $depth - 1); - } elseif (isset(static::$belongsTo[static::$columns[$column]['internal']])) { + } elseif (isset(static::$belongsTo[$def['internal']])) { + if ($depth - 1 < 1) { + continue; + } + $value = self::populateBelongsToArray(static::$columns[$column]['internal'], $result, $depth - 1); } elseif (\in_array(static::$columns[$column]['type'], ['string', 'int', 'float', 'bool'])) { \settype($value, static::$columns[$column]['type']); @@ -2181,6 +2193,28 @@ class DataMapperAbstract implements DataMapperInterface $obj = ArrayUtils::setArray($path, $obj, $value, '/', true); } + foreach (static::$hasMany as $member => $def) { + $column = $def['mapper']::getColumnByMember($member); + $alias = $column . '_' . ($depth - 1); + + if (!\array_key_exists($alias, $result) || !isset($def['column'])) { + continue; + } + + $value = $result[$alias]; + + $path = $member; + if (\in_array($def['mapper']::$columns[$column]['type'], ['string', 'int', 'float', 'bool'])) { + \settype($value, $def['mapper']::$columns[$column]['type']); + } elseif ($def['mapper']::$columns[$column]['type'] === 'DateTime') { + $value = $value === null ? null : new \DateTime($value); + } elseif ($def['mapper']::$columns[$column]['type'] === 'Json') { + $value = \json_decode($value, true); + } + + $obj = ArrayUtils::setArray($path, $obj, $value, '/', true); + } + return $obj; } @@ -2338,25 +2372,15 @@ class DataMapperAbstract implements DataMapperInterface unset($keys[$key]); } - if (empty($keys) && $primaryKey !== null) { - $countResulsts = \count($obj); + if (!empty($keys) || $primaryKey === null) { + $dbData = self::getRaw($keys, $relations, $depth, $ref, $query); + foreach ($dbData as $row) { + $value = $row[static::$primaryField . '_' . $depth]; + $obj[$value] = self::createBaseModel(); + self::addInitialized(static::class, $value, $obj[$value]); - if ($countResulsts === 0) { - return self::createNullModel(); - } elseif ($countResulsts === 1) { - return \reset($obj); + $obj[$value] = self::populateAbstract($row, $obj[$value], $depth); } - - return $obj; - } - - $dbData = self::getRaw($keys, $relations, $depth, $ref, $query); - foreach ($dbData as $row) { - $value = $row[static::$primaryField . '_' . $depth]; - $obj[$value] = self::createBaseModel(); - self::addInitialized(static::class, $value, $obj[$value]); - - $obj[$value] = self::populateAbstract($row, $obj[$value], $depth); } self::fillRelations($obj, $relations, $depth - 1); @@ -2514,6 +2538,12 @@ class DataMapperAbstract implements DataMapperInterface { $result = self::get(null, $relations, $depth); + if (\is_object($result)) { + if (\stripos(\get_class($result), '\Null') !== false) { + return []; + } + } + return !\is_array($result) ? [$result] : $result; } @@ -2531,7 +2561,7 @@ class DataMapperAbstract implements DataMapperInterface { $result = self::getArray(null, $relations, $depth); - return !\is_array($result) ? [$result] : $result; + return !\is_array(\reset($result)) ? [$result] : $result; } /** @@ -2577,6 +2607,12 @@ class DataMapperAbstract implements DataMapperInterface { $result = self::get(null, $relations, $depth, null, $query); + if (\is_object($result)) { + if (\stripos(\get_class($result), '\Null') !== false) { + return []; + } + } + return !\is_array($result) ? [$result] : $result; } @@ -3070,6 +3106,19 @@ class DataMapperAbstract implements DataMapperInterface } } + /** + * Clear cache + * + * @return mixed + * + * @since 1.0.0 + */ + public static function clearCache() + { + self::$initObjects = []; + self::$initArrays = []; + } + /** * Find database column name by member name * diff --git a/DataStorage/Database/Query/Builder.php b/DataStorage/Database/Query/Builder.php index b13112658..97f3f97fd 100644 --- a/DataStorage/Database/Query/Builder.php +++ b/DataStorage/Database/Query/Builder.php @@ -555,7 +555,7 @@ class Builder extends BuilderAbstract $i = 0; foreach ($columns as $column) { if (isset($operator[$i]) && !\in_array(\strtolower($operator[$i]), self::OPERATORS)) { - throw new \InvalidArgumentException('Unknown operator.'); + throw new \InvalidArgumentException('Unknown operator: "' . $operator[$i] . '"'); } $this->wheres[self::getPublicColumnName($column)][] = [ diff --git a/DataStorage/Database/Schema/Grammar/MysqlGrammar.php b/DataStorage/Database/Schema/Grammar/MysqlGrammar.php index e3d6f88e8..99fa410d6 100644 --- a/DataStorage/Database/Schema/Grammar/MysqlGrammar.php +++ b/DataStorage/Database/Schema/Grammar/MysqlGrammar.php @@ -75,7 +75,7 @@ class MysqlGrammar extends Grammar $builder->select('*') ->from('information_schema.columns') ->where('table_schema', '=', $query->getConnection()->getDatabase()) - ->andWhere('table_name', '=' . $table); + ->andWhere('table_name', '=', $table); return \rtrim($builder->toSql(), ';'); } diff --git a/tests/DataStorage/Database/DataMapperAbstractTest.php b/tests/DataStorage/Database/DataMapperAbstractTest.php index e08983338..d39c6a320 100644 --- a/tests/DataStorage/Database/DataMapperAbstractTest.php +++ b/tests/DataStorage/Database/DataMapperAbstractTest.php @@ -218,7 +218,11 @@ class DataMapperAbstractTest extends \PHPUnit\Framework\TestCase self::assertEquals($this->model->belongsToOne->string, $modelR->belongsToOne->string); $for = ManyToManyDirectModelMapper::getFor($id, 'to'); - self::assertEquals(\reset($this->model->hasManyDirect)->string, \reset($for)->string); + + self::assertEquals( + \reset($this->model->hasManyDirect)->string, + $for->string + ); self::assertCount(1, BaseModelMapper::getAll()); } @@ -250,7 +254,10 @@ class DataMapperAbstractTest extends \PHPUnit\Framework\TestCase self::assertEquals($this->modelArray['belongsToOne']['string'], $modelR['belongsToOne']['string']); $for = ManyToManyDirectModelMapper::getForArray($id, 'to'); - self::assertEquals(\reset($this->modelArray['hasManyDirect'])['string'], \reset($for)['string']); + self::assertEquals( + \reset($this->modelArray['hasManyDirect'])['string'], + \reset($for)['string'] + ); self::assertCount(1, BaseModelMapper::getAllArray()); } diff --git a/tests/DataStorage/Database/TestModel/BaseModelMapper.php b/tests/DataStorage/Database/TestModel/BaseModelMapper.php index 3411a11c5..156a6dbad 100644 --- a/tests/DataStorage/Database/TestModel/BaseModelMapper.php +++ b/tests/DataStorage/Database/TestModel/BaseModelMapper.php @@ -46,15 +46,15 @@ class BaseModelMapper extends DataMapperAbstract */ protected static array $belongsTo = [ 'belongsToOne' => [ - 'mapper' => BelongsToModelMapper::class, - 'dest' => 'test_base_belongs_to_one', + 'mapper' => BelongsToModelMapper::class, + 'self' => 'test_base_belongs_to_one', ], ]; protected static array $ownsOne = [ 'ownsOneSelf' => [ - 'mapper' => OwnsOneModelMapper::class, - 'dest' => 'test_base_owns_one_self', + 'mapper' => OwnsOneModelMapper::class, + 'self' => 'test_base_owns_one_self', ], ]; diff --git a/tests/Module/ModuleAbstractTest.php b/tests/Module/ModuleAbstractTest.php index 848e139fe..55e373ab4 100644 --- a/tests/Module/ModuleAbstractTest.php +++ b/tests/Module/ModuleAbstractTest.php @@ -17,6 +17,7 @@ namespace phpOMS\tests\Module; require_once __DIR__ . '/../Autoloader.php'; use phpOMS\Application\ApplicationAbstract; +use phpOMS\DataStorage\Database\RelationType; use phpOMS\Event\EventManager; use phpOMS\Message\Http\HttpRequest; use phpOMS\Message\Http\HttpResponse; @@ -212,6 +213,8 @@ class ModuleAbstractTest extends \PHPUnit\Framework\TestCase private function dbSetup() : void { + BaseModelMapper::clearCache(); + $GLOBALS['dbpool']->get()->con->prepare( 'CREATE TABLE `test_base` ( `test_base_id` int(11) NOT NULL AUTO_INCREMENT,