diff --git a/phpcs.xml.dist b/phpcs.xml.dist index 1219d48..37fe9c9 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -14,5 +14,50 @@ src/ tests/ - + + + + + + + + + + tests/ + + + + + tests/ + + + tests/ + + + + + tests/ + + + + + tests/ + + + tests/ + + + + + tests/ + + + tests/ + + + tests/ + + + tests/ + diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 58f379d..a79c04a 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -10,9 +10,6 @@ parameters: - message: '/Unsafe usage of new static\(\)\./' - message: '/Cannot unset property .+ because it might have hooks in a subclass\./' - message: '/Array has \d+ duplicate keys/' - - - message: '/(unknown class|does not accept)/' - path: tests/Styles/ - message: '/Parameter #1 .+ of class Respect\\Relational\\Mapper constructor expects .+, string given\./' path: tests/MapperTest.php diff --git a/src/Db.php b/src/Db.php index 63d4020..e91781c 100644 --- a/src/Db.php +++ b/src/Db.php @@ -7,23 +7,21 @@ use PDO; use PDOStatement; +use function array_map; +use function is_array; +use function is_callable; +use function is_int; +use function is_object; + final class Db { - protected PDO $connection; protected Sql $currentSql; - protected Sql $protoSql; - - public function __call(string $methodName, array $arguments): static - { - $this->currentSql->__call($methodName, $arguments); - return $this; - } + protected Sql $protoSql; - public function __construct(PDO $connection, Sql|null $sqlPrototype = null) + public function __construct(protected PDO $connection, Sql|null $sqlPrototype = null) { $connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); - $this->connection = $connection; $this->protoSql = $sqlPrototype ?: new Sql(); $this->currentSql = clone $this->protoSql; } @@ -63,11 +61,11 @@ public function prepare(string $queryString, mixed $object = '\stdClass', array| match (true) { is_int($object) => $statement->setFetchMode($object), - '\stdClass' === $object || 'stdClass' === $object => $statement->setFetchMode(PDO::FETCH_OBJ), + $object === '\stdClass' || $object === 'stdClass' => $statement->setFetchMode(PDO::FETCH_OBJ), is_callable($object) => $statement->setFetchMode(PDO::FETCH_OBJ), is_object($object) => $statement->setFetchMode(PDO::FETCH_INTO, $object), is_array($object) => $statement->setFetchMode(PDO::FETCH_ASSOC), - is_null($extra) => $statement->setFetchMode(PDO::FETCH_CLASS, $object), + $extra === null => $statement->setFetchMode(PDO::FETCH_CLASS, $object), default => $statement->setFetchMode(PDO::FETCH_CLASS, $object, $extra), }; @@ -93,8 +91,15 @@ protected function executeStatement(mixed $object = '\stdClass', mixed $extra = protected function performFetch(string $method, mixed $object = '\stdClass', mixed $extra = null): mixed { $statement = $this->executeStatement($object, $extra); - $result = $statement->{$method}(); - return $result; + return $statement->{$method}(); + } + + /** @param array $arguments */ + public function __call(string $methodName, array $arguments): static + { + $this->currentSql->__call($methodName, $arguments); + + return $this; } } diff --git a/src/Mapper.php b/src/Mapper.php index 17942e0..62e611d 100644 --- a/src/Mapper.php +++ b/src/Mapper.php @@ -4,16 +4,38 @@ namespace Respect\Relational; -use Exception; use PDO; use PDOException; use PDOStatement; use ReflectionClass; +use ReflectionException; +use ReflectionProperty; use Respect\Data\AbstractMapper; +use Respect\Data\CollectionIterator; use Respect\Data\Collections as c; use Respect\Data\Collections\Collection; -use Respect\Data\CollectionIterator; use SplObjectStorage; +use Throwable; + +use function array_combine; +use function array_diff; +use function array_fill; +use function array_intersect_key; +use function array_keys; +use function array_merge; +use function array_pop; +use function array_reverse; +use function class_exists; +use function count; +use function get_object_vars; +use function is_array; +use function is_numeric; +use function is_object; +use function is_scalar; +use function iterator_to_array; +use function preg_match; +use function preg_replace; +use function str_replace; /** Maps objects to database operations */ final class Mapper extends AbstractMapper implements @@ -22,12 +44,15 @@ final class Mapper extends AbstractMapper implements c\Typable { protected Db $db; + public string $entityNamespace = '\\'; + public bool $disableEntityConstructor = false; public function __construct(PDO|Db $db) { parent::__construct(); + $this->db = $db instanceof PDO ? new Db($db) : $db; } @@ -36,20 +61,6 @@ public function getDb(): Db return $this->db; } - protected function flushSingle(object $entity): void - { - $coll = $this->tracked[$entity]; - $cols = $this->extractColumns($entity, $coll); - - if ($this->removed->offsetExists($entity)) { - $this->rawDelete($cols, $coll, $entity); - } elseif ($this->new->offsetExists($entity)) { - $this->rawInsert($cols, $coll, $entity); - } else { - $this->rawUpdate($cols, $coll); - } - } - public function persist(object $object, Collection $onCollection): bool { $next = $onCollection->getNext(); @@ -75,6 +86,74 @@ public function persist(object $object, Collection $onCollection): bool return parent::persist($object, $onCollection); } + public function flush(): void + { + $conn = $this->db->getConnection(); + $conn->beginTransaction(); + + try { + foreach ($this->changed as $entity) { + $this->flushSingle($entity); + } + } catch (Throwable $e) { + $conn->rollback(); + + throw $e; + } + + $this->reset(); + $conn->commit(); + } + + public function getFilters(Collection $collection): mixed + { + return $collection->getExtra('filters'); + } + + public function getMixins(Collection $collection): mixed + { + return $collection->getExtra('mixins'); + } + + public function getType(Collection $collection): mixed + { + return $collection->getExtra('type'); + } + + public function mixable(Collection $collection): bool + { + return $collection->have('mixins'); + } + + public function typable(Collection $collection): bool + { + return $collection->have('type'); + } + + public function filterable(Collection $collection): bool + { + return $collection->have('filters'); + } + + protected function flushSingle(object $entity): void + { + $coll = $this->tracked[$entity]; + $cols = $this->extractColumns($entity, $coll); + + if ($this->removed->offsetExists($entity)) { + $this->rawDelete($cols, $coll, $entity); + } elseif ($this->new->offsetExists($entity)) { + $this->rawInsert($cols, $coll, $entity); + } else { + $this->rawUpdate($cols, $coll); + } + } + + /** + * @param array $cols + * + * @return array + */ protected function extractAndOperateMixins(Collection $collection, array $cols): array { if (!$this->mixable($collection)) { @@ -88,11 +167,11 @@ protected function extractAndOperateMixins(Collection $collection, array $cols): array_combine( //create array with keys only $spec, - array_fill(0, count($spec), '') - ) + array_fill(0, count($spec), ''), + ), ); - if (isset($cols["{$mix}_id"])) { - $mixCols['id'] = $cols["{$mix}_id"]; + if (isset($cols[$mix . '_id'])) { + $mixCols['id'] = $cols[$mix . '_id']; $cols = array_diff($cols, $mixCols); //Remove mixin columns $this->rawUpdate($mixCols, $this->__get($mix)); } else { @@ -105,6 +184,11 @@ protected function extractAndOperateMixins(Collection $collection, array $cols): return $cols; } + /** + * @param array $columns + * + * @return array + */ protected function guessCondition(array &$columns, Collection $collection): array { $primaryName = $this->getStyle()->identifier($collection->getName()); @@ -114,21 +198,23 @@ protected function guessCondition(array &$columns, Collection $collection): arra return $condition; } + /** @param array $condition */ protected function rawDelete( array $condition, Collection $collection, - object $entity + object $entity, ): bool { $name = $collection->getName(); $columns = $this->extractColumns($entity, $collection); $condition = $this->guessCondition($columns, $collection); return $this->db - ->deleteFrom($name) - ->where($condition) - ->exec(); + ->deleteFrom($name) + ->where($condition) + ->exec(); } + /** @param array $columns */ protected function rawUpdate(array $columns, Collection $collection): bool { $columns = $this->extractAndOperateMixins($collection, $columns); @@ -136,58 +222,42 @@ protected function rawUpdate(array $columns, Collection $collection): bool $condition = $this->guessCondition($columns, $collection); return $this->db - ->update($name) - ->set($columns) - ->where($condition) - ->exec(); + ->update($name) + ->set($columns) + ->where($condition) + ->exec(); } + /** @param array $columns */ protected function rawInsert( array $columns, Collection $collection, - object|null $entity = null + object|null $entity = null, ): bool { $columns = $this->extractAndOperateMixins($collection, $columns); $name = $collection->getName(); $isInserted = $this->db - ->insertInto($name, $columns) - ->values($columns) - ->exec(); + ->insertInto($name, $columns) + ->values($columns) + ->exec(); - if (!is_null($entity)) { + if ($entity !== null) { $this->checkNewIdentity($entity, $collection); } return $isInserted; } - public function flush(): void - { - $conn = $this->db->getConnection(); - $conn->beginTransaction(); - - try { - foreach ($this->changed as $entity) { - $this->flushSingle($entity); - } - } catch (Exception $e) { - $conn->rollback(); - throw $e; - } - - $this->reset(); - $conn->commit(); - } - protected function checkNewIdentity(object $entity, Collection $collection): bool { $identity = null; try { $identity = $this->db->getConnection()->lastInsertId(); - } catch (PDOException $e) { + } catch (PDOException) { //some drivers may throw an exception here, it is just irrelevant return false; } + if (!$identity) { return false; } @@ -200,7 +270,7 @@ protected function checkNewIdentity(object $entity, Collection $collection): boo protected function createStatement( Collection $collection, - mixed $withExtra = null + mixed $withExtra = null, ): PDOStatement { $query = $this->generateQuery($collection); @@ -218,7 +288,7 @@ protected function generateQuery(Collection $collection): Sql { $collections = iterator_to_array( CollectionIterator::recursive($collection), - true + true, ); $sql = new Sql(); @@ -228,20 +298,24 @@ protected function generateQuery(Collection $collection): Sql return $sql; } + /** @return array */ protected function extractColumns(object $entity, Collection $collection): array { $primaryName = $this->getStyle()->identifier($collection->getName()); $cols = $this->getAllProperties($entity); foreach ($cols as &$c) { - if (is_object($c)) { - $c = $this->inferGet($c, $primaryName); + if (!is_object($c)) { + continue; } + + $c = $this->inferGet($c, $primaryName); } return $cols; } + /** @param array $collections */ protected function buildSelectStatement(Sql $sql, array $collections): Sql { $selectTable = []; @@ -249,48 +323,51 @@ protected function buildSelectStatement(Sql $sql, array $collections): Sql if ($this->mixable($c)) { foreach ($this->getMixins($c) as $mixin => $columns) { foreach ($columns as $col) { - $selectTable[] = "{$tableSpecifier}_mix{$mixin}.$col"; + $selectTable[] = $tableSpecifier . '_mix' . $mixin . '.' . $col; } - $selectTable[] = "{$tableSpecifier}_mix{$mixin}.". - $this->getStyle()->identifier($mixin). - " as {$mixin}_id"; + + $selectTable[] = $tableSpecifier . '_mix' . $mixin . '.' . + $this->getStyle()->identifier($mixin) . + ' as ' . $mixin . '_id'; } } + if ($this->filterable($c)) { $filters = $this->getFilters($c); if ($filters) { - $pkName = $tableSpecifier.'.'. + $pkName = $tableSpecifier . '.' . $this->getStyle()->identifier($c->getName()); if ($filters == ['*']) { - $selectColumns[] = $pkName; + $selectColumns = [$pkName]; } else { $selectColumns = [ - $tableSpecifier.'.'. + $tableSpecifier . '.' . $this->getStyle()->identifier($c->getName()), ]; foreach ($filters as $f) { - $selectColumns[] = "{$tableSpecifier}.{$f}"; + $selectColumns[] = $tableSpecifier . '.' . $f; } } if ($c->getNext()) { - $selectColumns[] = $tableSpecifier.'.'. + $selectColumns[] = $tableSpecifier . '.' . $this->getStyle()->remoteIdentifier( - $c->getNext()->getName() + $c->getNext()->getName(), ); } $selectTable = array_merge($selectTable, $selectColumns); } } else { - $selectTable[] = "$tableSpecifier.*"; + $selectTable[] = $tableSpecifier . '.*'; } } return $sql->select($selectTable); } + /** @param array $collections */ protected function buildTables(Sql $sql, array $collections): Sql { $conditions = $aliases = []; @@ -301,20 +378,25 @@ protected function buildTables(Sql $sql, array $collections): Sql $collection, $alias, $aliases, - $conditions + $conditions, ); } return $sql->where($conditions); } + /** + * @param array $conditions + * + * @return array + */ protected function parseConditions(array &$conditions, Collection $collection, string $alias): array { $entity = $collection->getName(); $originalConditions = $collection->getCondition(); $parsedConditions = []; $aliasedPk = $this->getStyle()->identifier($entity); - $aliasedPk = $alias.'.'.$aliasedPk; + $aliasedPk = $alias . '.' . $aliasedPk; if (is_scalar($originalConditions)) { $parsedConditions = [$aliasedPk => $originalConditions]; @@ -322,12 +404,12 @@ protected function parseConditions(array &$conditions, Collection $collection, s foreach ($originalConditions as $column => $value) { if (is_numeric($column)) { $parsedConditions[$column] = preg_replace( - "/{$entity}[.](\w+)/", - "$alias.$1", - $value + '/' . $entity . '[.](\w+)/', + $alias . '.$1', + $value, ); } else { - $parsedConditions["$alias.$column"] = $value; + $parsedConditions[$alias . '.' . $column] = $value; } } } @@ -337,20 +419,26 @@ protected function parseConditions(array &$conditions, Collection $collection, s protected function parseMixins(Sql $sql, Collection $collection, string $entity): void { - if ($this->mixable($collection)) { - foreach ($this->getMixins($collection) as $mix => $spec) { - $sql->innerJoin($mix); - $sql->as("{$entity}_mix{$mix}"); - } + if (!$this->mixable($collection)) { + return; + } + + foreach (array_keys($this->getMixins($collection)) as $mix) { + $sql->innerJoin($mix); + $sql->as($entity . '_mix' . $mix); } } + /** + * @param array $aliases + * @param array $conditions + */ protected function parseCollection( Sql $sql, Collection $collection, string $alias, array &$aliases, - array &$conditions + array &$conditions, ): mixed { $s = $this->getStyle(); $entity = $collection->getName(); @@ -362,41 +450,41 @@ protected function parseCollection( $conditions = $this->parseConditions( $conditions, $collection, - $alias + $alias, ) ?: $conditions; //No parent collection means it's the first table in the query - if (is_null($parentAlias)) { + if ($parentAlias === null) { $sql->from($entity); $this->parseMixins($sql, $collection, $entity); return null; + } + + if ($collection->isRequired()) { + $sql->innerJoin($entity); } else { - if ($collection->isRequired()) { - $sql->innerJoin($entity); - } else { - $sql->leftJoin($entity); - } + $sql->leftJoin($entity); + } - $this->parseMixins($sql, $collection, $entity); + $this->parseMixins($sql, $collection, $entity); - if ($alias !== $entity) { - $sql->as($alias); - } + if ($alias !== $entity) { + $sql->as($alias); + } - $aliasedPk = $alias.'.'.$s->identifier($entity); - $aliasedParentPk = $parentAlias.'.'.$s->identifier($parent); + $aliasedPk = $alias . '.' . $s->identifier($entity); + $aliasedParentPk = $parentAlias . '.' . $s->identifier($parent); - if ($this->hasComposition($entity, $next, $parent)) { - $onName = $alias.'.'.$s->remoteIdentifier($parent); - $onAlias = $aliasedParentPk; - } else { - $onName = $parentAlias.'.'.$s->remoteIdentifier($entity); - $onAlias = $aliasedPk; - } - - return $sql->on([$onName => $onAlias]); + if ($this->hasComposition($entity, $next, $parent)) { + $onName = $alias . '.' . $s->remoteIdentifier($parent); + $onAlias = $aliasedParentPk; + } else { + $onName = $parentAlias . '.' . $s->remoteIdentifier($entity); + $onAlias = $aliasedPk; } + + return $sql->on([$onName => $onAlias]); } protected function hasComposition(string $entity, string|null $next, string|null $parent): bool @@ -413,7 +501,7 @@ protected function hasComposition(string $entity, string|null $next, string|null protected function fetchSingle( Collection $collection, - PDOStatement $statement + PDOStatement $statement, ): SplObjectStorage|false { $name = $collection->getName(); $entityName = $name; @@ -436,7 +524,7 @@ protected function fetchSingle( protected function getNewEntityByName(string $entityName): object { $entityName = $this->getStyle()->styledName($entityName); - $entityClass = $this->entityNamespace.$entityName; + $entityClass = $this->entityNamespace . $entityName; $entityClass = class_exists($entityClass) ? $entityClass : '\stdClass'; $entityReflection = new ReflectionClass($entityClass); @@ -465,9 +553,9 @@ protected function inferSet(object &$entity, string $prop, mixed $value): void } try { - $mirror = new \ReflectionProperty($entity, $prop); + $mirror = new ReflectionProperty($entity, $prop); $mirror->setValue($entity, $value); - } catch (\ReflectionException $e) { + } catch (ReflectionException) { $entity->{$prop} = $value; } } @@ -475,17 +563,17 @@ protected function inferSet(object &$entity, string $prop, mixed $value): void protected function inferGet(object &$object, string $prop): mixed { try { - $mirror = new \ReflectionProperty($object, $prop); + $mirror = new ReflectionProperty($object, $prop); return $mirror->getValue($object); - } catch (\ReflectionException $e) { + } catch (ReflectionException) { return null; } } protected function fetchMulti( Collection $collection, - PDOStatement $statement + PDOStatement $statement, ): SplObjectStorage|false { $entities = []; $row = $statement->fetch(PDO::FETCH_NUM); @@ -495,21 +583,22 @@ protected function fetchMulti( } $this->postHydrate( - $entities = $this->createEntities($row, $statement, $collection) + $entities = $this->createEntities($row, $statement, $collection), ); return $entities; } + /** @param array $row */ protected function createEntities( array $row, PDOStatement $statement, - Collection $collection + Collection $collection, ): SplObjectStorage { $entities = new SplObjectStorage(); $entitiesInstances = $this->buildEntitiesInstances( $collection, - $entities + $entities, ); $entityInstance = array_pop($entitiesInstances); @@ -518,22 +607,25 @@ protected function createEntities( $columnMeta = $statement->getColumnMeta($col); $columnName = $columnMeta['name']; $primaryName = $this->getStyle()->identifier( - $entities[$entityInstance]->getName() + $entities[$entityInstance]->getName(), ); $this->inferSet($entityInstance, $columnName, $value); - if ($primaryName == $columnName) { - $entityInstance = array_pop($entitiesInstances); + if ($primaryName != $columnName) { + continue; } + + $entityInstance = array_pop($entitiesInstances); } return $entities; } + /** @return array */ protected function buildEntitiesInstances( Collection $collection, - SplObjectStorage $entities + SplObjectStorage $entities, ): array { $entitiesInstances = []; @@ -547,7 +639,8 @@ protected function buildEntitiesInstances( if ($this->mixable($c)) { $mixins = $this->getMixins($c); - foreach ($mixins as $mix) { + $mixinCount = count($mixins); + for ($i = 0; $i < $mixinCount; $i++) { $entitiesInstances[] = $entityInstance; } } @@ -572,6 +665,7 @@ protected function postHydrate(SplObjectStorage $entities): void foreach ($entitiesClone as $sub) { $this->tryHydration($entities, $sub, $field, $v); } + $this->inferSet($instance, $field, $v); } } @@ -582,56 +676,37 @@ protected function tryHydration(SplObjectStorage $entities, object $sub, string $tableName = $entities[$sub]->getName(); $primaryName = $this->getStyle()->identifier($tableName); - if ($tableName === $this->getStyle()->remoteFromIdentifier($field) - && $this->inferGet($sub, $primaryName) === $v) { - $v = $sub; + if ( + $tableName !== $this->getStyle()->remoteFromIdentifier($field) + || $this->inferGet($sub, $primaryName) !== $v + ) { + return; } + + $v = $sub; } protected function getSetterStyle(string $name): string { $name = str_replace('_', '', $this->getStyle()->styledProperty($name)); - return "set{$name}"; + return 'set' . $name; } + /** @return array */ protected function getAllProperties(object $object): array { $cols = get_object_vars($object); - $ref = new \ReflectionClass($object); + $ref = new ReflectionClass($object); foreach ($ref->getProperties() as $prop) { $docComment = $prop->getDocComment(); if ($docComment !== false && preg_match('/@Relational\\\isNotColumn/', $docComment)) { continue; } + $cols[$prop->name] = $prop->getValue($object); } return $cols; } - - public function getFilters(Collection $collection): mixed - { - return $collection->getExtra('filters'); - } - public function getMixins(Collection $collection): mixed - { - return $collection->getExtra('mixins'); - } - public function getType(Collection $collection): mixed - { - return $collection->getExtra('type'); - } - public function mixable(Collection $collection): bool - { - return $collection->have('mixins'); - } - public function typable(Collection $collection): bool - { - return $collection->have('type'); - } - public function filterable(Collection $collection): bool - { - return $collection->have('filters'); - } } diff --git a/src/Sql.php b/src/Sql.php index 5a801e0..b211b79 100644 --- a/src/Sql.php +++ b/src/Sql.php @@ -4,47 +4,49 @@ namespace Respect\Relational; +use function array_merge; +use function array_shift; +use function array_walk_recursive; +use function implode; +use function in_array; +use function is_int; +use function is_numeric; +use function preg_match; +use function preg_replace; +use function rtrim; +use function sprintf; +use function stripos; +use function strtoupper; +use function substr; +use function trim; + class Sql { - const SQL_OPERATORS = '/\s?(NOT)?\s?(=|==|<>|!=|>|>=|<|<=|LIKE)\s?$/'; - const PLACEHOLDER = '?'; + public const string SQL_OPERATORS = '/\s?(NOT)?\s?(=|==|<>|!=|>|>=|<|<=|LIKE)\s?$/'; + public const string PLACEHOLDER = '?'; protected string $query = ''; + + /** @var array */ protected array $params = []; - public static function __callStatic(string $operation, array $parts): static + public function __construct(string $rawSql = '', array|null $params = null) { - $sql = new static(); - - return $sql->$operation(...$parts); + $this->setQuery($rawSql, $params); } public static function enclose(mixed $sql): mixed { if ($sql instanceof self) { - $sql->query = '('.trim($sql->query).') '; + $sql->query = '(' . trim($sql->query) . ') '; } elseif ($sql != '') { - $sql = '('.trim($sql).') '; + $sql = '(' . trim($sql) . ') '; } return $sql; } - public function __call(string $operation, array $parts): static - { - return $this->preBuild($operation, $parts); - } - - public function __construct(string $rawSql = '', array|null $params = null) - { - $this->setQuery($rawSql, $params); - } - - public function __toString(): string - { - return rtrim($this->query); - } - + /** @return array */ public function getParams(): array { return $this->params; @@ -62,10 +64,11 @@ public function setQuery(string $rawSql, array|null $params = null): static public function appendQuery(mixed $sql, array|null $params = null): static { - $this->query = trim($this->query)." $sql"; + $this->query = trim($this->query) . ' ' . $sql; if ($sql instanceof self) { $this->params = array_merge($this->params, $sql->getParams()); } + if ($params !== null) { $this->params = array_merge($this->params, $params); } @@ -73,6 +76,7 @@ public function appendQuery(mixed $sql, array|null $params = null): static return $this; } + /** @param array $parts */ protected function preBuild(string $operation, array $parts): static { $raw = ($operation == 'select' || $operation == 'on'); @@ -80,6 +84,7 @@ protected function preBuild(string $operation, array $parts): static if (empty($parts) && !in_array($operation, ['asc', 'desc', '_'], true)) { return $this; } + if ($operation == 'cond') { // condition list return $this->build('and', $parts); @@ -91,6 +96,7 @@ protected function preBuild(string $operation, array $parts): static return $this->build($operation, $parts); } + /** @param array $parts */ protected function build(string $operation, array $parts): static { return match ($operation) { @@ -106,32 +112,18 @@ protected function build(string $operation, array $parts): static }; } - private function buildAlterTable(array $parts): static - { - $this->buildFirstPart($parts); - - return $this->buildParts($parts, '%s '); - } - - private function buildCreate(array $parts): static - { - $this->params = []; - $this->buildFirstPart($parts); - - return $this->buildParts($parts, '(%s) '); - } - + /** @param array $parts */ protected function buildKeyValues(array $parts, string $format = '%s ', string $partSeparator = ', '): static { foreach ($parts as $key => $part) { if (is_numeric($key)) { - $parts[$key] = "$part"; + $parts[$key] = (string) $part; } else { - $value = ($part instanceof self) ? "$part" : static::PLACEHOLDER; - if (preg_match(static::SQL_OPERATORS, $key) > 0) { - $parts[$key] = "$key $value"; + $value = $part instanceof self ? (string) $part : self::PLACEHOLDER; + if (preg_match(self::SQL_OPERATORS, $key) > 0) { + $parts[$key] = $key . ' ' . $value; } else { - $parts[$key] = "$key = $value"; + $parts[$key] = $key . ' = ' . $value; } } } @@ -139,39 +131,42 @@ protected function buildKeyValues(array $parts, string $format = '%s ', string $ return $this->buildParts($parts, $format, $partSeparator); } + /** @param array $parts */ protected function buildComparators(array $parts, string $format = '%s ', string $partSeparator = ', '): static { foreach ($parts as $key => $part) { if (is_numeric($key)) { - $parts[$key] = "$part"; + $parts[$key] = (string) $part; } else { - $parts[$key] = "$key = $part"; + $parts[$key] = $key . ' = ' . $part; } } return $this->buildParts($parts, $format, $partSeparator); } + /** @param array $parts */ protected function buildAliases(array $parts, string $format = '%s ', string $partSeparator = ', '): static { foreach ($parts as $key => $part) { if (is_numeric($key)) { - $parts[$key] = "$part"; + $parts[$key] = (string) $part; } else { - $parts[$key] = "$part AS $key"; + $parts[$key] = $part . ' AS ' . $key; } } return $this->buildParts($parts, $format, $partSeparator); } + /** @param array $parts */ protected function buildValuesList(array $parts): static { foreach ($parts as $key => $part) { if (is_numeric($key) || $part instanceof self) { - $parts[$key] = "$part"; + $parts[$key] = (string) $part; } else { - $parts[$key] = static::PLACEHOLDER; + $parts[$key] = self::PLACEHOLDER; } } @@ -182,21 +177,23 @@ protected function buildOperation(string $operation): void { $command = strtoupper(preg_replace('/[A-Z0-9]+/', ' $0', $operation)); if ($command == '_') { - $this->query = rtrim($this->query).') '; + $this->query = rtrim($this->query) . ') '; } elseif ($command[0] == '_') { - $this->query .= '('.trim($command, '_ ').' '; + $this->query .= '(' . trim($command, '_ ') . ' '; } elseif (substr($command, -1) == '_') { - $this->query .= trim($command, '_ ').' ('; + $this->query .= trim($command, '_ ') . ' ('; } else { - $this->query .= trim($command).' '; + $this->query .= trim($command) . ' '; } } + /** @param array $parts */ protected function buildFirstPart(array &$parts): void { - $this->query .= array_shift($parts).' '; + $this->query .= array_shift($parts) . ' '; } + /** @param array $parts */ protected function buildParts(array $parts, string $format = '%s ', string $partSeparator = ', '): static { if (!empty($parts)) { @@ -206,29 +203,70 @@ protected function buildParts(array $parts, string $format = '%s ', string $part return $this; } + /** + * @param array $parts + * + * @return array + */ protected function normalizeParts(array $parts, bool $raw = false): array { $params = & $this->params; $newParts = []; - array_walk_recursive($parts, function ($value, $key) use (&$newParts, &$params, &$raw) { - if ($value instanceof Sql) { - $params = array_merge($params, $value->getParams()); - if (0 !== stripos((string) $value, '(')) { - $value = Sql::enclose($value); - } - $newParts[$key] = $value; - } elseif ($raw) { - $newParts[$key] = $value; - } elseif (is_int($key)) { - $newParts[] = $value; - } else { - $newParts[$key] = $key; - $params[] = $value; + array_walk_recursive($parts, static function ($value, $key) use (&$newParts, &$params, &$raw): void { + if ($value instanceof Sql) { + $params = array_merge($params, $value->getParams()); + if (stripos((string) $value, '(') !== 0) { + $value = Sql::enclose($value); } + + $newParts[$key] = $value; + } elseif ($raw) { + $newParts[$key] = $value; + } elseif (is_int($key)) { + $newParts[] = $value; + } else { + $newParts[$key] = $key; + $params[] = $value; } - ); + }); return $newParts; } + + /** @param array $parts */ + private function buildAlterTable(array $parts): static + { + $this->buildFirstPart($parts); + + return $this->buildParts($parts, '%s '); + } + + /** @param array $parts */ + private function buildCreate(array $parts): static + { + $this->params = []; + $this->buildFirstPart($parts); + + return $this->buildParts($parts, '(%s) '); + } + + /** @param array $parts */ + public static function __callStatic(string $operation, array $parts): static + { + $sql = new static(); + + return $sql->$operation(...$parts); + } + + /** @param array $parts */ + public function __call(string $operation, array $parts): static + { + return $this->preBuild($operation, $parts); + } + + public function __toString(): string + { + return rtrim($this->query); + } } diff --git a/tests/DbTest.php b/tests/DbTest.php index 399b620..cf2dfe8 100644 --- a/tests/DbTest.php +++ b/tests/DbTest.php @@ -4,21 +4,26 @@ namespace Respect\Relational; +use PDO; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\TestCase; +use function count; +use function in_array; +use function is_array; + #[CoversClass(Db::class)] class DbTest extends TestCase { - protected $object; protected function setUp(): void { - if (!in_array('sqlite', \PDO::getAvailableDrivers())) { + if (!in_array('sqlite', PDO::getAvailableDrivers())) { $this->markTestSkipped('PDO_SQLITE is not available'); } - $db = new \PDO('sqlite::memory:'); + + $db = new PDO('sqlite::memory:'); $db->query('CREATE TABLE unit (testez INTEGER PRIMARY KEY AUTOINCREMENT, testa INT, testb VARCHAR(255))'); $db->query("INSERT INTO unit (testa, testb) VALUES (10, 'abc')"); $db->query("INSERT INTO unit (testa, testb) VALUES (20, 'def')"); @@ -26,22 +31,17 @@ protected function setUp(): void $this->object = new Db($db); } - protected function tearDown(): void - { - unset($this->object); - } - public function testBasicStatement(): void { $this->assertEquals( 'unit', - $this->object->select('*')->from('sqlite_master')->fetch()->tbl_name + $this->object->select('*')->from('sqlite_master')->fetch()->tbl_name, ); } public function testPassingValues(): void { - $line = $this->object->select('*')->from('unit')->where(array('testb' => 'abc'))->fetch(); + $line = $this->object->select('*')->from('unit')->where(['testb' => 'abc'])->fetch(); $this->assertEquals(10, $line->testa); } @@ -59,8 +59,10 @@ public function testFetchingClass(): void public function testFetchingClassArgs(): void { - $line = $this->object->select('*')->from('unit')->fetch('Respect\Relational\testFetchingClassArgs', - array('foo')); + $line = $this->object->select('*')->from('unit')->fetch( + 'Respect\Relational\testFetchingClassArgs', + ['foo'], + ); $this->assertInstanceOF('Respect\Relational\testFetchingClassArgs', $line); $this->assertEquals('foo', $line->testd); } @@ -68,18 +70,19 @@ public function testFetchingClassArgs(): void public function testFetchingCallback(): void { $line = $this->object->select('*')->from('unit')->fetch( - function($row) { - $row->acid = 'test'; - return $row; - } + static function ($row) { + $row->acid = 'test'; + + return $row; + }, ); $this->assertEquals('test', $line->acid); } public function testFetchingInto(): void { - $x = new testFetchingInto; - $line = $this->object->select('*')->from('unit')->where(array('testb' => 'abc'))->fetch($x); + $x = new testFetchingInto(); + $this->object->select('*')->from('unit')->where(['testb' => 'abc'])->fetch($x); $this->assertEquals('abc', $x->testb); } @@ -91,28 +94,33 @@ public function testRawSql(): void public function testFetchingArray(): void { - $line = $this->object->select('*')->from('unit')->where(array('testb' => 'abc'))->fetch(\PDO::FETCH_ASSOC); + $line = $this->object->select('*')->from('unit')->where(['testb' => 'abc'])->fetch(PDO::FETCH_ASSOC); $this->assertTrue(is_array($line)); } public function testFetchingArray2(): void { - $line = $this->object->select('*')->from('unit')->where(array('testb' => 'abc'))->fetch(array()); + $line = $this->object->select('*')->from('unit')->where(['testb' => 'abc'])->fetch([]); $this->assertTrue(is_array($line)); } public function testGetSql(): void { - $sql = $this->object->select('*')->from('unit')->where(array('testb' => 'abc'))->getSql(); + $sql = $this->object->select('*')->from('unit')->where(['testb' => 'abc'])->getSql(); $this->assertEquals('SELECT * FROM unit WHERE testb = ?', (string) $sql); - $this->assertEquals(array('abc'), $sql->getParams()); + $this->assertEquals(['abc'], $sql->getParams()); } public function testRawSqlWithParams(): void { - $line = $this->object->query('SELECT * FROM unit WHERE testb = ?', array('abc'))->fetch(); + $line = $this->object->query('SELECT * FROM unit WHERE testb = ?', ['abc'])->fetch(); $this->assertEquals(10, $line->testa); } + + protected function tearDown(): void + { + unset($this->object); + } } class testFetchingClass @@ -127,11 +135,7 @@ class testFetchingInto class testFetchingClassArgs { - public $testd, $testa, $testb, $testez; - - public function __construct($testd) + public function __construct(public $testd) { - $this->testd = $testd; } - } diff --git a/tests/MapperTest.php b/tests/MapperTest.php index 3946120..fea367f 100644 --- a/tests/MapperTest.php +++ b/tests/MapperTest.php @@ -4,130 +4,153 @@ namespace Respect\Relational; +use Datetime; +use DomainException; +use Exception; use PDO; +use PDOException; +use PDOStatement; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\TestCase; use Respect\Data\Collections\Filtered; use Respect\Data\Collections\Mix; use Respect\Data\Collections\Typed; use Respect\Data\Styles; +use stdClass; +use Throwable; +use TypeError; + +use function array_reverse; +use function count; +use function current; +use function date; +use function end; +use function get_object_vars; +use function reset; #[CoversClass(Mapper::class)] -class MapperTest extends TestCase { - +class MapperTest extends TestCase +{ protected $conn, $mapper, $posts, $authors, $comments, $categories, $postsCategories, $issues; - protected function setUp(): void { + protected function setUp(): void + { $conn = new PDO('sqlite::memory:'); $db = new Db($conn); - $conn->exec((string) Sql::createTable('post', array( - 'id INTEGER PRIMARY KEY', - 'title VARCHAR(255)', - 'text TEXT', - 'author_id INTEGER' - ))); - $conn->exec((string) Sql::createTable('author', array( - 'id INTEGER PRIMARY KEY', - 'name VARCHAR(255)' - ))); - $conn->exec((string) Sql::createTable('comment', array( - 'id INTEGER PRIMARY KEY', - 'post_id INTEGER', - 'text TEXT', - 'datetime DATETIME' - ))); - $conn->exec((string) Sql::createTable('category', array( - 'id INTEGER PRIMARY KEY', - 'name VARCHAR(255)', - 'category_id INTEGER' - ))); - $conn->exec((string) Sql::createTable('post_category', array( - 'id INTEGER PRIMARY KEY', - 'post_id INTEGER', - 'category_id INTEGER' - ))); - $conn->exec((string) Sql::createTable('issues', array( - 'id INTEGER PRIMARY KEY', - 'type VARCHAR(255)', - 'title VARCHAR(22)' - ))); - $this->posts = array( - (object) array( + $conn->exec((string) Sql::createTable('post', [ + 'id INTEGER PRIMARY KEY', + 'title VARCHAR(255)', + 'text TEXT', + 'author_id INTEGER', + ])); + $conn->exec((string) Sql::createTable('author', [ + 'id INTEGER PRIMARY KEY', + 'name VARCHAR(255)', + ])); + $conn->exec((string) Sql::createTable('comment', [ + 'id INTEGER PRIMARY KEY', + 'post_id INTEGER', + 'text TEXT', + 'datetime DATETIME', + ])); + $conn->exec((string) Sql::createTable('category', [ + 'id INTEGER PRIMARY KEY', + 'name VARCHAR(255)', + 'category_id INTEGER', + ])); + $conn->exec((string) Sql::createTable('post_category', [ + 'id INTEGER PRIMARY KEY', + 'post_id INTEGER', + 'category_id INTEGER', + ])); + $conn->exec((string) Sql::createTable('issues', [ + 'id INTEGER PRIMARY KEY', + 'type VARCHAR(255)', + 'title VARCHAR(22)', + ])); + $this->posts = [ + (object) [ 'id' => 5, 'title' => 'Post Title', 'text' => 'Post Text', - 'author_id' => 1 - ) - ); - $this->authors = array( - (object) array( + 'author_id' => 1, + ], + ]; + $this->authors = [ + (object) [ 'id' => 1, - 'name' => 'Author 1' - ) - ); - $this->comments = array( - (object) array( + 'name' => 'Author 1', + ], + ]; + $this->comments = [ + (object) [ 'id' => 7, 'post_id' => 5, 'text' => 'Comment Text', - 'datetime' => '2012-06-19 00:35:42' - ), - (object) array( + 'datetime' => '2012-06-19 00:35:42', + ], + (object) [ 'id' => 8, 'post_id' => 4, 'text' => 'Comment Text 2', - 'datetime' => '2012-06-19 00:35:42' - ) - ); - $this->categories = array( - (object) array( + 'datetime' => '2012-06-19 00:35:42', + ], + ]; + $this->categories = [ + (object) [ 'id' => 2, 'name' => 'Sample Category', - 'category_id' => null - ), - (object) array( + 'category_id' => null, + ], + (object) [ 'id' => 3, 'name' => 'NONON', - 'category_id' => null - ) - ); - $this->postsCategories = array( - (object) array( + 'category_id' => null, + ], + ]; + $this->postsCategories = [ + (object) [ 'id' => 66, 'post_id' => 5, - 'category_id' => 2 - ) - ); - $this->issues = array( - (object) array( + 'category_id' => 2, + ], + ]; + $this->issues = [ + (object) [ 'id' => 1, 'type' => 'bug', - 'title' => 'Bug 1' - ), - (object) array( + 'title' => 'Bug 1', + ], + (object) [ 'id' => 2, 'type' => 'improvement', - 'title' => 'Improvement 1' - ) - ); + 'title' => 'Improvement 1', + ], + ]; - foreach ($this->authors as $author) + foreach ($this->authors as $author) { $db->insertInto('author', (array) $author)->values((array) $author)->exec(); + } - foreach ($this->posts as $post) + foreach ($this->posts as $post) { $db->insertInto('post', (array) $post)->values((array) $post)->exec(); + } - foreach ($this->comments as $comment) + foreach ($this->comments as $comment) { $db->insertInto('comment', (array) $comment)->values((array) $comment)->exec(); + } - foreach ($this->categories as $category) + foreach ($this->categories as $category) { $db->insertInto('category', (array) $category)->values((array) $category)->exec(); + } - foreach ($this->postsCategories as $postCategory) + foreach ($this->postsCategories as $postCategory) { $db->insertInto('post_category', (array) $postCategory)->values((array) $postCategory)->exec(); + } - foreach ($this->issues as $issue) + foreach ($this->issues as $issue) { $db->insertInto('issues', (array) $issue)->values((array) $issue)->exec(); + } $mapper = new Mapper($conn); $this->mapper = $mapper; @@ -151,25 +174,25 @@ public function test_get_defined_db_instance(): void public function test_creating_with_invalid_args_should_throw_exception(): void { - $this->expectException(\TypeError::class); - $mapper = new Mapper('foo'); + $this->expectException(TypeError::class); + new Mapper('foo'); } public function test_rolling_back_transaction(): void { $conn = $this->createMock(PDO::class); $conn->expects($this->any()) - ->method('prepare') - ->will($this->throwException(new \Exception)); + ->method('prepare') + ->will($this->throwException(new Exception())); $conn->expects($this->once()) - ->method('rollback'); + ->method('rollback'); $mapper = new Mapper($conn); - $obj = new \stdClass(); + $obj = new stdClass(); $obj->id = null; $mapper->foo->persist($obj); try { $mapper->flush(); - } catch (\Exception $e) { + } catch (Throwable) { //OK! } } @@ -178,20 +201,20 @@ public function test_ignoring_last_insert_id_errors(): void { $conn = $this->createStub(PDO::class); $conn->method('getAttribute') - ->willReturn('sqlite'); - $stmt = $this->createStub(\PDOStatement::class); + ->willReturn('sqlite'); + $stmt = $this->createStub(PDOStatement::class); $stmt->method('execute') - ->willReturn(true); + ->willReturn(true); $conn->method('prepare') - ->willReturn($stmt); + ->willReturn($stmt); $conn->method('lastInsertId') - ->willThrowException(new \PDOException()); + ->willThrowException(new PDOException()); $conn->method('beginTransaction') - ->willReturn(true); + ->willReturn(true); $conn->method('commit') - ->willReturn(true); + ->willReturn(true); $mapper = new Mapper($conn); - $obj = new \stdClass(); + $obj = new stdClass(); $obj->id = null; $obj->name = 'bar'; $mapper->foo->persist($obj); @@ -202,7 +225,7 @@ public function test_ignoring_last_insert_id_errors(): void public function test_removing_untracked_object(): void { - $comment = new \stdClass(); + $comment = new stdClass(); $comment->id = 7; $this->assertNotEmpty($this->mapper->comment[7]->fetch()); $this->mapper->comment->remove($comment); @@ -230,6 +253,7 @@ public function test_extra_sql_on_single_fetch_should_be_applied_on_mapper_sql() $fetchedLast = $this->mapper->comment->fetch(Sql::orderBy('id DESC')); $this->assertEquals($expectedLast, $fetchedLast); } + public function test_extra_sql_on_fetchAll_should_be_applied_on_mapper_sql(): void { $expectedComments = array_reverse($this->comments); @@ -237,7 +261,8 @@ public function test_extra_sql_on_fetchAll_should_be_applied_on_mapper_sql(): vo $this->assertEquals($expectedComments, $fetchedComments); } - public function test_nested_collections_should_hydrate_results(): void { + public function test_nested_collections_should_hydrate_results(): void + { $mapper = $this->mapper; $comment = $mapper->comment->post[5]->fetch(); $this->assertEquals(7, $comment->id); @@ -249,7 +274,8 @@ public function test_nested_collections_should_hydrate_results(): void { $this->assertEquals(4, count(get_object_vars($comment->post_id))); } - public function testOneToN(): void { + public function testOneToN(): void + { $mapper = $this->mapper; $comments = $mapper->comment->post($mapper->author)->fetchAll(); $comment = current($comments); @@ -266,7 +292,8 @@ public function testOneToN(): void { $this->assertEquals(2, count(get_object_vars($comment->post_id->author_id))); } - public function testNtoN(): void { + public function testNtoN(): void + { $mapper = $this->mapper; $comments = $mapper->comment->post->post_category->category[2]->fetchAll(); $comment = current($comments); @@ -280,40 +307,45 @@ public function testNtoN(): void { $this->assertEquals(4, count(get_object_vars($comment->post_id))); } - public function testNtoNReverse(): void { + public function testNtoNReverse(): void + { $mapper = $this->mapper; $cat = $mapper->category->post_category->post[5]->fetch(); $this->assertEquals(2, $cat->id); $this->assertEquals('Sample Category', $cat->name); } - public function testSimplePersist(): void { + public function testSimplePersist(): void + { $mapper = $this->mapper; - $entity = (object) array('id' => 4, 'name' => 'inserted', 'category_id' => null); + $entity = (object) ['id' => 4, 'name' => 'inserted', 'category_id' => null]; $mapper->category->persist($entity); $mapper->flush(); $result = $this->conn->query('select * from category where id=4')->fetch(PDO::FETCH_OBJ); $this->assertEquals($entity, $result); } - public function testSimplePersistCollection(): void { + + public function testSimplePersistCollection(): void + { $mapper = $this->mapper; - $entity = (object) array('id' => 4, 'name' => 'inserted', 'category_id' => null); + $entity = (object) ['id' => 4, 'name' => 'inserted', 'category_id' => null]; $mapper->category->persist($entity); $mapper->flush(); $result = $this->conn->query('select * from category where id=4')->fetch(PDO::FETCH_OBJ); $this->assertEquals($entity, $result); } - public function testNestedPersistCollection(): void { - $postWithAuthor = (object) array( + public function testNestedPersistCollection(): void + { + $postWithAuthor = (object) [ 'id' => null, 'title' => 'hi', 'text' => 'hi text', - 'author_id' => (object) array( + 'author_id' => (object) [ 'id' => null, - 'name' => 'New' - ) - ); + 'name' => 'New', + ], + ]; $this->mapper->post->author->persist($postWithAuthor); $this->mapper->flush(); $author = $this->conn->query('select * from author order by id desc limit 1')->fetch(PDO::FETCH_OBJ); @@ -321,16 +353,18 @@ public function testNestedPersistCollection(): void { $this->assertEquals('New', $author->name); $this->assertEquals('hi', $post->title); } - public function testNestedPersistCollectionShortcut(): void { - $postWithAuthor = (object) array( + + public function testNestedPersistCollectionShortcut(): void + { + $postWithAuthor = (object) [ 'id' => null, 'title' => 'hi', 'text' => 'hi text', - 'author_id' => (object) array( + 'author_id' => (object) [ 'id' => null, - 'name' => 'New' - ) - ); + 'name' => 'New', + ], + ]; $this->mapper->postAuthor = $this->mapper->post->author; $this->mapper->postAuthor->persist($postWithAuthor); $this->mapper->flush(); @@ -340,16 +374,17 @@ public function testNestedPersistCollectionShortcut(): void { $this->assertEquals('hi', $post->title); } - public function testNestedPersistCollectionWithChildrenShortcut(): void { - $postWithAuthor = (object) array( + public function testNestedPersistCollectionWithChildrenShortcut(): void + { + $postWithAuthor = (object) [ 'id' => null, 'title' => 'hi', 'text' => 'hi text', - 'author_id' => (object) array( + 'author_id' => (object) [ 'id' => null, - 'name' => 'New' - ) - ); + 'name' => 'New', + ], + ]; $this->mapper->postAuthor = $this->mapper->post($this->mapper->author); $this->mapper->postAuthor->persist($postWithAuthor); $this->mapper->flush(); @@ -359,9 +394,10 @@ public function testNestedPersistCollectionWithChildrenShortcut(): void { $this->assertEquals('hi', $post->title); } - public function testSubCategory(): void { + public function testSubCategory(): void + { $mapper = $this->mapper; - $entity = (object) array('id' => 8, 'name' => 'inserted', 'category_id' => 2); + $entity = (object) ['id' => 8, 'name' => 'inserted', 'category_id' => 2]; $mapper->category->persist($entity); $mapper->flush(); $result = $this->conn->query('select * from category where id=8')->fetch(PDO::FETCH_OBJ); @@ -370,21 +406,24 @@ public function testSubCategory(): void { $this->assertEquals($result->name, $result2->name); $this->assertEquals($entity, $result); } - public function testSubCategoryCondition(): void { + + public function testSubCategoryCondition(): void + { $mapper = $this->mapper; - $entity = (object) array('id' => 8, 'name' => 'inserted', 'category_id' => 2); + $entity = (object) ['id' => 8, 'name' => 'inserted', 'category_id' => 2]; $mapper->category->persist($entity); $mapper->flush(); $result = $this->conn->query('select * from category where id=8')->fetch(PDO::FETCH_OBJ); - $result2 = $mapper->category(array("id"=>8))->category->fetch(); + $result2 = $mapper->category(['id' => 8])->category->fetch(); $this->assertEquals($result->id, $result2->id); $this->assertEquals($result->name, $result2->name); $this->assertEquals($entity, $result); } - public function testAutoIncrementPersist(): void { + public function testAutoIncrementPersist(): void + { $mapper = $this->mapper; - $entity = (object) array('id' => null, 'name' => 'inserted', 'category_id' => null); + $entity = (object) ['id' => null, 'name' => 'inserted', 'category_id' => null]; $mapper->category->persist($entity); $mapper->flush(); $result = $this->conn->query('select * from category where name="inserted"')->fetch(PDO::FETCH_OBJ); @@ -392,15 +431,16 @@ public function testAutoIncrementPersist(): void { $this->assertEquals(4, $result->id); } - public function testPassedIdentity(): void { + public function testPassedIdentity(): void + { $mapper = $this->mapper; - $post = new \stdClass(); + $post = new stdClass(); $post->id = null; $post->title = 12345; $post->text = 'text abc'; - $comment = new \stdClass(); + $comment = new stdClass(); $comment->id = null; $comment->post_id = $post; $comment->text = 'abc'; @@ -410,16 +450,17 @@ public function testPassedIdentity(): void { $mapper->flush(); $postId = $this->conn - ->query('select id from post where title = 12345') - ->fetchColumn(0); + ->query('select id from post where title = 12345') + ->fetchColumn(0); $comment = $this->conn->query('select * from comment where post_id = ' . $postId) - ->fetchObject(); + ->fetchObject(); $this->assertEquals('abc', $comment->text); } - public function testJoinedPersist(): void { + public function testJoinedPersist(): void + { $mapper = $this->mapper; $entity = $mapper->comment[8]->fetch(); $entity->text = 'HeyHey'; @@ -429,8 +470,8 @@ public function testJoinedPersist(): void { $this->assertEquals('HeyHey', $result); } - - public function testRemove(): void { + public function testRemove(): void + { $mapper = $this->mapper; $c8 = $mapper->comment[8]->fetch(); $pre = $this->conn->query('select count(*) from comment')->fetchColumn(0); @@ -495,8 +536,8 @@ public function test_setters_and_getters_datetime_as_object(): void $mapper->entityNamespace = '\Respect\Relational\\'; $post = new Post(); $post->id = 44; - $post->text = "Test using datetime setters"; - $post->setDatetime(new \Datetime('now')); + $post->text = 'Test using datetime setters'; + $post->setDatetime(new Datetime('now')); $mapper->post->persist($post); $mapper->flush(); @@ -509,26 +550,28 @@ public function test_style(): void { $this->assertInstanceOf('Respect\Data\Styles\Stylable', $this->mapper->getStyle()); $this->assertInstanceOf('Respect\Data\Styles\Standard', $this->mapper->getStyle()); - $styles = array( + $styles = [ new Styles\CakePHP(), new Styles\NorthWind(), new Styles\Sakila(), new Styles\Standard(), - ); + ]; foreach ($styles as $style) { $this->mapper->setStyle($style); $this->assertEquals($style, $this->mapper->getStyle()); } } - public function test_feching_a_single_filtered_collection_should_not_bring_filtered_children(): void { + public function test_feching_a_single_filtered_collection_should_not_bring_filtered_children(): void + { $mapper = $this->mapper; $mapper->authorsWithPosts = Filtered::post()->author(); $author = $mapper->authorsWithPosts->fetch(); $this->assertEquals($this->authors[0], $author); } - public function test_persisting_a_previously_fetched_filtered_entity_back_into_its_collection(): void { + public function test_persisting_a_previously_fetched_filtered_entity_back_into_its_collection(): void + { $mapper = $this->mapper; $mapper->authorsWithPosts = Filtered::post()->author(); $author = $mapper->authorsWithPosts->fetch(); @@ -539,7 +582,8 @@ public function test_persisting_a_previously_fetched_filtered_entity_back_into_i $this->assertEquals('Author Changed', $result->name); } - public function test_persisting_a_previously_fetched_filtered_entity_back_into_a_foreign_compatible_collection(): void { + public function test_persisting_a_previously_fetched_filtered_entity_back_into_a_foreign_compatible_collection(): void + { $mapper = $this->mapper; $mapper->authorsWithPosts = Filtered::post()->author(); $author = $mapper->authorsWithPosts->fetch(); @@ -550,10 +594,11 @@ public function test_persisting_a_previously_fetched_filtered_entity_back_into_a $this->assertEquals('Author Changed', $result->name); } - public function test_persisting_a_newly_created_filtered_entity_into_its_collection(): void { + public function test_persisting_a_newly_created_filtered_entity_into_its_collection(): void + { $mapper = $this->mapper; $mapper->authorsWithPosts = Filtered::post()->author(); - $author = new \stdClass; + $author = new stdClass(); $author->id = null; $author->name = 'Author Changed'; $mapper->authorsWithPosts->persist($author); @@ -562,10 +607,11 @@ public function test_persisting_a_newly_created_filtered_entity_into_its_collect $this->assertEquals('Author Changed', $result->name); } - public function test_persisting_a_newly_created_filtered_entity_into_a_foreig_compatible_collection(): void { + public function test_persisting_a_newly_created_filtered_entity_into_a_foreig_compatible_collection(): void + { $mapper = $this->mapper; $mapper->authorsWithPosts = Filtered::post()->author(); - $author = new \stdClass; + $author = new stdClass(); $author->id = null; $author->name = 'Author Changed'; $mapper->author->persist($author); @@ -574,26 +620,29 @@ public function test_persisting_a_newly_created_filtered_entity_into_a_foreig_co $this->assertEquals('Author Changed', $result->name); } - public function test_feching_multiple_filtered_collections_should_not_bring_filtered_children(): void { + public function test_feching_multiple_filtered_collections_should_not_bring_filtered_children(): void + { $mapper = $this->mapper; $mapper->authorsWithPosts = Filtered::post()->author(); $authors = $mapper->authorsWithPosts->fetchAll(); $this->assertEquals($this->authors, $authors); } - public function test_filtered_collections_should_hydrate_non_filtered_parts_as_usual(): void { + public function test_filtered_collections_should_hydrate_non_filtered_parts_as_usual(): void + { $mapper = $this->mapper; $mapper->postsFromAuthorsWithComments = Filtered::comment()->post()->author(); $post = $mapper->postsFromAuthorsWithComments->fetch(); - $this->assertEquals((object) (array('author_id' => $post->author_id) + (array) $this->posts[0]), $post); + $this->assertEquals((object) (['author_id' => $post->author_id] + (array) $this->posts[0]), $post); $this->assertEquals($this->authors[0], $post->author_id); } - public function test_filtered_collections_should_persist_hydrated_non_filtered_parts_as_usual(): void { + public function test_filtered_collections_should_persist_hydrated_non_filtered_parts_as_usual(): void + { $mapper = $this->mapper; $mapper->postsFromAuthorsWithComments = Filtered::comment()->post()->author(); $post = $mapper->postsFromAuthorsWithComments->fetch(); - $this->assertEquals((object) (array('author_id' => $post->author_id) + (array) $this->posts[0]), $post); + $this->assertEquals((object) (['author_id' => $post->author_id] + (array) $this->posts[0]), $post); $this->assertEquals($this->authors[0], $post->author_id); $post->title = 'Title Changed'; $post->author_id->name = 'John'; @@ -605,11 +654,12 @@ public function test_filtered_collections_should_persist_hydrated_non_filtered_p $this->assertEquals('John', $result->name); } - public function test_multiple_filtered_collections_dont_persist(): void { + public function test_multiple_filtered_collections_dont_persist(): void + { $mapper = $this->mapper; $mapper->authorsWithPosts = Filtered::comment()->post->stack(Filtered::author()); $post = $mapper->authorsWithPosts->fetch(); - $this->assertEquals((object) array('id' => '5', 'author_id' => 1, 'text' => 'Post Text', 'title' => 'Post Title'), $post); + $this->assertEquals((object) ['id' => '5', 'author_id' => 1, 'text' => 'Post Text', 'title' => 'Post Title'], $post); $post->title = 'Title Changed'; $post->author_id = $mapper->author[1]->fetch(); $post->author_id->name = 'A'; @@ -620,13 +670,15 @@ public function test_multiple_filtered_collections_dont_persist(): void { $result = $this->conn->query('select name from author where id=1')->fetch(PDO::FETCH_OBJ); $this->assertNotEquals('A', $result->name); } - public function test_multiple_filtered_collections_dont_persist_newly_create_objects(): void { + + public function test_multiple_filtered_collections_dont_persist_newly_create_objects(): void + { $mapper = $this->mapper; $mapper->authorsWithPosts = Filtered::comment()->post->stack(Filtered::author()); $post = $mapper->authorsWithPosts->fetch(); - $this->assertEquals((object) array('id' => '5', 'author_id' => 1, 'text' => 'Post Text', 'title' => 'Post Title'), $post); + $this->assertEquals((object) ['id' => '5', 'author_id' => 1, 'text' => 'Post Text', 'title' => 'Post Title'], $post); $post->title = 'Title Changed'; - $post->author_id = new \stdClass; + $post->author_id = new stdClass(); $post->author_id->id = null; $post->author_id->name = 'A'; $mapper->postsFromAuthorsWithComments->persist($post); @@ -637,12 +689,13 @@ public function test_multiple_filtered_collections_dont_persist_newly_create_obj $this->assertNotEquals('A', $result->name); } - public function test_multiple_filtered_collections_fetch_at_once_dont_persist(): void { + public function test_multiple_filtered_collections_fetch_at_once_dont_persist(): void + { $mapper = $this->mapper; $mapper->authorsWithPosts = Filtered::comment()->post->stack(Filtered::author()); $post = $mapper->authorsWithPosts->fetchAll(); $post = $post[0]; - $this->assertEquals((object) array('id' => '5', 'author_id' => 1, 'text' => 'Post Text', 'title' => 'Post Title'), $post); + $this->assertEquals((object) ['id' => '5', 'author_id' => 1, 'text' => 'Post Text', 'title' => 'Post Title'], $post); $post->title = 'Title Changed'; $post->author_id = $mapper->author[1]->fetch(); $post->author_id->name = 'A'; @@ -654,104 +707,120 @@ public function test_multiple_filtered_collections_fetch_at_once_dont_persist(): $this->assertNotEquals('A', $result->name); } - public function test_reusing_registered_filtered_collections_keeps_their_filtering(): void { + public function test_reusing_registered_filtered_collections_keeps_their_filtering(): void + { $mapper = $this->mapper; $mapper->commentFil = Filtered::comment(); $mapper->author = Filtered::author(); $post = $mapper->commentFil->post->author->fetch(); - $this->assertEquals((object) array('id' => '5', 'author_id' => 1, 'text' => 'Post Text', 'title' => 'Post Title'), $post); + $this->assertEquals((object) ['id' => '5', 'author_id' => 1, 'text' => 'Post Text', 'title' => 'Post Title'], $post); $post->title = 'Title Changed'; $mapper->postsFromAuthorsWithComments->persist($post); $mapper->flush(); $result = $this->conn->query('select title from post where id=5')->fetch(PDO::FETCH_OBJ); $this->assertEquals('Title Changed', $result->title); } - public function test_reusing_registered_filtered_collections_keeps_their_filtering_on_fetchAll(): void { + + public function test_reusing_registered_filtered_collections_keeps_their_filtering_on_fetchAll(): void + { $mapper = $this->mapper; $mapper->commentFil = Filtered::comment(); $mapper->author = Filtered::author(); $post = $mapper->commentFil->post->author->fetchAll(); $post = $post[0]; - $this->assertEquals((object) array('id' => '5', 'author_id' => 1, 'text' => 'Post Text', 'title' => 'Post Title'), $post); + $this->assertEquals((object) ['id' => '5', 'author_id' => 1, 'text' => 'Post Text', 'title' => 'Post Title'], $post); $post->title = 'Title Changed'; $mapper->postsFromAuthorsWithComments->persist($post); $mapper->flush(); $result = $this->conn->query('select title from post where id=5')->fetch(PDO::FETCH_OBJ); $this->assertEquals('Title Changed', $result->title); } - public function test_registered_filtered_collections_by_column_keeps_their_filtering(): void { + + public function test_registered_filtered_collections_by_column_keeps_their_filtering(): void + { $mapper = $this->mapper; $mapper->post = Filtered::by('title')->post(); $post = $mapper->post->fetch(); - $this->assertEquals((object) array('id' => '5', 'title' => 'Post Title'), $post); + $this->assertEquals((object) ['id' => '5', 'title' => 'Post Title'], $post); $post->title = 'Title Changed'; $mapper->postsFromAuthorsWithComments->persist($post); $mapper->flush(); $result = $this->conn->query('select title from post where id=5')->fetch(PDO::FETCH_OBJ); $this->assertEquals('Title Changed', $result->title); } - public function test_registered_filtered_collections_by_column_keeps_their_filtering_on_fetchAll(): void { + + public function test_registered_filtered_collections_by_column_keeps_their_filtering_on_fetchAll(): void + { $mapper = $this->mapper; $mapper->post = Filtered::by('title')->post(); $post = $mapper->post->fetchAll(); $post = $post[0]; - $this->assertEquals((object) array('id' => '5', 'title' => 'Post Title'), $post); + $this->assertEquals((object) ['id' => '5', 'title' => 'Post Title'], $post); $post->title = 'Title Changed'; $mapper->postsFromAuthorsWithComments->persist($post); $mapper->flush(); $result = $this->conn->query('select title from post where id=5')->fetch(PDO::FETCH_OBJ); $this->assertEquals('Title Changed', $result->title); } - public function test_registered_filtered_wildcard_collections_keeps_their_filtering(): void { + + public function test_registered_filtered_wildcard_collections_keeps_their_filtering(): void + { $mapper = $this->mapper; $mapper->post = Filtered::by('*')->post(); $post = $mapper->post->fetch(); - $this->assertEquals((object) array('id' => '5'), $post); + $this->assertEquals((object) ['id' => '5'], $post); $post->title = 'Title Changed'; $mapper->postsFromAuthorsWithComments->persist($post); $mapper->flush(); $result = $this->conn->query('select title from post where id=5')->fetch(PDO::FETCH_OBJ); $this->assertEquals('Title Changed', $result->title); } - public function test_registered_filtered_wildcard_collections_keeps_their_filtering_on_fetchAll(): void { + + public function test_registered_filtered_wildcard_collections_keeps_their_filtering_on_fetchAll(): void + { $mapper = $this->mapper; $mapper->post = Filtered::by('*')->post(); $post = $mapper->post->fetchAll(); $post = $post[0]; - $this->assertEquals((object) array('id' => '5'), $post); + $this->assertEquals((object) ['id' => '5'], $post); $post->title = 'Title Changed'; $mapper->postsFromAuthorsWithComments->persist($post); $mapper->flush(); $result = $this->conn->query('select title from post where id=5')->fetch(PDO::FETCH_OBJ); $this->assertEquals('Title Changed', $result->title); } - public function test_fetching_registered_filtered_collections_alongside_normal(): void { + + public function test_fetching_registered_filtered_collections_alongside_normal(): void + { $mapper = $this->mapper; $mapper->post = Filtered::by('*')->post()->author(); $post = $mapper->post->fetchAll(); $post = $post[0]; - $this->assertEquals((object) array('id' => '5', 'author_id' => $post->author_id), $post); - $this->assertEquals((object) array('name' => 'Author 1', 'id' => 1), $post->author_id); + $this->assertEquals((object) ['id' => '5', 'author_id' => $post->author_id], $post); + $this->assertEquals((object) ['name' => 'Author 1', 'id' => 1], $post->author_id); $post->title = 'Title Changed'; $mapper->postsFromAuthorsWithComments->persist($post); $mapper->flush(); $result = $this->conn->query('select title from post where id=5')->fetch(PDO::FETCH_OBJ); $this->assertEquals('Title Changed', $result->title); } - public function test_mixins_bring_results_from_two_tables(): void { + + public function test_mixins_bring_results_from_two_tables(): void + { $mapper = $this->mapper; - $mapper->postComment = Mix::with(array('comment' => array('text')))->post()->author(); + $mapper->postComment = Mix::with(['comment' => ['text']])->post()->author(); $post = $mapper->postComment->fetch(); - $this->assertEquals((object) array('name' => 'Author 1', 'id' => 1), $post->author_id); - $this->assertEquals((object) array('id' => '5', 'author_id' => $post->author_id, 'text' => 'Comment Text', 'title' => 'Post Title', 'comment_id' => 7), $post); - + $this->assertEquals((object) ['name' => 'Author 1', 'id' => 1], $post->author_id); + $this->assertEquals((object) ['id' => '5', 'author_id' => $post->author_id, 'text' => 'Comment Text', 'title' => 'Post Title', 'comment_id' => 7], $post); } - public function test_mixins_persists_results_on_two_tables(): void { + + public function test_mixins_persists_results_on_two_tables(): void + { $mapper = $this->mapper; - $mapper->postComment = Mix::with(array('comment' => array('text')))->post()->author(); + $mapper->postComment = Mix::with(['comment' => ['text']])->post()->author(); $post = $mapper->postComment->fetch(); - $this->assertEquals((object) array('name' => 'Author 1', 'id' => 1), $post->author_id); - $this->assertEquals((object) array('id' => '5', 'author_id' => $post->author_id, 'text' => 'Comment Text', 'title' => 'Post Title', 'comment_id' => 7), $post); + $this->assertEquals((object) ['name' => 'Author 1', 'id' => 1], $post->author_id); + $this->assertEquals((object) ['id' => '5', 'author_id' => $post->author_id, 'text' => 'Comment Text', 'title' => 'Post Title', 'comment_id' => 7], $post); $post->title = 'Title Changed'; $post->text = 'Comment Changed'; $mapper->postsFromAuthorsWithComments->persist($post); @@ -760,13 +829,14 @@ public function test_mixins_persists_results_on_two_tables(): void { $this->assertEquals('Title Changed', $result->title); $result = $this->conn->query('select text from comment where id=7')->fetch(PDO::FETCH_OBJ); $this->assertEquals('Comment Changed', $result->text); - } - public function test_mixins_persists_newly_created_entities_on_two_tables(): void { + + public function test_mixins_persists_newly_created_entities_on_two_tables(): void + { $mapper = $this->mapper; - $mapper->postComment = Mix::with(array('comment' => array('text')))->post()->author(); - $post = (object) array('text' => 'Comment X', 'title' => 'Post X', 'id' => null); - $post->author_id = (object) array('name' => 'Author X', 'id' => null); + $mapper->postComment = Mix::with(['comment' => ['text']])->post()->author(); + $post = (object) ['text' => 'Comment X', 'title' => 'Post X', 'id' => null]; + $post->author_id = (object) ['name' => 'Author X', 'id' => null]; $mapper->postComment->persist($post); $mapper->flush(); $result = $this->conn->query('select title, text from post order by id desc')->fetch(PDO::FETCH_OBJ); @@ -774,15 +844,16 @@ public function test_mixins_persists_newly_created_entities_on_two_tables(): voi $this->assertEquals('', $result->text); $result = $this->conn->query('select text from comment order by id desc')->fetch(PDO::FETCH_OBJ); $this->assertEquals('Comment X', $result->text); - } - public function test_mixins_all(): void { + + public function test_mixins_all(): void + { $mapper = $this->mapper; - $mapper->postComment = Mix::with(array('comment' => array('text')))->post()->author(); + $mapper->postComment = Mix::with(['comment' => ['text']])->post()->author(); $post = $mapper->postComment->fetchAll(); $post = $post[0]; - $this->assertEquals((object) array('name' => 'Author 1', 'id' => 1), $post->author_id); - $this->assertEquals((object) array('id' => '5', 'author_id' => $post->author_id, 'text' => 'Comment Text', 'title' => 'Post Title', 'comment_id' => 7), $post); + $this->assertEquals((object) ['name' => 'Author 1', 'id' => 1], $post->author_id); + $this->assertEquals((object) ['id' => '5', 'author_id' => $post->author_id, 'text' => 'Comment Text', 'title' => 'Post Title', 'comment_id' => 7], $post); $post->title = 'Title Changed'; $post->text = 'Comment Changed'; $mapper->postsFromAuthorsWithComments->persist($post); @@ -791,9 +862,10 @@ public function test_mixins_all(): void { $this->assertEquals('Title Changed', $result->title); $result = $this->conn->query('select text from comment where id=7')->fetch(PDO::FETCH_OBJ); $this->assertEquals('Comment Changed', $result->text); - } - public function test_typed(): void { + + public function test_typed(): void + { $mapper = $this->mapper; $mapper->entityNamespace = '\Respect\Relational\\'; $mapper->typedIssues = Typed::by('type')->issues(); @@ -808,7 +880,9 @@ public function test_typed(): void { $result = $this->conn->query('select title from issues where id=1')->fetch(PDO::FETCH_OBJ); $this->assertEquals('Title Changed', $result->title); } - public function test_typed_single(): void { + + public function test_typed_single(): void + { $mapper = $this->mapper; $mapper->entityNamespace = '\Respect\Relational\\'; $mapper->typedIssues = Typed::by('type')->issues(); @@ -825,7 +899,7 @@ public function test_typed_single(): void { public function test_persist_new_with_arrayobject(): void { $mapper = $this->mapper; - $arrayEntity = array('id' => 10, 'name' => 'array_object_category', 'category_id' => null); + $arrayEntity = ['id' => 10, 'name' => 'array_object_category', 'category_id' => null]; $entity = (object) $arrayEntity; $mapper->category->persist($entity); $mapper->flush(); @@ -833,7 +907,6 @@ public function test_persist_new_with_arrayobject(): void $this->assertEquals('array_object_category', $result->name); } - // -------------------------------------------------------------- public function testFetchingEntityWithoutPublicPropertiesTyped(): void { $mapper = $this->mapper; @@ -900,7 +973,7 @@ public function testShouldExecuteEntityConstructorByDefault(): void try { $mapper->comment->fetch(); $this->fail('This should throws exception'); - } catch (\DomainException $e) { + } catch (DomainException $e) { $this->assertEquals('Exception from __construct', $e->getMessage()); } } @@ -913,101 +986,126 @@ public function testShouldNotExecuteEntityConstructorWhenDisabled(): void $this->assertInstanceOf('Respect\\Relational\\OtherEntity\\Comment', $mapper->comment->fetch()); } - } -class Postcomment { - public $id=null; +class Postcomment +{ + public $id = null; } -class Bug { - public $id=null, $title, $type; +class Bug +{ + public $id = null, $title, $type; } -class Improvement { - public $id=null, $title, $type; +class Improvement +{ + public $id = null, $title, $type; } -class Comment { - public $id=null, $post_id=null, $text=null; +class Comment +{ + public $id = null, $post_id = null, $text = null; + private $datetime; - public function setDatetime(\Datetime $datetime) + + public function setDatetime(Datetime $datetime): void { $this->datetime = $datetime->format('Y-m-d H:i:s'); } + public function getDatetime() { - return new \Datetime($this->datetime); + return new Datetime($this->datetime); } } -class Post { - public $id=null, $author_id=null, $text=null, $title=null; +class Post +{ + public $id = null, $author_id = null, $text = null, $title = null; + /** @Relational\isNotColumn -> annotation because generate a sql error case column not exists in db. */ private $datetime = ''; - public function setDatetime(\Datetime $datetime) + + public function setDatetime(Datetime $datetime): void { $this->datetime = $datetime->format('Y-m-d H:i:s'); } + public function getDatetime() { - return new \Datetime($this->datetime); + return new Datetime($this->datetime); } } namespace Respect\Relational\OtherEntity; -class Post { +use DomainException; + +class Post +{ private $id, $author_id, $title, $text; + public function getTitle() { return $this->title; } - public function setTitle($title) + + public function setTitle($title): void { $this->title = $title; } + public function getId() { return $this->id; } + public function getAuthor() { return $this->author_id; } + public function getText() { return $this->text; } - public function setId($id) + + public function setId($id): void { $this->id = $id; } - public function setAuthor(Author $author) + + public function setAuthor(Author $author): void { $this->author_id = $author; } - public function setText($text) + + public function setText($text): void { $this->text = $text; } } -class Author { +class Author +{ private $id, $name; public function getId() { return $this->id; } + public function getName() { return $this->name; } - public function setId($id) + + public function setId($id): void { $this->id = $id; } - public function setName($name) + + public function setName($name): void { $this->name = $name; } @@ -1017,11 +1115,15 @@ public function setName($name) class Comment { public $id = null; + public $post_id = null; + public $text = null; + public $datetime = null; + public function __construct() { - throw new \DomainException('Exception from __construct'); + throw new DomainException('Exception from __construct'); } } diff --git a/tests/SqlTest.php b/tests/SqlTest.php index 847d662..bd3b4a7 100644 --- a/tests/SqlTest.php +++ b/tests/SqlTest.php @@ -8,205 +8,205 @@ use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; +use function array_merge; +use function array_values; + #[CoversClass(Sql::class)] class SqlTest extends TestCase { - protected $object; protected function setUp(): void { - $this->object = new Sql; + $this->object = new Sql(); } public function testCastingObjectToStringReturnsQuery(): void { $sql = $this->object->select('*')->from('table'); - $query = "SELECT * FROM table"; + $query = 'SELECT * FROM table'; $this->assertNotSame($query, $sql); $this->assertSame($query, (string) $sql); - $this->assertSame($query, "$sql"); + $this->assertSame($query, (string) $sql); } public function testSimpleSelect(): void { $sql = (string) $this->object->select('*')->from('table'); - $this->assertEquals("SELECT * FROM table", $sql); + $this->assertEquals('SELECT * FROM table', $sql); } public function testSelectMagicGetDistinctFromHell(): void { $sql = (string) $this->object->selectDistinct('*')->from('table'); - $this->assertEquals("SELECT DISTINCT * FROM table", $sql); + $this->assertEquals('SELECT DISTINCT * FROM table', $sql); } public function testSelectColumns(): void { $sql = (string) $this->object->select('column', 'other_column')->from('table'); - $this->assertEquals("SELECT column, other_column FROM table", $sql); + $this->assertEquals('SELECT column, other_column FROM table', $sql); } public function testSelectTables(): void { $sql = (string) $this->object->select('*')->from('table', 'other_table'); - $this->assertEquals("SELECT * FROM table, other_table", $sql); + $this->assertEquals('SELECT * FROM table, other_table', $sql); } public function testSelectInnerJoin(): void { $sql = (string) $this->object->select('*')->from('table')->innerJoin('other_table')->on('table.column = other_table.other_column'); - $this->assertEquals("SELECT * FROM table INNER JOIN other_table ON table.column = other_table.other_column", $sql); + $this->assertEquals('SELECT * FROM table INNER JOIN other_table ON table.column = other_table.other_column', $sql); } public function testSelectInnerJoinArr(): void { - $sql = (string) $this->object->select('*')->from('table')->innerJoin('other_table')->on(array('table.column' => 'other_table.other_column')); - $this->assertEquals("SELECT * FROM table INNER JOIN other_table ON table.column = other_table.other_column", $sql); + $sql = (string) $this->object->select('*')->from('table')->innerJoin('other_table')->on(['table.column' => 'other_table.other_column']); + $this->assertEquals('SELECT * FROM table INNER JOIN other_table ON table.column = other_table.other_column', $sql); } public function testSelectWhere(): void { $sql = (string) $this->object->select('*')->from('table')->where('column=123'); - $this->assertEquals("SELECT * FROM table WHERE column=123", $sql); + $this->assertEquals('SELECT * FROM table WHERE column=123', $sql); } public function testSelectWhereBetween(): void { $sql = (string) $this->object->select('*')->from('table')->where('column')->between(1, 2); - $this->assertEquals("SELECT * FROM table WHERE column BETWEEN 1 AND 2", $sql); + $this->assertEquals('SELECT * FROM table WHERE column BETWEEN 1 AND 2', $sql); } public function testSelectWhereIn(): void { - $data = array('key' => '123', 'other_key' => '456'); + $data = ['key' => '123', 'other_key' => '456']; $sql = (string) $this->object->select('*')->from('table')->where('column')->in($data); - $this->assertEquals("SELECT * FROM table WHERE column IN (?, ?)", $sql); + $this->assertEquals('SELECT * FROM table WHERE column IN (?, ?)', $sql); $this->assertEquals(array_values($data), $this->object->getParams()); } public function testSelectWhereArray(): void { - $data = array('column' => '123', 'other_column' => '456'); + $data = ['column' => '123', 'other_column' => '456']; $sql = (string) $this->object->select('*')->from('table')->where($data); - $this->assertEquals("SELECT * FROM table WHERE column = ? AND other_column = ?", $sql); + $this->assertEquals('SELECT * FROM table WHERE column = ? AND other_column = ?', $sql); $this->assertEquals(array_values($data), $this->object->getParams()); } public function testSelectWhereArrayEmptyAnd(): void { - $data = array('column' => '123', 'other_column' => '456'); + $data = ['column' => '123', 'other_column' => '456']; $sql = (string) $this->object->select('*')->from('table')->where($data)->and(); - $this->assertEquals("SELECT * FROM table WHERE column = ? AND other_column = ?", $sql); + $this->assertEquals('SELECT * FROM table WHERE column = ? AND other_column = ?', $sql); $this->assertEquals(array_values($data), $this->object->getParams()); } public function testSelectWhereOr(): void { - $data = array('column' => '123'); - $data2 = array('other_column' => '456'); + $data = ['column' => '123']; + $data2 = ['other_column' => '456']; $sql = (string) $this->object->select('*')->from('table')->where($data)->or($data2); - $this->assertEquals("SELECT * FROM table WHERE column = ? OR other_column = ?", $sql); + $this->assertEquals('SELECT * FROM table WHERE column = ? OR other_column = ?', $sql); $this->assertEquals(array_values(array_merge($data, $data2)), $this->object->getParams()); } public function testSelectWhereArrayQualifiedNames(): void { - $data = array('a.column' => '123', 'b.other_column' => '456'); + $data = ['a.column' => '123', 'b.other_column' => '456']; $sql = (string) $this->object->select('*')->from('table a', 'other_table b')->where($data); - $this->assertEquals("SELECT * FROM table a, other_table b WHERE a.column = ? AND b.other_column = ?", $sql); + $this->assertEquals('SELECT * FROM table a, other_table b WHERE a.column = ? AND b.other_column = ?', $sql); $this->assertEquals(array_values($data), $this->object->getParams()); } public function testSelectGroupBy(): void { $sql = (string) $this->object->select('*')->from('table')->groupBy('column', 'other_column'); - $this->assertEquals("SELECT * FROM table GROUP BY column, other_column", $sql); + $this->assertEquals('SELECT * FROM table GROUP BY column, other_column', $sql); } public function testSelectGroupByHaving(): void { - $condition = array('other_column' => 456, 'yet_another_column' => 567); + $condition = ['other_column' => 456, 'yet_another_column' => 567]; $sql = (string) $this->object->select('*')->from('table')->groupBy('column', 'other_column')->having($condition); - $this->assertEquals("SELECT * FROM table GROUP BY column, other_column HAVING other_column = ? AND yet_another_column = ?", $sql); + $this->assertEquals('SELECT * FROM table GROUP BY column, other_column HAVING other_column = ? AND yet_another_column = ?', $sql); $this->assertEquals(array_values($condition), $this->object->getParams()); } public function testSimpleUpdate(): void { - $data = array('column' => 123, 'column_2' => 234); - $condition = array('other_column' => 456, 'yet_another_column' => 567); + $data = ['column' => 123, 'column_2' => 234]; + $condition = ['other_column' => 456, 'yet_another_column' => 567]; $sql = (string) $this->object->update('table')->set($data)->where($condition); - $this->assertEquals("UPDATE table SET column = ?, column_2 = ? WHERE other_column = ? AND yet_another_column = ?", $sql); + $this->assertEquals('UPDATE table SET column = ?, column_2 = ? WHERE other_column = ? AND yet_another_column = ?', $sql); $this->assertEquals(array_values(array_merge($data, $condition)), $this->object->getParams()); } public function testSimpleInsert(): void { - $data = array('column' => 123, 'column_2' => 234); + $data = ['column' => 123, 'column_2' => 234]; $sql = (string) $this->object->insertInto('table', $data)->values($data); - $this->assertEquals("INSERT INTO table (column, column_2) VALUES (?, ?)", $sql); + $this->assertEquals('INSERT INTO table (column, column_2) VALUES (?, ?)', $sql); $this->assertEquals(array_values($data), $this->object->getParams()); } public function testSimpleDelete(): void { - $condition = array('other_column' => 456, 'yet_another_column' => 567); + $condition = ['other_column' => 456, 'yet_another_column' => 567]; $sql = (string) $this->object->deleteFrom('table')->where($condition); - $this->assertEquals("DELETE FROM table WHERE other_column = ? AND yet_another_column = ?", $sql); + $this->assertEquals('DELETE FROM table WHERE other_column = ? AND yet_another_column = ?', $sql); $this->assertEquals(array_values($condition), $this->object->getParams()); } public function testCreateTable(): void { - $columns = array( + $columns = [ 'column INT', 'other_column VARCHAR(255)', - 'yet_another_column TEXT' - ); + 'yet_another_column TEXT', + ]; $sql = (string) $this->object->createTable('table', $columns); - $this->assertEquals("CREATE TABLE table (column INT, other_column VARCHAR(255), yet_another_column TEXT)", $sql); + $this->assertEquals('CREATE TABLE table (column INT, other_column VARCHAR(255), yet_another_column TEXT)', $sql); } public function testAlterTable(): void { - $columns = array( + $columns = [ 'ADD column INT', 'ADD other_column VARCHAR(255)', - 'ADD yet_another_column TEXT' - ); + 'ADD yet_another_column TEXT', + ]; $sql = (string) $this->object->alterTable('table', $columns); - $this->assertEquals("ALTER TABLE table ADD column INT, ADD other_column VARCHAR(255), ADD yet_another_column TEXT", $sql); + $this->assertEquals('ALTER TABLE table ADD column INT, ADD other_column VARCHAR(255), ADD yet_another_column TEXT', $sql); } public function testGrant(): void { $sql = (string) $this->object->grant('SELECT', 'UPDATE')->on('table')->to('user', 'other_user'); - $this->assertEquals("GRANT SELECT, UPDATE ON table TO user, other_user", $sql); + $this->assertEquals('GRANT SELECT, UPDATE ON table TO user, other_user', $sql); } public function testRevoke(): void { $sql = (string) $this->object->revoke('SELECT', 'UPDATE')->on('table')->to('user', 'other_user'); - $this->assertEquals("REVOKE SELECT, UPDATE ON table TO user, other_user", $sql); + $this->assertEquals('REVOKE SELECT, UPDATE ON table TO user, other_user', $sql); } public function testComplexFunctions(): void { - $condition = array("AES_DECRYPT('pass', 'salt')" => 123); + $condition = ["AES_DECRYPT('pass', 'salt')" => 123]; $sql = (string) $this->object->select('column', 'COUNT(column)', 'other_column')->from('table')->where($condition); $this->assertEquals("SELECT column, COUNT(column), other_column FROM table WHERE AES_DECRYPT('pass', 'salt') = ?", $sql); $this->assertEquals(array_values($condition), $this->object->getParams()); } - /** - * @ticket 13 - */ + /** @ticket 13 */ public function testAggregateFunctions(): void { - $where = array('abc' => 10); - $having = array('SUM(abc) >=' => '10', 'AVG(def) =' => 15); + $where = ['abc' => 10]; + $having = ['SUM(abc) >=' => '10', 'AVG(def) =' => 15]; $sql = (string) $this->object->select('column', 'MAX(def)')->from('table')->where($where)->groupBy('abc', 'def')->having($having); - $this->assertEquals("SELECT column, MAX(def) FROM table WHERE abc = ? GROUP BY abc, def HAVING SUM(abc) >= ? AND AVG(def) = ?", $sql); + $this->assertEquals('SELECT column, MAX(def) FROM table WHERE abc = ? GROUP BY abc, def HAVING SUM(abc) >= ? AND AVG(def) = ?', $sql); $this->assertEquals(array_values(array_merge($where, $having)), $this->object->getParams()); } @@ -214,55 +214,54 @@ public function testStaticBuilderCall(): void { $this->assertEquals( 'ORDER BY updated_at DESC', - (string) Sql::orderBy('updated_at')->desc() + (string) Sql::orderBy('updated_at')->desc(), ); } + public function testLastParameterWithoutParts(): void { $this->assertEquals( 'ORDER BY updated_at DESC', - $this->object->orderBy('updated_at')->desc() + $this->object->orderBy('updated_at')->desc(), ); } public static function provider_sql_operators(): array { - // $operator, $expectedWhere - return array( - array('='), - array('=='), - array('<>'), - array('!='), - array('>'), - array('>='), - array('<'), - array('<='), - array('LIKE'), - ); - } - - /** - * @ticket 13 - */ + // operator, expectedWhere + return [ + ['='], + ['=='], + ['<>'], + ['!='], + ['>'], + ['>='], + ['<'], + ['<='], + ['LIKE'], + ]; + } + + /** @ticket 13 */ #[DataProvider('provider_sql_operators')] - public function test_sql_operators($operator, $expected=null): void + public function test_sql_operators($operator, $expected = null): void { $expected = $expected ?: ' ?'; - $where = array('id '.$operator => 10); + $where = ['id ' . $operator => 10]; $sql = (string) $this->object->select('*')->from('table')->where($where); - $this->assertEquals('SELECT * FROM table WHERE id '.$operator.$expected, $sql); + $this->assertEquals('SELECT * FROM table WHERE id ' . $operator . $expected, $sql); } public function testSetQueryWithParams(): void { $query = 'SELECT * FROM table WHERE a > ? AND b = ?'; - $params = array(1, 'foo'); + $params = [1, 'foo']; $sql = (string) $this->object->setQuery($query, $params); $this->assertEquals($query, $sql); $this->assertEquals($params, $this->object->getParams()); - $sql = (string) $this->object->setQuery('', array()); + $sql = (string) $this->object->setQuery('', []); $this->assertEmpty($sql); $this->assertEmpty($this->object->getParams()); } @@ -270,7 +269,7 @@ public function testSetQueryWithParams(): void public function testSetQueryWithParamsViaConstructor(): void { $query = 'SELECT * FROM table WHERE a > ? AND b = ?'; - $params = array(1, 'foo'); + $params = [1, 'foo']; $sql = new Sql($query, $params); $this->assertEquals($query, (string) $sql); @@ -280,112 +279,112 @@ public function testSetQueryWithParamsViaConstructor(): void public function testAppendQueryWithParams(): void { $query = 'SELECT * FROM table WHERE a > ? AND b = ?'; - $this->object->setQuery('SELECT * FROM table WHERE a > ? AND b = ?', array(1, 'foo')); - $sql = (string) $this->object->appendQuery('AND c = ?', array(2)); + $this->object->setQuery('SELECT * FROM table WHERE a > ? AND b = ?', [1, 'foo']); + $sql = (string) $this->object->appendQuery('AND c = ?', [2]); - $this->assertEquals($query.' AND c = ?', $sql); - $this->assertEquals(array(1, 'foo', 2), $this->object->getParams()); + $this->assertEquals($query . ' AND c = ?', $sql); + $this->assertEquals([1, 'foo', 2], $this->object->getParams()); } public function testSelectWhereWithRepeatedReferences(): void { - $data1 = array('a >' => 1, 'b' => 'foo'); - $data2 = array('a >' => 4); - $data3 = array('b' => 'bar'); + $data1 = ['a >' => 1, 'b' => 'foo']; + $data2 = ['a >' => 4]; + $data3 = ['b' => 'bar']; $sql = (string) $this->object->select('*')->from('table')->where($data1)->or($data2)->and($data3); - $this->assertEquals("SELECT * FROM table WHERE a > ? AND b = ? OR a > ? AND b = ?", $sql); - $this->assertEquals(array(1, 'foo', 4, 'bar'), $this->object->getParams()); + $this->assertEquals('SELECT * FROM table WHERE a > ? AND b = ? OR a > ? AND b = ?', $sql); + $this->assertEquals([1, 'foo', 4, 'bar'], $this->object->getParams()); } public function testSelectWhereWithConditionsGroupedByUnderscores(): void { - $data = array(array('a' => 1), array('b' => 2), array('c' => 3), array('d' => 4)); + $data = [['a' => 1], ['b' => 2], ['c' => 3], ['d' => 4]]; $sql = (string) $this->object->select('*')->from('table')->where($data[0])->and_($data[1])->or($data[2])->_(); - $this->assertEquals("SELECT * FROM table WHERE a = ? AND (b = ? OR c = ?)", $sql); - $this->assertEquals(array(1, 2, 3), $this->object->getParams()); - $this->object->setQuery('', array()); + $this->assertEquals('SELECT * FROM table WHERE a = ? AND (b = ? OR c = ?)', $sql); + $this->assertEquals([1, 2, 3], $this->object->getParams()); + $this->object->setQuery('', []); $sql = (string) $this->object->select('*')->from('table')->where_($data[0])->or($data[1])->_()->and_($data[2])->or($data[3])->_(); - $this->assertEquals("SELECT * FROM table WHERE (a = ? OR b = ?) AND (c = ? OR d = ?)", $sql); - $this->assertEquals(array(1, 2, 3, 4), $this->object->getParams()); - $this->object->setQuery('', array()); + $this->assertEquals('SELECT * FROM table WHERE (a = ? OR b = ?) AND (c = ? OR d = ?)', $sql); + $this->assertEquals([1, 2, 3, 4], $this->object->getParams()); + $this->object->setQuery('', []); $sql = (string) $this->object->select('*')->from('table')->where($data[0])->and_($data[1])->or_($data[2])->and($data[3])->_()->_(); - $this->assertEquals("SELECT * FROM table WHERE a = ? AND (b = ? OR (c = ? AND d = ?))", $sql); - $this->assertEquals(array(1, 2, 3, 4), $this->object->getParams()); + $this->assertEquals('SELECT * FROM table WHERE a = ? AND (b = ? OR (c = ? AND d = ?))', $sql); + $this->assertEquals([1, 2, 3, 4], $this->object->getParams()); } public function testSelectWhereWithConditionsGroupedBySubqueries(): void { - $data = array(array('a' => 1), array('b' => 2), array('c' => 3), array('d' => 4)); + $data = [['a' => 1], ['b' => 2], ['c' => 3], ['d' => 4]]; $sql = (string) $this->object->select('*')->from('table')->where($data[0], Sql::cond($data[1])->or($data[2])); - $this->assertEquals("SELECT * FROM table WHERE a = ? AND (b = ? OR c = ?)", $sql); - $this->assertEquals(array(1, 2, 3), $this->object->getParams()); - $this->object->setQuery('', array()); + $this->assertEquals('SELECT * FROM table WHERE a = ? AND (b = ? OR c = ?)', $sql); + $this->assertEquals([1, 2, 3], $this->object->getParams()); + $this->object->setQuery('', []); $sql = (string) $this->object->select('*')->from('table')->where(Sql::cond($data[0])->or($data[1]), Sql::cond($data[2])->or($data[3])); - $this->assertEquals("SELECT * FROM table WHERE (a = ? OR b = ?) AND (c = ? OR d = ?)", $sql); - $this->assertEquals(array(1, 2, 3, 4), $this->object->getParams()); - $this->object->setQuery('', array()); + $this->assertEquals('SELECT * FROM table WHERE (a = ? OR b = ?) AND (c = ? OR d = ?)', $sql); + $this->assertEquals([1, 2, 3, 4], $this->object->getParams()); + $this->object->setQuery('', []); $sql = (string) $this->object->select('*')->from('table')->where($data[0], Sql::cond($data[1])->or(Sql::cond($data[2], $data[3]))); - $this->assertEquals("SELECT * FROM table WHERE a = ? AND (b = ? OR (c = ? AND d = ?))", $sql); - $this->assertEquals(array(1, 2, 3, 4), $this->object->getParams()); + $this->assertEquals('SELECT * FROM table WHERE a = ? AND (b = ? OR (c = ? AND d = ?))', $sql); + $this->assertEquals([1, 2, 3, 4], $this->object->getParams()); } public function testSelectWhereWithSubquery(): void { - $subquery = Sql::select('column1')->from('t2')->where(array('column2' => 2)); - $sql = (string) $this->object->select('column1')->from('t1')->where(array('column1' => $subquery, 'column2' => 'foo')); + $subquery = Sql::select('column1')->from('t2')->where(['column2' => 2]); + $sql = (string) $this->object->select('column1')->from('t1')->where(['column1' => $subquery, 'column2' => 'foo']); - $this->assertEquals("SELECT column1 FROM t1 WHERE column1 = (SELECT column1 FROM t2 WHERE column2 = ?) AND column2 = ?", $sql); - $this->assertEquals(array(2, 'foo'), $this->object->getParams()); + $this->assertEquals('SELECT column1 FROM t1 WHERE column1 = (SELECT column1 FROM t2 WHERE column2 = ?) AND column2 = ?', $sql); + $this->assertEquals([2, 'foo'], $this->object->getParams()); } public function testSelectWhereWithNestedSubqueries(): void { - $subquery1 = Sql::select('column1')->from('t3')->where(array('column3' => 3)); - $subquery2 = Sql::select('column1')->from('t2')->where(array('column2' => $subquery1, 'column3' => 'foo')); - $sql = (string) $this->object->select('column1')->from('t1')->where(array('column1' => $subquery2)); + $subquery1 = Sql::select('column1')->from('t3')->where(['column3' => 3]); + $subquery2 = Sql::select('column1')->from('t2')->where(['column2' => $subquery1, 'column3' => 'foo']); + $sql = (string) $this->object->select('column1')->from('t1')->where(['column1' => $subquery2]); - $this->assertEquals("SELECT column1 FROM t1 WHERE column1 = (SELECT column1 FROM t2 WHERE column2 = (SELECT column1 FROM t3 WHERE column3 = ?) AND column3 = ?)", $sql); - $this->assertEquals(array(3, 'foo'), $this->object->getParams()); + $this->assertEquals('SELECT column1 FROM t1 WHERE column1 = (SELECT column1 FROM t2 WHERE column2 = (SELECT column1 FROM t3 WHERE column3 = ?) AND column3 = ?)', $sql); + $this->assertEquals([3, 'foo'], $this->object->getParams()); } public function testSelectUsingAliasedColumns(): void { - $sql = (string) $this->object->select('f1', array('alias' => 'f2'), 'f3', array('another_alias' => 'f4'))->from('table'); - $this->assertEquals("SELECT f1, f2 AS alias, f3, f4 AS another_alias FROM table", $sql); + $sql = (string) $this->object->select('f1', ['alias' => 'f2'], 'f3', ['another_alias' => 'f4'])->from('table'); + $this->assertEquals('SELECT f1, f2 AS alias, f3, f4 AS another_alias FROM table', $sql); $this->assertEmpty($this->object->getParams()); } public function testSelectWithColumnAsSubquery(): void { - $subquery = Sql::select('f1')->from('t2')->where(array('f2' => 2)); - $sql = (string) $this->object->select('f1', array('subalias' => $subquery))->from('t1')->where(array('f2' => 'foo')); + $subquery = Sql::select('f1')->from('t2')->where(['f2' => 2]); + $sql = (string) $this->object->select('f1', ['subalias' => $subquery])->from('t1')->where(['f2' => 'foo']); - $this->assertEquals("SELECT f1, (SELECT f1 FROM t2 WHERE f2 = ?) AS subalias FROM t1 WHERE f2 = ?", $sql); - $this->assertEquals(array(2, 'foo'), $this->object->getParams()); + $this->assertEquals('SELECT f1, (SELECT f1 FROM t2 WHERE f2 = ?) AS subalias FROM t1 WHERE f2 = ?', $sql); + $this->assertEquals([2, 'foo'], $this->object->getParams()); } public function testInsertWithValueFunctions(): void { - $data = array('column' => 123, 'column_2' => 234); + $data = ['column' => 123, 'column_2' => 234]; $sql = (string) $this->object->insertInto('table', $data, 'date')->values($data, 'NOW()'); - $this->assertEquals("INSERT INTO table (column, column_2, date) VALUES (?, ?, NOW())", $sql); + $this->assertEquals('INSERT INTO table (column, column_2, date) VALUES (?, ?, NOW())', $sql); $this->assertEquals(array_values($data), $this->object->getParams()); } public function testInsertWithSelectSubquery(): void { - $data = array('f3' => 3, 'f4' => 4); + $data = ['f3' => 3, 'f4' => 4]; $subquery = Sql::select('f1', 'f2')->from('t2')->where($data); - $sql = (string) $this->object->insertInto('t1', array('f1', 'f2'))->appendQuery($subquery); + $sql = (string) $this->object->insertInto('t1', ['f1', 'f2'])->appendQuery($subquery); - $this->assertEquals("INSERT INTO t1 (f1, f2) SELECT f1, f2 FROM t2 WHERE f3 = ? AND f4 = ?", $sql); + $this->assertEquals('INSERT INTO t1 (f1, f2) SELECT f1, f2 FROM t2 WHERE f3 = ? AND f4 = ?', $sql); $this->assertEquals(array_values($data), $this->object->getParams()); } } diff --git a/tests/Styles/AbstractStyleTest.php b/tests/Styles/AbstractStyleTest.php index 8519a1a..f795352 100644 --- a/tests/Styles/AbstractStyleTest.php +++ b/tests/Styles/AbstractStyleTest.php @@ -7,12 +7,63 @@ use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; +use ReflectionMethod; #[CoversClass(AbstractStyle::class)] class AbstractStyleTest extends TestCase { private AbstractStyle $style; + protected function setUp(): void + { + $this->style = new class extends AbstractStyle { + public function styledProperty(string $name): string + { + return $name; + } + + public function realName(string $name): string + { + return $name; + } + + public function realProperty(string $name): string + { + return $name; + } + + public function styledName(string $name): string + { + return $name; + } + + public function identifier(string $name): string + { + return 'id'; + } + + public function remoteIdentifier(string $name): string + { + return $name . '_id'; + } + + public function composed(string $left, string $right): string + { + return $left . '_' . $right; + } + + public function isRemoteIdentifier(string $name): bool + { + return false; + } + + public function remoteFromIdentifier(string $name): string|null + { + return null; + } + }; + } + /** @return array */ public static function singularPluralProvider(): array { @@ -35,38 +86,23 @@ public static function camelCaseToSeparatorProvider(): array ]; } - protected function setUp(): void - { - $this->style = new class extends AbstractStyle { - public function styledProperty(string $name): string { return $name; } - public function realName(string $name): string { return $name; } - public function realProperty(string $name): string { return $name; } - public function styledName(string $name): string { return $name; } - public function identifier(string $name): string { return 'id'; } - public function remoteIdentifier(string $name): string { return $name . '_id'; } - public function composed(string $left, string $right): string { return "{$left}_{$right}"; } - public function isRemoteIdentifier(string $name): bool { return false; } - public function remoteFromIdentifier(string $name): ?string { return null; } - }; - } - #[DataProvider('singularPluralProvider')] public function test_plural_to_singular_and_vice_versa(string $singular, string $plural): void { - $pluralToSingular = new \ReflectionMethod($this->style, 'pluralToSingular'); + $pluralToSingular = new ReflectionMethod($this->style, 'pluralToSingular'); $this->assertEquals($singular, $pluralToSingular->invoke($this->style, $plural)); - $singularToPlural = new \ReflectionMethod($this->style, 'singularToPlural'); + $singularToPlural = new ReflectionMethod($this->style, 'singularToPlural'); $this->assertEquals($plural, $singularToPlural->invoke($this->style, $singular)); } #[DataProvider('camelCaseToSeparatorProvider')] public function test_camel_case_to_separator_and_vice_versa(string $separator, string $camelCase, string $separated): void { - $camelCaseToSeparatorMethod = new \ReflectionMethod($this->style, 'camelCaseToSeparator'); + $camelCaseToSeparatorMethod = new ReflectionMethod($this->style, 'camelCaseToSeparator'); $this->assertEquals($separated, $camelCaseToSeparatorMethod->invoke($this->style, $camelCase, $separator)); - $separatorToCamelCaseMethod = new \ReflectionMethod($this->style, 'separatorToCamelCase'); + $separatorToCamelCaseMethod = new ReflectionMethod($this->style, 'separatorToCamelCase'); $this->assertEquals($camelCase, $separatorToCamelCaseMethod->invoke($this->style, $separated, $separator)); } } diff --git a/tests/Styles/CakePHPTest.php b/tests/Styles/CakePHPTest.php index e7871b1..ee5f491 100644 --- a/tests/Styles/CakePHPTest.php +++ b/tests/Styles/CakePHPTest.php @@ -4,157 +4,155 @@ namespace Respect\Data\Styles\CakePHP; -use PDO, - Respect\Relational\Db, - Respect\Relational\Sql, - Respect\Data\Styles\CakePHP, - Respect\Relational\Mapper; +use PDO; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; +use Respect\Data\Styles\CakePHP; +use Respect\Relational\Db; +use Respect\Relational\Mapper; +use Respect\Relational\Sql; #[CoversClass(CakePHP::class)] class CakePHPTest extends TestCase { + private CakePHP $style; - /** - * @var Respect\Data\Styles\CakePHP - */ - private $style; + private Mapper $mapper; - /** - * @var Respect\Relational\Mapper - */ - private $mapper; - - /** - * @var PDO - */ - private $conn; + private PDO $conn; private $posts; + private $authors; + private $comments; + private $categories; + private $postsCategories; protected function setUp(): void { - $conn = new PDO('sqlite::memory:'); $db = new Db($conn); $conn->exec( (string) Sql::createTable( 'posts', - array( + [ 'id INTEGER PRIMARY KEY', 'title VARCHAR(255)', 'text TEXT', 'author_id INTEGER', - ) - ) + ], + ), ); $conn->exec( (string) Sql::createTable( 'authors', - array( + [ 'id INTEGER PRIMARY KEY', - 'name VARCHAR(255)' - ) - ) + 'name VARCHAR(255)', + ], + ), ); $conn->exec( (string) Sql::createTable( 'comments', - array( + [ 'id INTEGER PRIMARY KEY', 'post_id INTEGER', 'text TEXT', - ) - ) + ], + ), ); $conn->exec( (string) Sql::createTable( - //$id, $name, $category_id + // id, name, category_id 'categories', - array( + [ 'id INTEGER PRIMARY KEY', 'name VARCHAR(255)', - 'category_id INTEGER' - ) - ) + 'category_id INTEGER', + ], + ), ); $conn->exec( (string) Sql::createTable( 'post_categories', - array( + [ 'id INTEGER PRIMARY KEY', 'post_id INTEGER', - 'category_id INTEGER' - ) - ) + 'category_id INTEGER', + ], + ), ); - $this->posts = array( - (object) array( + $this->posts = [ + (object) [ 'id' => 5, 'title' => 'Post Title', 'text' => 'Post Text', - 'author_id' => 1 - ) - ); - $this->authors = array( - (object) array( + 'author_id' => 1, + ], + ]; + $this->authors = [ + (object) [ 'id' => 1, - 'name' => 'Author 1' - ) - ); - $this->comments = array( - (object) array( + 'name' => 'Author 1', + ], + ]; + $this->comments = [ + (object) [ 'id' => 7, 'post_id' => 5, - 'text' => 'Comment Text' - ), - (object) array( + 'text' => 'Comment Text', + ], + (object) [ 'id' => 8, 'post_id' => 4, - 'text' => 'Comment Text 2' - ) - ); - $this->categories = array( - (object) array( + 'text' => 'Comment Text 2', + ], + ]; + $this->categories = [ + (object) [ 'id' => 2, 'name' => 'Sample Category', - 'category_id' => null - ), - (object) array( + 'category_id' => null, + ], + (object) [ 'id' => 3, 'name' => 'NONON', - 'category_id' => null - ) - ); - $this->postsCategories = array( - (object) array( + 'category_id' => null, + ], + ]; + $this->postsCategories = [ + (object) [ 'id' => 66, 'post_id' => 5, - 'category_id' => 2 - ) - ); + 'category_id' => 2, + ], + ]; - foreach ($this->authors as $author) + foreach ($this->authors as $author) { $db->insertInto('authors', (array) $author)->values((array) $author)->exec(); + } - foreach ($this->posts as $post) + foreach ($this->posts as $post) { $db->insertInto('posts', (array) $post)->values((array) $post)->exec(); + } - foreach ($this->comments as $comment) + foreach ($this->comments as $comment) { $db->insertInto('comments', (array) $comment)->values((array) $comment)->exec(); + } - foreach ($this->categories as $category) + foreach ($this->categories as $category) { $db->insertInto('categories', (array) $category)->values((array) $category)->exec(); + } - foreach ($this->postsCategories as $postCategory) + foreach ($this->postsCategories as $postCategory) { $db->insertInto('post_categories', (array) $postCategory)->values((array) $postCategory)->exec(); + } $this->conn = $conn; $this->style = new CakePHP(); @@ -163,11 +161,6 @@ protected function setUp(): void $this->mapper->entityNamespace = __NAMESPACE__ . '\\'; } - protected function tearDown(): void - { - $this->style = null; - } - #[DataProvider('tableEntityProvider')] public function test_table_and_entities_methods($table, $entity): void { @@ -222,8 +215,8 @@ public function test_fetching_all_entity_typed_nested(): void $mapper = $this->mapper; $comment = $mapper->comments->posts->authors->fetchAll(); $this->assertInstanceOf(__NAMESPACE__ . '\Comment', $comment[0]); - $this->assertInstanceOf(__NAMESPACE__ . '\Post', $comment[0]->post_id); - $this->assertInstanceOf(__NAMESPACE__ . '\Author', $comment[0]->post_id->author_id); + $this->assertInstanceOf(__NAMESPACE__ . '\Post', $comment[0]->post_id); + $this->assertInstanceOf(__NAMESPACE__ . '\Author', $comment[0]->post_id->author_id); } public function test_persisting_entity_typed(): void @@ -251,45 +244,44 @@ public function test_persisting_new_entity_typed(): void public static function tableEntityProvider(): array { - return array( - array('posts', 'Post'), - array('comments', 'Comment'), - array('categories', 'Category'), - array('post_categories', 'PostCategory'), - array('post_tags', 'PostTag'), - ); + return [ + ['posts', 'Post'], + ['comments', 'Comment'], + ['categories', 'Category'], + ['post_categories', 'PostCategory'], + ['post_tags', 'PostTag'], + ]; } public static function manyToMantTableProvider(): array { - return array( - array('post', 'category', 'post_categories'), - array('user', 'group', 'user_groups'), - array('group', 'profile', 'group_profiles'), - ); + return [ + ['post', 'category', 'post_categories'], + ['user', 'group', 'user_groups'], + ['group', 'profile', 'group_profiles'], + ]; } public static function columnsPropertyProvider(): array { - return array( - array('id'), - array('text'), - array('name'), - array('content'), - array('created'), - ); + return [ + ['id'], + ['text'], + ['name'], + ['content'], + ['created'], + ]; } public static function foreignProvider(): array { - return array( - array('posts', 'post_id'), - array('authors', 'author_id'), - array('tags', 'tag_id'), - array('users', 'user_id'), - ); + return [ + ['posts', 'post_id'], + ['authors', 'author_id'], + ['tags', 'tag_id'], + ['users', 'user_id'], + ]; } - } class Post diff --git a/tests/Styles/NorthWindTest.php b/tests/Styles/NorthWindTest.php index afc3c6b..99c52cd 100644 --- a/tests/Styles/NorthWindTest.php +++ b/tests/Styles/NorthWindTest.php @@ -4,156 +4,154 @@ namespace Respect\Data\Styles\NorthWind; -use PDO, - Respect\Relational\Db, - Respect\Relational\Sql, - Respect\Data\Styles\NorthWind, - Respect\Relational\Mapper; +use PDO; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; +use Respect\Data\Styles\NorthWind; +use Respect\Relational\Db; +use Respect\Relational\Mapper; +use Respect\Relational\Sql; #[CoversClass(NorthWind::class)] class NorthWindTest extends TestCase { + private NorthWind $style; - /** - * @var Respect\Data\Styles\NorthWind - */ - private $style; + private Mapper $mapper; - /** - * @var Respect\Relational\Mapper - */ - private $mapper; - - /** - * @var PDO - */ - private $conn; + private PDO $conn; private $posts; + private $authors; + private $comments; + private $categories; + private $postsCategories; protected function setUp(): void { - $conn = new PDO('sqlite::memory:'); $db = new Db($conn); $conn->exec( (string) Sql::createTable( 'Posts', - array( + [ 'PostID INTEGER PRIMARY KEY', 'Title VARCHAR(255)', 'Text TEXT', 'AuthorID INTEGER', - ) - ) + ], + ), ); $conn->exec( (string) Sql::createTable( 'Authors', - array( + [ 'AuthorID INTEGER PRIMARY KEY', - 'Name VARCHAR(255)' - ) - ) + 'Name VARCHAR(255)', + ], + ), ); $conn->exec( (string) Sql::createTable( 'Comments', - array( + [ 'CommentID INTEGER PRIMARY KEY', 'PostID INTEGER', 'Text TEXT', - ) - ) + ], + ), ); $conn->exec( (string) Sql::createTable( 'Categories', - array( + [ 'CategoryID INTEGER PRIMARY KEY', 'Name VARCHAR(255)', - 'Description TEXT' - ) - ) + 'Description TEXT', + ], + ), ); $conn->exec( (string) Sql::createTable( 'PostCategories', - array( + [ 'PostCategoryID INTEGER PRIMARY KEY', 'PostID INTEGER', - 'CategoryID INTEGER' - ) - ) + 'CategoryID INTEGER', + ], + ), ); - $this->posts = array( - (object) array( + $this->posts = [ + (object) [ 'PostID' => 5, 'Title' => 'Post Title', 'Text' => 'Post Text', - 'AuthorID' => 1 - ) - ); - $this->authors = array( - (object) array( 'AuthorID' => 1, - 'Name' => 'Author 1' - ) - ); - $this->comments = array( - (object) array( + ], + ]; + $this->authors = [ + (object) [ + 'AuthorID' => 1, + 'Name' => 'Author 1', + ], + ]; + $this->comments = [ + (object) [ 'CommentID' => 7, 'PostID' => 5, - 'Text' => 'Comment Text' - ), - (object) array( + 'Text' => 'Comment Text', + ], + (object) [ 'CommentID' => 8, 'PostID' => 4, - 'Text' => 'Comment Text 2' - ) - ); - $this->categories = array( - (object) array( + 'Text' => 'Comment Text 2', + ], + ]; + $this->categories = [ + (object) [ 'CategoryID' => 2, 'Name' => 'Sample Category', - 'Description' => 'Category description' - ), - (object) array( + 'Description' => 'Category description', + ], + (object) [ 'CategoryID' => 3, 'Name' => 'NONON', - 'CategoryID' => null - ) - ); - $this->postsCategories = array( - (object) array( + 'CategoryID' => null, + ], + ]; + $this->postsCategories = [ + (object) [ 'PostCategoryID' => 66, 'PostID' => 5, - 'CategoryID' => 2 - ) - ); + 'CategoryID' => 2, + ], + ]; - foreach ($this->authors as $author) + foreach ($this->authors as $author) { $db->insertInto('Authors', (array) $author)->values((array) $author)->exec(); + } - foreach ($this->posts as $post) + foreach ($this->posts as $post) { $db->insertInto('Posts', (array) $post)->values((array) $post)->exec(); + } - foreach ($this->comments as $comment) + foreach ($this->comments as $comment) { $db->insertInto('Comments', (array) $comment)->values((array) $comment)->exec(); + } - foreach ($this->categories as $category) + foreach ($this->categories as $category) { $db->insertInto('Categories', (array) $category)->values((array) $category)->exec(); + } - foreach ($this->postsCategories as $postCategory) + foreach ($this->postsCategories as $postCategory) { $db->insertInto('PostCategories', (array) $postCategory)->values((array) $postCategory)->exec(); + } $this->conn = $conn; $this->style = new NorthWind(); @@ -164,43 +162,43 @@ protected function setUp(): void public static function tableEntityProvider(): array { - return array( - array('Posts', 'Posts'), - array('Comments', 'Comments'), - array('Categories', 'Categories'), - array('PostCategories', 'PostCategories'), - array('PostTags', 'PostTags'), - ); + return [ + ['Posts', 'Posts'], + ['Comments', 'Comments'], + ['Categories', 'Categories'], + ['PostCategories', 'PostCategories'], + ['PostTags', 'PostTags'], + ]; } public static function manyToMantTableProvider(): array { - return array( - array('Posts', 'Categories', 'PostCategories'), - array('Users', 'Groups', 'UserGroups'), - array('Groups', 'Profiles', 'GroupProfiles'), - ); + return [ + ['Posts', 'Categories', 'PostCategories'], + ['Users', 'Groups', 'UserGroups'], + ['Groups', 'Profiles', 'GroupProfiles'], + ]; } public static function columnsPropertyProvider(): array { - return array( - array('Text'), - array('Name'), - array('Content'), - array('Created'), - array('Udated'), - ); + return [ + ['Text'], + ['Name'], + ['Content'], + ['Created'], + ['Udated'], + ]; } public static function keyProvider(): array { - return array( - array('Posts', 'PostID'), - array('Authors', 'AuthorID'), - array('Tags', 'TagID'), - array('Users', 'UserID'), - ); + return [ + ['Posts', 'PostID'], + ['Authors', 'AuthorID'], + ['Tags', 'TagID'], + ['Users', 'UserID'], + ]; } #[DataProvider('tableEntityProvider')] @@ -257,8 +255,8 @@ public function test_fetching_all_entity_typed_nested(): void $mapper = $this->mapper; $comment = $mapper->Comments->Posts->Authors->fetchAll(); $this->assertInstanceOf(__NAMESPACE__ . '\Comments', $comment[0]); - $this->assertInstanceOf(__NAMESPACE__ . '\Posts', $comment[0]->PostID); - $this->assertInstanceOf(__NAMESPACE__ . '\Authors', $comment[0]->PostID->AuthorID); + $this->assertInstanceOf(__NAMESPACE__ . '\Posts', $comment[0]->PostID); + $this->assertInstanceOf(__NAMESPACE__ . '\Authors', $comment[0]->PostID->AuthorID); } public function test_persisting_entity_typed(): void @@ -283,7 +281,6 @@ public function test_persisting_new_entity_typed(): void $result = $this->conn->query('select Text from Comments where CommentID=9')->fetchColumn(0); $this->assertEquals('HeyHey', $result); } - } diff --git a/tests/Styles/PluralTest.php b/tests/Styles/PluralTest.php index 7b82d6a..b484cb7 100644 --- a/tests/Styles/PluralTest.php +++ b/tests/Styles/PluralTest.php @@ -4,151 +4,150 @@ namespace Respect\Data\Styles\Plural; -use PDO, - Respect\Relational\Db, - Respect\Relational\Sql, - Respect\Data\Styles\Plural, - Respect\Relational\Mapper; +use PDO; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; +use Respect\Data\Styles\Plural; +use Respect\Relational\Db; +use Respect\Relational\Mapper; +use Respect\Relational\Sql; #[CoversClass(Plural::class)] class PluralTest extends TestCase { - /** - * @var Respect\Data\Styles\Plural - */ - private $style; + private Plural $style; - /** - * @var Respect\Relational\Mapper - */ - private $mapper; + private Mapper $mapper; - /** - * @var PDO - */ - private $conn; + private PDO $conn; private $posts; + private $authors; + private $comments; + private $categories; + private $postsCategories; protected function setUp(): void { - $conn = new PDO('sqlite::memory:'); $db = new Db($conn); $conn->exec( (string) Sql::createTable( 'posts', - array( + [ 'id INTEGER PRIMARY KEY', 'title VARCHAR(255)', 'text TEXT', 'author_id INTEGER', - ) - ) + ], + ), ); $conn->exec( (string) Sql::createTable( 'authors', - array( + [ 'id INTEGER PRIMARY KEY', - 'name VARCHAR(255)' - ) - ) + 'name VARCHAR(255)', + ], + ), ); $conn->exec( (string) Sql::createTable( 'comments', - array( + [ 'id INTEGER PRIMARY KEY', 'post_id INTEGER', 'text TEXT', - ) - ) + ], + ), ); $conn->exec( (string) Sql::createTable( 'categories', - array( + [ 'id INTEGER PRIMARY KEY', 'name VARCHAR(255)', - ) - ) + ], + ), ); $conn->exec( (string) Sql::createTable( 'posts_categories', - array( + [ 'id INTEGER PRIMARY KEY', 'post_id INTEGER', - 'category_id INTEGER' - ) - ) + 'category_id INTEGER', + ], + ), ); - $this->posts = array( - (object) array( + $this->posts = [ + (object) [ 'id' => 5, 'title' => 'Post Title', 'text' => 'Post Text', - 'author_id' => 1 - ) - ); - $this->authors = array( - (object) array( + 'author_id' => 1, + ], + ]; + $this->authors = [ + (object) [ 'id' => 1, - 'name' => 'Author 1' - ) - ); - $this->comments = array( - (object) array( + 'name' => 'Author 1', + ], + ]; + $this->comments = [ + (object) [ 'id' => 7, 'post_id' => 5, - 'text' => 'Comment Text' - ), - (object) array( + 'text' => 'Comment Text', + ], + (object) [ 'id' => 8, 'post_id' => 4, - 'text' => 'Comment Text 2' - ) - ); - $this->categories = array( - (object) array( + 'text' => 'Comment Text 2', + ], + ]; + $this->categories = [ + (object) [ 'id' => 2, - 'name' => 'Sample Category' - ), - (object) array( + 'name' => 'Sample Category', + ], + (object) [ 'id' => 3, - 'name' => 'NONON' - ) - ); - $this->postsCategories = array( - (object) array( + 'name' => 'NONON', + ], + ]; + $this->postsCategories = [ + (object) [ 'id' => 66, 'post_id' => 5, - 'category_id' => 2 - ) - ); + 'category_id' => 2, + ], + ]; - foreach ($this->authors as $author) + foreach ($this->authors as $author) { $db->insertInto('authors', (array) $author)->values((array) $author)->exec(); + } - foreach ($this->posts as $post) + foreach ($this->posts as $post) { $db->insertInto('posts', (array) $post)->values((array) $post)->exec(); + } - foreach ($this->comments as $comment) + foreach ($this->comments as $comment) { $db->insertInto('comments', (array) $comment)->values((array) $comment)->exec(); + } - foreach ($this->categories as $category) + foreach ($this->categories as $category) { $db->insertInto('categories', (array) $category)->values((array) $category)->exec(); + } - foreach ($this->postsCategories as $postCategory) + foreach ($this->postsCategories as $postCategory) { $db->insertInto('posts_categories', (array) $postCategory)->values((array) $postCategory)->exec(); + } $this->conn = $conn; $this->style = new Plural(); @@ -157,11 +156,6 @@ protected function setUp(): void $this->mapper->entityNamespace = __NAMESPACE__ . '\\'; } - protected function tearDown(): void - { - $this->style = null; - } - #[DataProvider('tableEntityProvider')] public function test_table_and_entities_methods($table, $entity): void { @@ -216,8 +210,8 @@ public function test_fetching_all_entity_typed_nested(): void $mapper = $this->mapper; $comment = $mapper->comments->posts->authors->fetchAll(); $this->assertInstanceOf(__NAMESPACE__ . '\Comment', $comment[0]); - $this->assertInstanceOf(__NAMESPACE__ . '\Post', $comment[0]->post_id); - $this->assertInstanceOf(__NAMESPACE__ . '\Author', $comment[0]->post_id->author_id); + $this->assertInstanceOf(__NAMESPACE__ . '\Post', $comment[0]->post_id); + $this->assertInstanceOf(__NAMESPACE__ . '\Author', $comment[0]->post_id->author_id); } public function test_persisting_entity_typed(): void @@ -245,45 +239,44 @@ public function test_persisting_new_entity_typed(): void public static function tableEntityProvider(): array { - return array( - array('posts', 'Post'), - array('comments', 'Comment'), - array('categories', 'Category'), - array('posts_categories', 'PostCategory'), - array('posts_tags', 'PostTag'), - ); + return [ + ['posts', 'Post'], + ['comments', 'Comment'], + ['categories', 'Category'], + ['posts_categories', 'PostCategory'], + ['posts_tags', 'PostTag'], + ]; } public static function manyToMantTableProvider(): array { - return array( - array('post', 'category', 'posts_categories'), - array('user', 'group', 'users_groups'), - array('group', 'profile', 'groups_profiles'), - ); + return [ + ['post', 'category', 'posts_categories'], + ['user', 'group', 'users_groups'], + ['group', 'profile', 'groups_profiles'], + ]; } public static function columnsPropertyProvider(): array { - return array( - array('id'), - array('text'), - array('name'), - array('content'), - array('created'), - ); + return [ + ['id'], + ['text'], + ['name'], + ['content'], + ['created'], + ]; } public static function foreignProvider(): array { - return array( - array('posts', 'post_id'), - array('authors', 'author_id'), - array('tags', 'tag_id'), - array('users', 'user_id'), - ); + return [ + ['posts', 'post_id'], + ['authors', 'author_id'], + ['tags', 'tag_id'], + ['users', 'user_id'], + ]; } - } class Post diff --git a/tests/Styles/SakilaTest.php b/tests/Styles/SakilaTest.php index c2c5721..c1a40bf 100644 --- a/tests/Styles/SakilaTest.php +++ b/tests/Styles/SakilaTest.php @@ -4,157 +4,155 @@ namespace Respect\Data\Styles\Sakila; -use PDO, - Respect\Relational\Db, - Respect\Relational\Sql, - Respect\Data\Styles\Sakila, - Respect\Relational\Mapper; +use PDO; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; +use Respect\Data\Styles\Sakila; +use Respect\Relational\Db; +use Respect\Relational\Mapper; +use Respect\Relational\Sql; #[CoversClass(Sakila::class)] class SakilaTest extends TestCase { + private Sakila $style; - /** - * @var Respect\Data\Styles\Sakila - */ - private $style; + private Mapper $mapper; - /** - * @var Respect\Relational\Mapper - */ - private $mapper; - - /** - * @var PDO - */ - private $conn; + private PDO $conn; private $posts; + private $authors; + private $comments; + private $categories; + private $postsCategories; protected function setUp(): void { - $conn = new PDO('sqlite::memory:'); $db = new Db($conn); $conn->exec( (string) Sql::createTable( 'post', - array( + [ 'post_id INTEGER PRIMARY KEY', 'title VARCHAR(255)', 'text TEXT', 'author_id INTEGER', - ) - ) + ], + ), ); $conn->exec( (string) Sql::createTable( 'author', - array( + [ 'author_id INTEGER PRIMARY KEY', - 'name VARCHAR(255)' - ) - ) + 'name VARCHAR(255)', + ], + ), ); $conn->exec( (string) Sql::createTable( 'comment', - array( + [ 'comment_id INTEGER PRIMARY KEY', 'post_id INTEGER', 'text TEXT', - ) - ) + ], + ), ); $conn->exec( (string) Sql::createTable( 'category', - array( + [ 'category_id INTEGER PRIMARY KEY', 'name VARCHAR(255)', 'content VARCHAR(255)', - 'description TEXT' - ) - ) + 'description TEXT', + ], + ), ); $conn->exec( (string) Sql::createTable( 'post_category', - array( + [ 'post_category_id INTEGER PRIMARY KEY', 'post_id INTEGER', - 'category_id INTEGER' - ) - ) + 'category_id INTEGER', + ], + ), ); - $this->posts = array( - (object) array( + $this->posts = [ + (object) [ 'post_id' => 5, 'title' => 'Post Title', 'text' => 'Post Text', - 'author_id' => 1 - ) - ); - $this->authors = array( - (object) array( 'author_id' => 1, - 'name' => 'Author 1' - ) - ); - $this->comments = array( - (object) array( + ], + ]; + $this->authors = [ + (object) [ + 'author_id' => 1, + 'name' => 'Author 1', + ], + ]; + $this->comments = [ + (object) [ 'comment_id' => 7, 'post_id' => 5, - 'text' => 'Comment Text' - ), - (object) array( + 'text' => 'Comment Text', + ], + (object) [ 'comment_id' => 8, 'post_id' => 4, - 'text' => 'Comment Text 2' - ) - ); - $this->categories = array( - (object) array( + 'text' => 'Comment Text 2', + ], + ]; + $this->categories = [ + (object) [ 'category_id' => 2, 'name' => 'Sample Category', - 'content' => null - ), - (object) array( + 'content' => null, + ], + (object) [ 'category_id' => 3, 'name' => 'NONON', - 'content' => null - ) - ); - $this->postsCategories = array( - (object) array( + 'content' => null, + ], + ]; + $this->postsCategories = [ + (object) [ 'post_category_id' => 66, 'post_id' => 5, - 'category_id' => 2 - ) - ); + 'category_id' => 2, + ], + ]; - foreach ($this->authors as $author) + foreach ($this->authors as $author) { $db->insertInto('author', (array) $author)->values((array) $author)->exec(); + } - foreach ($this->posts as $post) + foreach ($this->posts as $post) { $db->insertInto('post', (array) $post)->values((array) $post)->exec(); + } - foreach ($this->comments as $comment) + foreach ($this->comments as $comment) { $db->insertInto('comment', (array) $comment)->values((array) $comment)->exec(); + } - foreach ($this->categories as $category) + foreach ($this->categories as $category) { $db->insertInto('category', (array) $category)->values((array) $category)->exec(); + } - foreach ($this->postsCategories as $postCategory) + foreach ($this->postsCategories as $postCategory) { $db->insertInto('post_category', (array) $postCategory)->values((array) $postCategory)->exec(); + } $this->conn = $conn; $this->style = new Sakila(); @@ -165,43 +163,43 @@ protected function setUp(): void public static function tableEntityProvider(): array { - return array( - array('post', 'Post'), - array('comment', 'Comment'), - array('category', 'Category'), - array('post_category', 'PostCategory'), - array('post_tag', 'PostTag'), - ); + return [ + ['post', 'Post'], + ['comment', 'Comment'], + ['category', 'Category'], + ['post_category', 'PostCategory'], + ['post_tag', 'PostTag'], + ]; } public static function manyToMantTableProvider(): array { - return array( - array('post', 'category', 'post_category'), - array('user', 'group', 'user_group'), - array('group', 'profile', 'group_profile'), - ); + return [ + ['post', 'category', 'post_category'], + ['user', 'group', 'user_group'], + ['group', 'profile', 'group_profile'], + ]; } public static function columnsPropertyProvider(): array { - return array( - array('id'), - array('text'), - array('name'), - array('content'), - array('created'), - ); + return [ + ['id'], + ['text'], + ['name'], + ['content'], + ['created'], + ]; } public static function keyProvider(): array { - return array( - array('post', 'post_id'), - array('author', 'author_id'), - array('tag', 'tag_id'), - array('user', 'user_id'), - ); + return [ + ['post', 'post_id'], + ['author', 'author_id'], + ['tag', 'tag_id'], + ['user', 'user_id'], + ]; } #[DataProvider('tableEntityProvider')] @@ -258,8 +256,8 @@ public function test_fetching_all_entity_typed_nested(): void $mapper = $this->mapper; $comment = $mapper->comment->post->author->fetchAll(); $this->assertInstanceOf(__NAMESPACE__ . '\Comment', $comment[0]); - $this->assertInstanceOf(__NAMESPACE__ . '\Post', $comment[0]->post_id); - $this->assertInstanceOf(__NAMESPACE__ . '\Author', $comment[0]->post_id->author_id); + $this->assertInstanceOf(__NAMESPACE__ . '\Post', $comment[0]->post_id); + $this->assertInstanceOf(__NAMESPACE__ . '\Author', $comment[0]->post_id->author_id); } public function test_persisting_entity_typed(): void @@ -284,7 +282,6 @@ public function test_persisting_new_entity_typed(): void $result = $this->conn->query('select text from comment where comment_id=9')->fetchColumn(0); $this->assertEquals('HeyHey', $result); } - } class Post diff --git a/tests/Styles/StandardTest.php b/tests/Styles/StandardTest.php index 7cd6e8c..80e992e 100644 --- a/tests/Styles/StandardTest.php +++ b/tests/Styles/StandardTest.php @@ -11,63 +11,52 @@ #[CoversClass(Standard::class)] class StandardTest extends TestCase { + private Standard $style; - /** - * @var Respect\Data\Styles\Standard - */ - private $style; - + protected function setUp(): void + { + $this->style = new Standard(); + } public static function tableEntityProvider(): array { - return array( - array('post', 'Post'), - array('comment', 'Comment'), - array('category', 'Category'), - array('post_category', 'PostCategory'), - array('post_tag', 'PostTag'), - ); + return [ + ['post', 'Post'], + ['comment', 'Comment'], + ['category', 'Category'], + ['post_category', 'PostCategory'], + ['post_tag', 'PostTag'], + ]; } public static function manyToMantTableProvider(): array { - return array( - array('post', 'category', 'post_category'), - array('user', 'group', 'user_group'), - array('group', 'profile', 'group_profile'), - ); + return [ + ['post', 'category', 'post_category'], + ['user', 'group', 'user_group'], + ['group', 'profile', 'group_profile'], + ]; } public static function columnsPropertyProvider(): array { - return array( - array('id'), - array('text'), - array('name'), - array('content'), - array('created'), - ); + return [ + ['id'], + ['text'], + ['name'], + ['content'], + ['created'], + ]; } public static function foreignProvider(): array { - return array( - array('post', 'post_id'), - array('author', 'author_id'), - array('tag', 'tag_id'), - array('user', 'user_id'), - ); - } - - - protected function setUp(): void - { - $this->style = new Standard(); - } - - protected function tearDown(): void - { - $this->style = null; + return [ + ['post', 'post_id'], + ['author', 'author_id'], + ['tag', 'tag_id'], + ['user', 'user_id'], + ]; } #[DataProvider('tableEntityProvider')] @@ -100,5 +89,4 @@ public function test_foreign($table, $foreign): void $this->assertEquals($table, $this->style->remoteFromIdentifier($foreign)); $this->assertEquals($foreign, $this->style->remoteIdentifier($table)); } - }