From 5c814ec47121b3d86eef2634a9ccf94562ef3032 Mon Sep 17 00:00:00 2001 From: roxblnfk Date: Tue, 10 Dec 2024 14:39:17 +0400 Subject: [PATCH 1/6] Remove StyleCI config --- .styleci.yml | 73 ---------------------------------------------------- 1 file changed, 73 deletions(-) delete mode 100644 .styleci.yml diff --git a/.styleci.yml b/.styleci.yml deleted file mode 100644 index 6fde1340..00000000 --- a/.styleci.yml +++ /dev/null @@ -1,73 +0,0 @@ -preset: psr12 -risky: true - -version: 8 - -enabled: - - alpha_ordered_traits - - array_indentation - - array_push - - combine_consecutive_issets - - combine_consecutive_unsets - - combine_nested_dirname - - declare_strict_types - - dir_constant - - fully_qualified_strict_types - - function_to_constant - - is_null - - magic_constant_casing - - magic_method_casing - - method_separation - - modernize_types_casting - - native_function_casing - - native_function_type_declaration_casing - - no_alias_functions - - no_empty_comment - - no_empty_phpdoc - - no_empty_statement - - no_extra_block_blank_lines - - no_short_bool_cast - - no_superfluous_elseif - - no_unneeded_control_parentheses - - no_unneeded_curly_braces - - no_unneeded_final_method - - no_unset_cast - - no_unused_imports - - no_unused_lambda_imports - - no_useless_else - - no_useless_return - - normalize_index_brace - - php_unit_dedicate_assert - - php_unit_dedicate_assert_internal_type - - php_unit_expectation - - php_unit_mock - - php_unit_mock_short_will_return - - php_unit_namespaced - - php_unit_no_expectation_annotation - - phpdoc_no_empty_return - - phpdoc_no_useless_inheritdoc - - phpdoc_order - - phpdoc_property - - phpdoc_scalar - - phpdoc_separation - - phpdoc_singular_inheritdoc - - phpdoc_trim - - phpdoc_trim_consecutive_blank_line_separation - - phpdoc_type_to_var - - phpdoc_types - - phpdoc_types_order - - print_to_echo - - regular_callable_call - - return_assignment - - self_accessor - - self_static_accessor - - set_type_to_cast - - short_array_syntax - - short_list_syntax - - simplified_if_return - - single_quote - - standardize_not_equals - - ternary_to_null_coalescing - - trailing_comma_in_multiline_array - - unalign_double_arrow - - unalign_equals From 0702f32c5e93f6d18d9eefd518820ba563272526 Mon Sep 17 00:00:00 2001 From: roxblnfk Date: Tue, 10 Dec 2024 14:49:43 +0400 Subject: [PATCH 2/6] Configure metafiles --- .editorconfig | 10 +- .gitattributes | 11 +- .gitignore | 6 +- .php-cs-fixer.dist.php | 12 + composer.json | 12 + phpunit.xml | 1 + psalm-baseline.xml | 2473 ++++++++++++++++++++++++++++++++++++++++ psalm.xml | 9 +- 8 files changed, 2522 insertions(+), 12 deletions(-) create mode 100644 .php-cs-fixer.dist.php create mode 100644 psalm-baseline.xml diff --git a/.editorconfig b/.editorconfig index 5e253c70..558bf795 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,5 +1,3 @@ -# editorconfig.org - root = true [*] @@ -10,5 +8,11 @@ indent_style = space indent_size = 4 trim_trailing_whitespace = true -[*.yml] +[*.md] +trim_trailing_whitespace = false + +[*.{yml,yaml}] indent_size = 2 + +[Makefile] +indent_style = tab diff --git a/.gitattributes b/.gitattributes index fc911f3d..7a91380d 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,5 +1,6 @@ -/.github export-ignore -/.editorconfig export-ignore -/.gitattributes export-ignore -/.gitignore export-ignore -/tests export-ignore +/.* export-ignore +/tests export-ignore +/*.xml export-ignore +/*.yml export-ignore +/*.lock export-ignore +/*.dist export-ignore diff --git a/.gitignore b/.gitignore index 9557de92..b7032e0d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,8 @@ -.idea/ +/.idea/ +/runtime/ +/vendor/ .env composer.lock -vendor/ *.db clover.xml docker-compose.override.yml -.phpunit.result.cache diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php new file mode 100644 index 00000000..328c5b0d --- /dev/null +++ b/.php-cs-fixer.dist.php @@ -0,0 +1,12 @@ +include(__DIR__ . '/src') + ->include(__FILE__) + ->cache('./runtime/php-cs-fixer.cache') + ->allowRisky() + ->build(); diff --git a/composer.json b/composer.json index 89e89353..ea206d85 100644 --- a/composer.json +++ b/composer.json @@ -12,6 +12,7 @@ "docs": "https://cycle-orm.dev/docs", "chat": "https://discord.gg/spiralphp" }, + "keywords": ["mysql", "mssql", "sqlite", "postgresql", "orm", "sql", "query-builder", "data-mapper"], "authors": [ { "name": "Anton Titov (wolfy-j)", @@ -51,6 +52,7 @@ "phpunit/phpunit": "^9.5", "ramsey/uuid": "^4.0", "spiral/tokenizer": "^2.8 || ^3.0", + "spiral/code-style": "~2.2.0", "symfony/var-dumper": "^5.2 || ^6.0 || ^7.0", "vimeo/psalm": "5.21" }, @@ -63,5 +65,15 @@ "psr-4": { "Cycle\\ORM\\Tests\\": "tests/ORM/" } + }, + "config": { + "sort-packages": true + }, + "scripts": { + "cs:diff": "php-cs-fixer fix --dry-run -v --diff", + "cs:fix": "php-cs-fixer fix -v", + "psalm": "psalm", + "psalm:baseline": "psalm --set-baseline=psalm-baseline.xml", + "test": "phpunit --color=always" } } diff --git a/phpunit.xml b/phpunit.xml index bbc40674..a98f05fb 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -2,6 +2,7 @@ + + + + + + + $data, + $data instanceof \Traversable => \iterator_to_array($data), + default => throw new CollectionFactoryException('Unsupported iterable type.'), + }]]> + + + array + + + + + $data instanceof PivotedStorage + class, PivotedCollection::class)]]> + + + + getElements(), $data->getContext())]]> + + + Collection + + + getContext()]]> + + + $class === Collection::class ? ArrayCollection::class : $class + + + class, PivotedCollection::class)]]> + + + + + $class + + + class($data)]]> + + + + + $data instanceof PivotedStorage + class, LoophpPivotedCollection::class)]]> + + + getElements(), $data->getContext())]]> + + + CollectionInterface + + + getContext()]]> + + + $class === CollectionInterface::class ? Collection::class : $class + + + class, LoophpPivotedCollection::class)]]> + + + + + $elements + + + $elements + + + pivotContext]]> + + + LoophpPivotedCollection + LoophpPivotedCollection + + + parent::fromIterable($elements) + + + $iterable instanceof \Traversable ? \iterator_to_array($iterable) : $iterable + + + LoophpPivotedCollection + + + new static($iterable instanceof \Traversable ? \iterator_to_array($iterable) : $iterable) + + + + + pivotContext]]> + + + $elements + + + + + \IteratorAggregate + + + + + table]]> + + + + + primaryKeys[0]]]]> + + + $field + $field + \array_values($returning) + + + $value + + + array + columns, $this->mapper?->mapColumns($data) ?? $data)]]> + + + $insertID + + + table]]> + + + mapColumns + + + mapper->cast([$field => $insertID])[$field]]]> + + + mapper === null]]> + + + + + $primaryKeys + + + array + columns, + $this->mapper?->mapColumns($data) ?? $data + )]]> + + + table]]> + + + + + \IteratorAggregate + + + $value + + + + + \IteratorAggregate + + + + + $pkColumn + $table + + + $primaryKeys + + + $callable + $callable + + + afterExecute, null, static::class)($this->command)]]> + beforeExecute, null, static::class)($this->command)]]> + + + new static($command) + + + + + $command + + + $command + + + + + $db + + + + + $n + $n + $name + $name + + + waitScope]]> + + + [] + + + $n + $n + + + + + waitScope]]> + + + + + config[$type][self::LOADER])]]> + config[$type][self::RELATION])]]> + + + + + getLastError();]]> + + + $unitOfWork + + + + + $role + + + $relationStatus + $role + $tuple + + + getRelationStatus + getRole + getStatus + + + node]]> + state]]> + task]]> + + + + + Repository::class, + SchemaInterface::SOURCE => Source::class, + SchemaInterface::MAPPER => Mapper::class, + SchemaInterface::SCOPE => null, + SchemaInterface::TYPECAST_HANDLER => null, + ]]]> + + + config->getLoader($definition[Relation::TYPE])->resolve( + $this->factory, + [ + 'ormSchema' => $schema, + 'sourceProvider' => $sourceProvider, + 'factory' => $this, + 'role' => $role, + 'name' => $relation, + 'target' => $definition[Relation::TARGET], + 'schema' => $definition[Relation::SCHEMA], + ] + )]]> + config->getRelation($type)->resolve( + $this->factory, + [ + 'orm' => $orm, + 'role' => $role, + 'name' => $relation, + 'target' => $relSchema[Relation::TARGET], + 'schema' => $relSchema[Relation::SCHEMA] + + [Relation::LOAD => $relSchema[Relation::LOAD] ?? null] + + [Relation::COLLECTION_TYPE => $relSchema[Relation::COLLECTION_TYPE] ?? null], + ] + )]]> + + + $class + $class + $class + $definition[Relation::TYPE] + $handler + $parent + $parent + $parent + define($role, SchemaInterface::DATABASE)]]> + $table + $type + $type + + + $rules + $rules + + + $handler + $parent + $parent + $parent + $table + $type + $type + + + CollectionFactoryInterface + TypecastInterface + + + $class + $relSchema[Relation::SCHEMA] + + + defaults]]> + collectionFactoryAlias]]> + + + collectionFactoryAlias[$name] = $this->factory->make($name)]]> + factory->make($alias, $parameters)]]> + factory->make($handler, [ + 'database' => $database, + 'schema' => $schema, + 'role' => $role, + ])]]> + + + LoaderInterface + RelationInterface + + + $class + $class + getCode()]]> + + + + + SplObjectStorage + + + IteratorAggregate + + + $index + $indexName + $next[$value] + paths[$role]]]> + + + $indexName + $key + + + $next[$value] + $next[$value] + $next[$value] + $next[$value] + $removeFrom[$removeKey ?? $value] + $result[$value] + $rolePath[$value] + paths[$role][$indexName]]]> + paths[$role][$indexName]]]> + paths[$role][$indexName]]]> + paths[$role][$indexName]]]> + paths[$role][$indexName][$value]]]> + + + $rolePath[$value] + + + $data[$indexName] + $data[$k] + $scope[$key] + paths[$role][$indexName]]]> + + + $data[$indexName] + + + $index + $indexKeys + $indexName + $indexName + $indexName + $k + $key + $key + storage]]> + $values + $values + + + ?Node + ?object + + + $result + paths[$role][$indexName][$value] ?? null]]> + paths[$role][$indexName][$value] ?? null]]> + storage->offsetGet($entity)]]> + + + storage]]> + + + storage]]> + + + $next + $next + $next + $next + $removeFrom + + + getData + getData + offsetExists + offsetGet + offsetSet + offsetUnset + + + paths[$role][$indexName]]]> + paths[$role][$indexName]]]> + paths[$role][$indexName]]]> + + + $values + + + + + $name + rawData]]> + + + $changes[$name] + $value + + + getTransactionData()]]> + + + + + $column + + + $result[$field] + $result[$field] + $value + $value + $value + $value + + + + + waitingFields[$key] ?? false]]> + + + + + ]]> + + + entityFactory->make($role, $data, Node::MANAGED, typecast: $this->typecast)]]> + + + $data + $role + + + $data + + + + $data[LoaderInterface::ROLE_KEY] + + + + $data[$pk] + $id]]]> + + + $data + $data + $id + $index + $index + $pk + $role + + + TEntity + + + entityFactory->make($role, $data, Node::MANAGED, typecast: $this->typecast)]]> + + + ]]> + + + + + role]]> + + + columns + $this->parentColumns)]]> + + + $entity + $entity + + + $entity + $entity + + + + + $role + source->getTable()]]> + primaryColumns) === 1 ? $this->primaryColumns[0] : null]]> + + + $parent + + + $pk + $value + + + columns[$column]]]]> + columns[$PK]]]> + columns[\is_int($property) ? $column : $property]]]> + parentColumns[\is_int($property) ? $column : $property]]]> + + + $PK + $column + $column + $parent + $parent + $property + $property + columns[$column]]]]> + generatedFields]]> + $value + $value + + + primaryColumns]]> + define($role, SchemaInterface::PRIMARY_KEY)]]> + + + + + children]]> + discriminator]]> + entity]]> + + + + + classMap]]> + + + $key[0] + + + classMap[$role]]]> + + + [] + + + $class + classMap[$role]]]> + + + array + + + $currentData + + + $key + $key + + + $currentData + $currentData[$key] + $field + $relations + + $value + $value + + + array + array + + + new $class() + + + $relations + + + $currentData + $currentData + $relations + $result + + + class-string + + + + + + $relation + + + + + $objectOrClass + + + + + $property + $property + $property + $props + + + $class + $class + + + getRelations()[$property]]]> + + + $property + $property + $props + $props + $value + $value + + + Closure::bind($setter, null, $class)($object, $props, $data) + {$property} = $data[$property]; + unset($data[$property]); + } catch (\Throwable $e) { + if ($e::class === \TypeError::class) { + throw new MapperException( + "Can't hydrate an entity because property and value types are incompatible.", + previous: $e + ); + } + } + } + }, null, $class)($object, $props, $data)]]> + + + + + $properties + + + $properties + + + $class + ?string + + + + + $class + + + $key[0] + + + classProperties]]> + + + classProperties[$entity::class] ??= $this->propertiesExtractor + ->extract($entity, array_keys($relMap->getRelations()))]]> + + + PropertyMap[] + + + $currentData + + + $key + $key + $properties + + getRelations())]]> + + + $currentData + $currentData[$key] + $name + $properties + + $value + + + array + + + $currentData + $currentData + + + ]]> + entityToArray($entity), $relMap->getRelations())]]> + + + $pos + + + $pos + + + + initializer, null, $scope === '' ? $class : $scope)($proxy, $properties)]]> + + + classMap]]> + + + $relation + + + + + $entity + $entity + + + $entity + getValue()]]> + + + $v + + + object + + + $entity + + + + + children[$data[$this->discriminator]]]]> + + + $childClass + $class + $class + + + string + string + + + + + ]]> + + + + + resolveRole($entity)]]> + resolveRole($entity)]]> + resolveRole($entity)]]> + + + $this->entityFactory, + EntityProviderInterface::class => $this->entityProvider, + SourceProviderInterface::class => $this->sourceProvider, + TypecastProviderInterface::class => $this->typecastProvider, + IndexProviderInterface::class => $this->indexProvider, + MapperProviderInterface::class => $this->mapperProvider, + RelationProviderInterface::class => $this->relationProvider, + RepositoryProviderInterface::class => $this->repositoryProvider, + default => throw new InvalidArgumentException("Undefined service `$class`.") + }]]> + + + object + + + + + $item + static::OVERWRITE_DATA + + + $data[$key] + + + $item + $key + + + indexName]]> + + + results[] = &$data]]> + + + + + ParentMergeNode + + + push + + + $criteria + $index + $subset + $subset + $subset[$container] + + + $criteria + $criteria + $data + + + $subset[$container] + $subset[$container] + $subset[$container] + + + $subset[$container] + + + $data[$key] + $result[$key] + + + $index + $key + $result[$key] + $subset + $subset + $subset + + + mergeParent]]> + + + getCode()]]> + + + indexName]]> + + + getIndexes + getItemsCount + getItemsCount + getItemsSubset + getItemsSubset + hasIndex + hasIndex + hasIndex + hasIndex + hasIndex + + + empty($outerKeys) + + + + + + + + container]]> + indexName]]> + + + + + container]]> + indexName]]> + + + + + $keyValue + + + $pool[$keyValue] + $pool[$keyValue] + + + $deep + + + + + + $data + $key + $pool + data[$indexName]]]> + data[$index]]]> + data[$index]]]> + $value + $value + + + $pool[] + + + $data + $deep + $key + $key + $subset + $value + + + array + array + + + $deep + + + indexes]]> + + + lastItemKeys[$index]]]> + $value + + + data[$index]]]> + + + + + + + + result[] = &$data]]> + + + + + container]]> + indexName]]> + + + + + OVERWRITE_DATA + + + + + $zoom + + + $zoom[$criteria] + + + $zoom[$criteria] + + + $data[$key] + + + $data + $data + $key + + + duplicates]]> + + + + + + $rule::tryFrom((int)$value)]]> + + null + + + $key + $value + $value + + + $data[$column] + $data[$key] + $data[$key] + $data[$key] + $rule + $value + + + getCode()]]> + $value + + + $key + + + enumClasses]]> + + + + + origin->getValue()]]> + + + + + $role + + + $parent + $role + inversion]]> + + + bool + + + (array)$schema[Relation::INNER_KEY] + (array)$schema[Relation::OUTER_KEY] + + + schema[Relation::CASCADE] ?? false]]> + schema[Relation::CASCADE] ?? false]]> + + + $role + + + + + $related + $related + + + $nodeValue + $original + $prefill + $related + $related + $related + $related + $toReference[$outerKey] + outerKeys[$i]]]]> + + + + + $target + target]]> + target]]> + + + $related + + + $data + $field + + + $data[$key] + $original + $related + $related + $related + $scope[$key] + columns]]> + $value + $value + + + ?object + + + getSchema()->define($target, SchemaInterface::PRIMARY_KEY)]]> + + + getValue()]]> + + + mapperProvider->getMapper($this->target)->cast($data)]]> + ?array + + + resolve($related, true)]]> + + + empty($value) + + + + + $related + + + $item + $item + $item + $item + $item + $original ?? [] + $role + schema[Relation::COLLECTION_TYPE] ?? null]]> + schema[Relation::WHERE] ?? []]]> + + + $data + + + $item[LoaderInterface::ROLE_KEY] + + + $mappers[$role] + $mappers[$role] + + + $mappers[$role] + + + $item + $item + $item + $item + $item + $original + $related + $role + outerKeys[$i]]]]> + + + ?iterable + iterable + + + getValue()]]> + factory->collection( + $this->schema[Relation::COLLECTION_TYPE] ?? null + )->collect($data)]]> + + + $related + + + $original + + + !$data + + + [] + + + $node + + + + + $original + $original + $related + $related + + + $original + $original + $related + + + $rTuple + + + + + role]]> + target]]> + target]]> + + + \is_array($pivot) + + + make($this->pivotRole, $pivot, Node::MANAGED)]]> + entityFactory->make( + $this->schema[Relation::THROUGH_ENTITY], + $pivot, + Node::MANAGED, + typecast: true + )]]> + + + get($parent)]]> + + + $d + toArray()]]> + $entity + $entity + $entity + $entity + $item + $item + $original + getContext()->offsetGet($item)]]> + $pivot + $pivot + $pivotRole + $related + getResult()[0]['output']]]> + $row + $targetRole + schema[Relation::COLLECTION_TYPE] ?? null]]> + schema[Relation::THROUGH_ENTITY]]]> + + + $data + getPivotContext()]]> + toArray()]]> + $pivot + $pivot + $pivot ?? [] + (array)$data + schema[Relation::INNER_KEY]]]> + schema[Relation::INNER_KEY]]]> + iterator_to_array($data) + + + $d[LoaderInterface::ROLE_KEY] + + + $pivot[LoaderInterface::ROLE_KEY] + getResult()[0]['output']]]> + + + + $pivots[] + + + $pivotData[$entity] + $pivotData[$entity] + $pivotMappers[$pivotRole] + $pivotMappers[$pivotRole] + $targetMappers[$targetRole] + $targetMappers[$targetRole] + + + $pivotMappers[$pivotRole] + $targetMappers[$targetRole] + + + $d + $entity + $entity + $item + $item + $item + $original + $pivot + $pivot + $pivotRole + $pivots + $related + $related + $relatedStorage + $row + $scope[$key] + $targetRole + pivotRole]]> + + + ?iterable + iterable + + + get + + + schema[Relation::THROUGH_INNER_KEY]]]> + schema[Relation::THROUGH_OUTER_KEY]]]> + + + getValue()]]> + factory->collection( + $this->schema[Relation::COLLECTION_TYPE] ?? null + )->collect($data)]]> + + + $data + $pivot + + + $data + state]]> + $pivot + + + state]]> + + + (array)$data + + + !$data + + + toArray + + + $elements[] = $entity; + $elements[] = $entity; + + + $relatedNode + + + + + $related + $target + $target + + + $related + $target + morphKey]]> + + + + + morphKey]]> + + + + + $related + + + $related + morphKey]]> + + + parent::getReferenceScope($node) + + + + + $related + $related + + + $original + $related + $related + $related + + + + + $key + + + $data[$key] + + + $key + $key + + + $schema[Relation::TARGET] + + + + + $item + $related + + + $item + $related + $value + + + + + ?array + + + $role + + + $data + + + $role + outerKeys[$i]]]]> + + + ?object + object|iterable|null + + + mapperProvider->getMapper($role)?->cast($data)]]> + + + mapperProvider->getMapper($role)]]> + + + + + OrmInterface + + + $container + $item + $outerRelations + $parent + $parent + $relName + $relName + $relationSchema + $relationSchema[Relation::SCHEMA][Relation::THROUGH_ENTITY] + + + $name + $name + $name + $outerRole + (array)$relationSchema[Relation::SCHEMA][Relation::OUTER_KEY] + (array)$relationSchema[Relation::SCHEMA][Relation::THROUGH_OUTER_KEY] + + + $relationSchema[Relation::SCHEMA][Relation::OUTER_KEY] + $relationSchema[Relation::SCHEMA][Relation::THROUGH_ENTITY] + $relationSchema[Relation::SCHEMA][Relation::THROUGH_OUTER_KEY] + + + $relations[$relName] + + + $container + $innerRelations + $item + $outerRelations + $outerRelations + $parent + $parent + $relName + $relName + $relSchema + $relSchema + $relation + $relationSchema + $relationType + $relations + + + $relationSchema[Relation::TARGET] + + + $innerRelations + slaves]]> + + + dependencies]]> + ]]> + + + getInnerRelations + getInnerRelations + getOuterRelations + getOuterRelations + + + $relSchema + $relSchema + + + $outerRelations + + + + + $compareCallback === null + + + $child + $container + $container + $container + $inversion + $inversion + $inversion + $item[Relation::SCHEMA][Relation::THROUGH_ENTITY] + $item[self::ENTITY] + $item[self::PARENT] + $item[self::RELATIONS] + $relation + $target + $target + $target + $targetRelations + $targetRelations + define($role, self::RELATIONS)]]> + + + $key + $role + + + $entitySchema[SchemaInterface::RELATIONS] + $item[Relation::SCHEMA] + $item[Relation::SCHEMA] + $item[Relation::SCHEMA] + $item[Relation::SCHEMA] + $item[Relation::SCHEMA] + $item[Relation::SCHEMA] + $item[Relation::SCHEMA] + $item[Relation::SCHEMA] + $item[Relation::SCHEMA][Relation::CASCADE] + $item[Relation::SCHEMA][Relation::CASCADE] + $item[Relation::SCHEMA][Relation::INNER_KEY] + $item[Relation::SCHEMA][Relation::INVERSION] + $item[Relation::SCHEMA][Relation::OUTER_KEY] + $item[Relation::SCHEMA][Relation::THROUGH_ENTITY] + $item[Relation::SCHEMA][Relation::THROUGH_INNER_KEY] + $item[Relation::SCHEMA][Relation::THROUGH_OUTER_KEY] + $item[Relation::TARGET] + $item[Relation::TARGET] + $item[Relation::TYPE] + $item[self::CHILDREN] + $item[self::ENTITY] + $item[self::ENTITY] + $item[self::ENTITY] + $item[self::ENTITY] + $item[self::PARENT] + $item[self::PARENT] + $item[self::PARENT] + $item[self::RELATIONS] + $item[self::RELATIONS] + $item[self::ROLE] + $item[self::ROLE] + $rel[Relation::SCHEMA] + $rel[Relation::SCHEMA] + $rel[Relation::SCHEMA] + $rel[Relation::SCHEMA][Relation::NULLABLE] + $rel[Relation::SCHEMA][Relation::THROUGH_ENTITY] + $rel[Relation::TARGET] + $rel[Relation::TYPE] + $rel[Relation::TYPE] + $relation[Relation::SCHEMA] + $relation[Relation::SCHEMA][Relation::INVERSION] + $relation[Relation::TARGET] + $relations[$relation] + $schema[Relation::INNER_KEY] + $schema[Relation::INNER_KEY] + $schema[Relation::OUTER_KEY] + $schema[Relation::OUTER_KEY] + $schema[Relation::THROUGH_ENTITY] + $schema[Relation::THROUGH_WHERE] + $schema[Relation::WHERE] + $targetRelation[Relation::SCHEMA] + $targetRelation[Relation::TARGET] + $targetRelations[$inversion][Relation::SCHEMA] + $targetRelations[$inversion][Relation::SCHEMA][Relation::INVERSION] + $targetSchema[Relation::INNER_KEY] + $targetSchema[Relation::INNER_KEY] + $targetSchema[Relation::INVERSION] + $targetSchema[Relation::OUTER_KEY] + $targetSchema[Relation::OUTER_KEY] + $targetSchema[Relation::THROUGH_ENTITY] + $targetSchema[Relation::THROUGH_WHERE] + $targetSchema[Relation::WHERE] + $targetSchema[self::RELATIONS] + schema[$role][$property]]]> + + + $item[self::ENTITY] + $item[self::PARENT] + $item[self::RELATIONS] + $rel[Relation::SCHEMA] + $rel[Relation::SCHEMA][Relation::THROUGH_ENTITY] + $rel[Relation::TARGET] + $rel[Relation::TYPE] + $result[$role][self::RELATIONS] + $result[$role][self::RELATIONS][$container] + $result[$role][self::RELATIONS][$container][Relation::SCHEMA] + $result[$role][self::RELATIONS][$container][Relation::SCHEMA][Relation::INVERSION] + $result[$target][self::RELATIONS] + $result[$target][self::RELATIONS] + $result[$target][self::RELATIONS][$inversion] + $result[$target][self::RELATIONS][$inversion] + $result[$target][self::RELATIONS][$inversion][Relation::SCHEMA] + $result[$target][self::RELATIONS][$inversion][Relation::SCHEMA] + $result[$target][self::RELATIONS][$inversion][Relation::SCHEMA][Relation::INVERSION] + $result[$target][self::RELATIONS][$inversion][Relation::SCHEMA][Relation::INVERSION] + + + $aliases[$aliases[$child]] + $aliases[$child] + $aliases[$child] + $aliases[$item[self::ENTITY]] + $aliases[$parent] + $aliases[$target] + $aliases[$through] + $result[$roleName][$relName] + $result[$roleName][$relName] + $result[$role] + $result[$target] + $result[$target] + $result[$target] + + $result[$target][self::RELATIONS][$inversion] + aliases[$found]]]> + classes[$role]]]> + subclasses[$item[self::PARENT]]]]> + subclasses[$item[self::PARENT]][$role]]]> + subclasses[$role]]]> + subclasses[$role]]]> + + + $aliases[$parent] + subclasses[$role]]]> + subclasses[$role]]]> + + + $aliases[$aliases[$child]] + $aliases[$child] + $aliases[$item[self::ENTITY]] + $aliases[$key] + $child + $container + $entitySchema + $found + $found + $handshake + $item + $item + $item + $item + $item + $item + $item[self::PARENT] + $nullable + $nullable + $parent + $parent + $rel + $relName + $rel[Relation::SCHEMA][Relation::THROUGH_ENTITY] + $rel[Relation::TARGET] + $relation + $relations + $result[$roleName][$relName] + $result[$role] + $result[$target][self::RELATIONS][$inversion][Relation::SCHEMA][Relation::INVERSION] + $role + $role + $role + $role + $schema + $schema + aliases]]> + schema]]> + $target + $target + $target + $target + $targetHandshake + $targetRelation + $targetRelations + $targetSchema + $targetSchema + $targetSchema + $targetSchema + $through + $through + + + ?string + array + array + null|class-string + + + $relName + $target + + + classes]]> + subclasses]]> + subclasses]]> + subclasses]]> + subclasses]]> + + + $relations[$relation] + $role + classes[$rr] + ?? $this->schema[$rr][self::ENTITY] + ?? throw new SchemaException("Undefined schema `{$role}`, not found.")]]> + classes[$rr] + ?? $this->schema[$rr][self::ENTITY] + ?? throw new SchemaException("Undefined schema `{$role}`, not found.")]]> + schema[$role][SchemaInterface::RELATIONS] ?? []]]> + schema[$role][SchemaInterface::RELATIONS] ?? []]]> + + + $targetContainer + subclasses[$parent] ?? []]]> + ?string + array + + + subclasses[$item[self::PARENT]][$role] = &$this->subclasses[$role]]]> + + + $aliases + + + $nullable + + + + + $ids + loader->getTarget()]]> + loader->getTarget()]]> + + + entityFactory->make($this->loader->getTarget(), $data[0], Node::MANAGED, typecast: true)]]> + getIterator(), false)]]> + + + TEntity|null + ]]> + + + ]]> + + + IteratorAggregate + + + $data[0] + getResult()]]> + $subOption + $subOption + $options + + + $name + $name + + + $pk[$key] + + + $prepared[$index][$key] + $result + $subOption + $subOption + $value + $values + + + ]]> + + + $subOption + + + 1 + ? $this->__call('where', [$pk, new Parameter($ids)]) + : $this->__call('where', [$pk, current($ids)])]]> + + + getResult()]]> + heap, + $this->schema, + $this->entityFactory, + $this->loader->getTarget(), + $node->getResult(), + $findInHeap, + typecast: true + )]]> + ]]> + getResult())]]> + >]]> + + + getResult()]]> + + + + + $alias + + $query + $query + + + $relation + $relation + $relation + + + $schema[Relation::LOAD] + + + $loaders[$alias] + $loaders[$alias] + $loaders[$alias] + + + $loaders[$alias] + + + $alias + + $parent + $query + $relation + $relations + $schema + + + SelectQuery + + + $query + $query + + + $relation + + + $relation + + + loadChain + loadRelation + + + configureSubQuery + + + $alias + + + join]]> + load]]> + + + $children + + + + + $loader + + + $relation + $row + define(SchemaInterface::COLUMNS)]]> + factory->make($loader->options['scope'])]]> + options['minify']]]> + options['minify']]]> + schema[$key]]]> + schema[$key]]]> + + + $relation + $row + + + int + string + string + + + options['as']]]> + options['as']]]> + options['method']]]> + options['using']]]> + + + static + + + fieldAlias($this->schema[$key])]]> + parent->fieldAlias($this->schema[$key])]]> + + + getAlias + + + + + options['where'] ?? $this->schema[Relation::WHERE] ?? []]]> + + + columnNames()]]> + define(SchemaInterface::PRIMARY_KEY)]]> + schema[Relation::INNER_KEY]]]> + schema[Relation::OUTER_KEY]]]> + + + + + define(SchemaInterface::COLUMNS)]]> + options['minify'] ?? true]]> + + + columnNames()]]> + ormSchema->define($this->parent->getTarget(), SchemaInterface::PRIMARY_KEY)]]> + + + bool + + + options['load'] ?? false]]> + options['load'] ?? false]]> + + + getAlias + getTarget + isLoaded + + + isLoaded + + + + + options['orderBy'] ?? $this->schema[Relation::ORDER_BY] ?? []]]> + options['where'] ?? $this->schema[Relation::WHERE] ?? []]]> + + + columnNames()]]> + define(SchemaInterface::PRIMARY_KEY)]]> + schema[Relation::INNER_KEY]]]> + schema[Relation::OUTER_KEY]]]> + + + + + options['where'] ?? $this->schema[Relation::WHERE] ?? []]]> + + + columnNames()]]> + define(SchemaInterface::PRIMARY_KEY)]]> + schema[Relation::INNER_KEY]]]> + schema[Relation::OUTER_KEY]]]> + + + + + $loader + + + $key + $key + $key + $key + $outerKeyList[$i] + $outerKeys[0] + $parentKeys[$i] + $schema[Relation::THROUGH_ENTITY] + $set + options['orderBy'] ?? $this->schema[Relation::ORDER_BY] ?? []]]> + options['where'] ?? $this->schema[Relation::WHERE] ?? []]]> + $throughOuterKeys[$i] + $loader->isLoaded(), + 'method' => $options['method'] ?? self::JOIN, + ] + ($options['pivot'] ?? [])]]> + + + $relation + columnNames()]]> + define(SchemaInterface::PRIMARY_KEY)]]> + schema[Relation::OUTER_KEY]]]> + schema[Relation::THROUGH_OUTER_KEY]]]> + + + $key + $key + $key + $key + $set + + + + + + static + + + fieldAlias($key)]]> + fieldAlias($outerKeyList[$i])]]> + parent->fieldAlias($parentKeys[$i])]]> + pivot->fieldAlias($key)]]> + pivot->fieldAlias($key)]]> + pivot->fieldAlias($key)]]> + pivot->fieldAlias($throughOuterKeys[$i])]]> + + + getAlias + + + + + localKey(Relation::MORPH_KEY) => $this->parent->getTarget()]]]> + + + getTarget + + + + + localKey(Relation::MORPH_KEY) => $this->parent->getTarget()]]]> + + + getTarget + + + + + columnNames()]]> + define(SchemaInterface::PRIMARY_KEY)]]> + schema[Relation::INNER_KEY]]]> + schema[Relation::OUTER_KEY]]]> + + + + + options['where'] ?? $this->schema[Relation::THROUGH_WHERE] ?? []]]> + + + columnNames()]]> + define(SchemaInterface::PRIMARY_KEY)]]> + schema[Relation::INNER_KEY]]]> + schema[Relation::THROUGH_INNER_KEY]]]> + + + string + + + define(SchemaInterface::TABLE)]]> + + + + + $alias + $column + $key + $parentKeys[$i] + + + $alias + $column + $key + + + $alias + + + + $aliases + + + parent->fieldAlias($parentKeys[$i])]]> + + + getAlias + + + + + columnNames()]]> + define(SchemaInterface::PRIMARY_KEY)]]> + schema[Relation::INNER_KEY]]]> + schema[Relation::OUTER_KEY]]]> + + + + + $q + $q + + + $q + $q + + + $result[$k] + + + $current + $result + $result[$k] + $v + + + $split + + + $split + + + getParentLoader + + + + + + + + $id + + + $id + + + + + getEagerLoaders() as $relation) { + $this->loadRelation($relation, [], false, true); + }]]> + + + define(SchemaInterface::PRIMARY_KEY)]]> + + + $key + $pk + $relation + $row + define(SchemaInterface::COLUMNS)]]> + + + $relation + columnNames()]]> + define(SchemaInterface::PRIMARY_KEY)]]> + + + $key + $pk + $relation + $row + + + ]]> + + + fieldAlias($key)]]> + fieldAlias($pk)]]> + + + + + string + + + + + $position + + + $position + + + + + ]]> + + + columns[$p[0]]]]> + + + + + $key + $key + $key + $key + $key + $key + $key + $key + $key + $key + $outerKeys[0] + $parentKeys[$i] + $set + + + $key + $key + $set + + + fieldAlias($key)]]> + fieldAlias($key)]]> + parent->fieldAlias($parentKeys[$i])]]> + + + getAlias + + + + + SelectQuery + + + + + SelectQuery + + + + + $rRole + + + $role + + + $castedData + + + $data[$key] + $data[$pk] + $ids[$key] + $data[$pk]]]]> + + + $ids[$key] + $key + $pk + $role + + + hydrate($e, $relMap->init($this, $node, $castedData));]]> + hydrate($e, $relMap->init($this, $node, $castedData));]]> + + + $role + $role + + + $role + + + + + $role + + + + + $keys + + + $keys + $pk + + + array + + + indexes[$entity]]]> + + + + + $role + + + $role + + + + + $role + + + $role + + + relMaps]]> + + + + + $role + + + $select + + + $role + + + + + $entity + + + + + Transaction + + + getLastError();]]> + + + + + $commands + $parent + + + $parentKey[$i] + $pk + + + $parent + $parent + $pk + + + + + getRole() ?? $entity]]> + + + $item + + + $item + + + $priorityStorage + $unprocessed + + + Node|null + object + object + object + + + + + $cmd + + + $cmd + + + getDriver + + + DriverInterface + DriverInterface + + + + + $mapper + $node + $state + + + + + $iterators + + + $collection[$id] + + + entity)]]]> + + + $collection + $collection + + + iterators[\spl_object_id($cleaner)] = &$iterator]]> + + + + + getPrimaryCommand() : $command]]> + + + run()]]> + + + $name + + + static + + + run + + + Tuple + + + diff --git a/psalm.xml b/psalm.xml index eead5e5b..95b56cc5 100644 --- a/psalm.xml +++ b/psalm.xml @@ -1,9 +1,10 @@ @@ -25,4 +26,10 @@ + + + + + + From a78807feea7300dc62f624f36c22f58bd898033d Mon Sep 17 00:00:00 2001 From: roxblnfk Date: Tue, 10 Dec 2024 14:54:59 +0400 Subject: [PATCH 3/6] Apply code style --- psalm-baseline.xml | 146 ++++++++-------- src/Collection/DoctrineCollectionFactory.php | 16 +- .../IlluminateCollectionFactory.php | 8 +- src/Collection/LoophpCollectionFactory.php | 6 +- .../Pivoted/LoophpPivotedCollection.php | 23 ++- src/Collection/Pivoted/PivotedCollection.php | 13 +- .../Pivoted/PivotedCollectionInterface.php | 4 +- src/Collection/Pivoted/PivotedStorage.php | 16 +- src/Command/Database/Delete.php | 4 +- src/Command/Database/Insert.php | 4 +- src/Command/Database/Update.php | 10 +- src/Command/DatabaseCommand.php | 5 +- src/Command/Special/MergeCommand.php | 4 +- src/Command/Special/WrappedCommand.php | 23 ++- src/Command/StoreCommand.php | 3 +- src/Command/Traits/ErrorTrait.php | 6 +- src/Config/RelationConfig.php | 36 ++-- src/EntityProxyInterface.php | 4 +- src/Exception/BuilderException.php | 4 +- src/Exception/CollectionFactoryException.php | 4 +- src/Exception/CommandException.php | 4 +- src/Exception/ConfigException.php | 4 +- src/Exception/FactoryException.php | 4 +- src/Exception/FactoryTypecastException.php | 4 +- src/Exception/HeapException.php | 4 +- src/Exception/LoaderException.php | 4 +- src/Exception/MapperException.php | 4 +- src/Exception/ORMException.php | 4 +- src/Exception/ParserException.php | 4 +- src/Exception/PoolException.php | 4 +- src/Exception/PromiseException.php | 4 +- .../Relation/BadRelationValueException.php | 4 +- src/Exception/Relation/NullException.php | 4 +- src/Exception/RelationException.php | 4 +- src/Exception/RunnerException.php | 4 +- src/Exception/SchemaException.php | 4 +- src/Exception/SelectorException.php | 4 +- .../SuccessTransactionRetryException.php | 4 +- src/Exception/TransactionException.php | 4 +- src/Exception/TypecastException.php | 4 +- src/Factory.php | 48 +++--- src/FactoryInterface.php | 16 +- src/Heap/Heap.php | 65 ++++--- src/Heap/Node.php | 159 +++++++++--------- src/Heap/NullHeap.php | 12 +- src/Heap/State.php | 22 +-- src/Heap/Traits/RelationTrait.php | 2 +- src/Iterator.php | 20 +-- src/Mapper/ClasslessMapper.php | 8 +- src/Mapper/DatabaseMapper.php | 34 ++-- src/Mapper/Mapper.php | 8 +- src/Mapper/Proxy/ClasslessProxyFactory.php | 20 +-- src/Mapper/Proxy/ClasslessProxyTrait.php | 7 +- src/Mapper/Proxy/EntityProxyTrait.php | 16 +- .../Hydrator/ClassPropertiesExtractor.php | 16 +- src/Mapper/Proxy/Hydrator/ClosureHydrator.php | 11 +- src/Mapper/Proxy/Hydrator/PropertyMap.php | 5 +- src/Mapper/Proxy/ProxyEntityFactory.php | 50 +++--- src/Mapper/StdMapper.php | 12 +- src/Mapper/Traits/SingleTableTrait.php | 6 +- src/MapperInterface.php | 5 +- src/ORM.php | 65 ++++--- src/ORMInterface.php | 2 +- src/Parser/AbstractMergeNode.php | 14 +- src/Parser/AbstractNode.php | 43 +++-- src/Parser/ArrayNode.php | 7 +- src/Parser/EmbeddedNode.php | 2 +- src/Parser/MultiKeyCollection.php | 14 +- src/Parser/OutputNode.php | 14 +- src/Parser/SingularNode.php | 4 +- src/Parser/Traits/DuplicateTrait.php | 8 +- src/Parser/Typecast.php | 41 ++--- src/Reference/EmptyReference.php | 5 +- src/Reference/Promise.php | 5 +- src/Reference/Reference.php | 6 +- src/Relation/AbstractRelation.php | 23 ++- src/Relation/BelongsTo.php | 8 +- src/Relation/DependencyInterface.php | 4 +- src/Relation/Embedded.php | 56 +++--- src/Relation/HasMany.php | 34 ++-- src/Relation/ManyToMany.php | 51 +++--- src/Relation/Morphed/MorphedHasOne.php | 10 +- src/Relation/RefersTo.php | 2 +- src/Relation/ReversedRelationInterface.php | 4 +- src/Relation/SameRowRelationInterface.php | 2 +- src/Relation/ShadowBelongsTo.php | 7 +- src/Relation/ShadowHasMany.php | 18 +- src/Relation/Traits/ToOneTrait.php | 2 +- src/RelationMap.php | 70 ++++---- src/Schema.php | 63 +++---- src/Select.php | 108 ++++++------ src/Select/AbstractLoader.php | 78 ++++----- src/Select/JoinableLoader.php | 26 +-- src/Select/Loader/BelongsToLoader.php | 8 +- src/Select/Loader/EmbeddedLoader.php | 55 +++--- src/Select/Loader/HasManyLoader.php | 12 +- src/Select/Loader/HasOneLoader.php | 8 +- src/Select/Loader/ManyToManyLoader.php | 64 +++---- .../Loader/Morphed/MorphedHasManyLoader.php | 2 +- .../Loader/Morphed/MorphedHasOneLoader.php | 2 +- src/Select/Loader/ParentLoader.php | 18 +- src/Select/Loader/PivotLoader.php | 8 +- src/Select/Loader/SubQueryLoader.php | 13 +- src/Select/Loader/SubclassLoader.php | 8 +- src/Select/QueryBuilder.php | 58 +++---- src/Select/QueryScope.php | 5 +- src/Select/Repository.php | 19 +-- src/Select/RootLoader.php | 27 ++- src/Select/Source.php | 5 +- src/Select/Traits/ChainTrait.php | 10 +- src/Select/Traits/ColumnsTrait.php | 2 +- src/Select/Traits/JoinOneTableTrait.php | 16 +- src/Select/Traits/ScopeTrait.php | 2 +- src/Select/Traits/WhereTrait.php | 5 +- src/Service/Implementation/EntityFactory.php | 7 +- src/Service/Implementation/EntityProvider.php | 3 +- src/Service/Implementation/IndexProvider.php | 7 +- src/Service/Implementation/MapperProvider.php | 5 +- .../Implementation/RelationProvider.php | 3 +- .../Implementation/RepositoryProvider.php | 5 +- src/Service/Implementation/SourceProvider.php | 3 +- .../Implementation/TypecastProvider.php | 5 +- src/Transaction.php | 5 +- src/Transaction/CommandGenerator.php | 14 +- src/Transaction/Pool.php | 65 ++++--- src/Transaction/Runner.php | 62 ++++--- src/Transaction/StateInterface.php | 4 +- src/Transaction/Tuple.php | 5 +- src/Transaction/TupleStorage.php | 5 +- src/Transaction/UnitOfWork.php | 13 +- 130 files changed, 1085 insertions(+), 1230 deletions(-) diff --git a/psalm-baseline.xml b/psalm-baseline.xml index f4aeef02..4e87c6ab 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -18,7 +18,7 @@ $data instanceof PivotedStorage - class, PivotedCollection::class)]]> + class, PivotedCollection::class)]]> @@ -34,7 +34,7 @@ $class === Collection::class ? ArrayCollection::class : $class - class, PivotedCollection::class)]]> + class, PivotedCollection::class)]]> @@ -124,8 +124,8 @@ $value + columns, $this->mapper?->mapColumns($data) ?? $data)]]> array - columns, $this->mapper?->mapColumns($data) ?? $data)]]> $insertID @@ -148,11 +148,11 @@ $primaryKeys - array - columns, - $this->mapper?->mapColumns($data) ?? $data + $this->mapper?->mapColumns($data) ?? $data, )]]> + array table]]> @@ -184,8 +184,8 @@ $callable - afterExecute, null, static::class)($this->command)]]> - beforeExecute, null, static::class)($this->command)]]> + afterExecute, null, static::class)($this->command)]]> + beforeExecute, null, static::class)($this->command)]]> new static($command) @@ -282,7 +282,7 @@ 'name' => $relation, 'target' => $definition[Relation::TARGET], 'schema' => $definition[Relation::SCHEMA], - ] + ], )]]> config->getRelation($type)->resolve( $this->factory, @@ -294,7 +294,7 @@ 'schema' => $relSchema[Relation::SCHEMA] + [Relation::LOAD => $relSchema[Relation::LOAD] ?? null] + [Relation::COLLECTION_TYPE => $relSchema[Relation::COLLECTION_TYPE] ?? null], - ] + ], )]]> @@ -357,10 +357,10 @@ - SplObjectStorage + \SplObjectStorage - IteratorAggregate + \IteratorAggregate $index @@ -484,7 +484,7 @@ - ]]> + ]]> entityFactory->make($role, $data, Node::MANAGED, typecast: $this->typecast)]]> @@ -521,7 +521,7 @@ entityFactory->make($role, $data, Node::MANAGED, typecast: $this->typecast)]]> - ]]> + ]]> @@ -529,7 +529,7 @@ role]]> - columns + $this->parentColumns)]]> + columns + $this->parentColumns)]]> $entity @@ -574,7 +574,7 @@ primaryColumns]]> - define($role, SchemaInterface::PRIMARY_KEY)]]> + define($role, SchemaInterface::PRIMARY_KEY)]]> @@ -616,7 +616,7 @@ $currentData[$key] $field $relations - + $value $value @@ -639,7 +639,7 @@ class-string - + $relation @@ -673,10 +673,10 @@ $value - Closure::bind($setter, null, $class)($object, $props, $data) - \Closure::bind($setter, null, $class)($object, $props, $data) + classProperties[$entity::class] ??= $this->propertiesExtractor - ->extract($entity, array_keys($relMap->getRelations()))]]> + ->extract($entity, \array_keys($relMap->getRelations()))]]> PropertyMap[] @@ -733,14 +733,14 @@ $key $properties - getRelations())]]> + getRelations())]]> $currentData $currentData[$key] $name $properties - + $value @@ -751,18 +751,18 @@ $currentData + entityToArray($entity), $relMap->getRelations())]]> ]]> - entityToArray($entity), $relMap->getRelations())]]> $pos $pos - + - initializer, null, $scope === '' ? $class : $scope)($proxy, $properties)]]> + initializer, null, $scope === '' ? $class : $scope)($proxy, $properties)]]> classMap]]> @@ -825,7 +825,7 @@ MapperProviderInterface::class => $this->mapperProvider, RelationProviderInterface::class => $this->relationProvider, RepositoryProviderInterface::class => $this->repositoryProvider, - default => throw new InvalidArgumentException("Undefined service `$class`.") + default => throw new \InvalidArgumentException("Undefined service `$class`."), }]]> @@ -1028,7 +1028,7 @@ $rule::tryFrom((int)$value)]]> + => $rule::tryFrom((int) $value)]]> null @@ -1074,8 +1074,8 @@ bool - (array)$schema[Relation::INNER_KEY] - (array)$schema[Relation::OUTER_KEY] + (array) $schema[Relation::INNER_KEY] + (array) $schema[Relation::OUTER_KEY] schema[Relation::CASCADE] ?? false]]> @@ -1130,7 +1130,7 @@ ?object - getSchema()->define($target, SchemaInterface::PRIMARY_KEY)]]> + getSchema()->define($target, SchemaInterface::PRIMARY_KEY)]]> getValue()]]> @@ -1194,7 +1194,7 @@ getValue()]]> factory->collection( - $this->schema[Relation::COLLECTION_TYPE] ?? null + $this->schema[Relation::COLLECTION_TYPE] ?? null, )->collect($data)]]> @@ -1244,7 +1244,7 @@ $this->schema[Relation::THROUGH_ENTITY], $pivot, Node::MANAGED, - typecast: true + typecast: true, )]]> @@ -1278,10 +1278,10 @@ $pivot $pivot $pivot ?? [] - (array)$data - schema[Relation::INNER_KEY]]]> - schema[Relation::INNER_KEY]]]> - iterator_to_array($data) + (array) $data + schema[Relation::INNER_KEY]]]> + schema[Relation::INNER_KEY]]]> + \iterator_to_array($data) $d[LoaderInterface::ROLE_KEY] @@ -1334,13 +1334,13 @@ get - schema[Relation::THROUGH_INNER_KEY]]]> - schema[Relation::THROUGH_OUTER_KEY]]]> + schema[Relation::THROUGH_INNER_KEY]]]> + schema[Relation::THROUGH_OUTER_KEY]]]> getValue()]]> factory->collection( - $this->schema[Relation::COLLECTION_TYPE] ?? null + $this->schema[Relation::COLLECTION_TYPE] ?? null, )->collect($data)]]> @@ -1356,7 +1356,7 @@ state]]> - (array)$data + (array) $data !$data @@ -1484,8 +1484,8 @@ $name $name $outerRole - (array)$relationSchema[Relation::SCHEMA][Relation::OUTER_KEY] - (array)$relationSchema[Relation::SCHEMA][Relation::THROUGH_OUTER_KEY] + (array) $relationSchema[Relation::SCHEMA][Relation::OUTER_KEY] + (array) $relationSchema[Relation::SCHEMA][Relation::THROUGH_OUTER_KEY] $relationSchema[Relation::SCHEMA][Relation::OUTER_KEY] @@ -1797,7 +1797,7 @@ ]]> - IteratorAggregate + \IteratorAggregate $data[0] @@ -1829,7 +1829,7 @@ 1 ? $this->__call('where', [$pk, new Parameter($ids)]) - : $this->__call('where', [$pk, current($ids)])]]> + : $this->__call('where', [$pk, \current($ids)])]]> getResult()]]> @@ -1840,7 +1840,7 @@ $this->loader->getTarget(), $node->getResult(), $findInHeap, - typecast: true + typecast: true, )]]> ]]> getResult())]]> @@ -1959,9 +1959,9 @@ columnNames()]]> - define(SchemaInterface::PRIMARY_KEY)]]> - schema[Relation::INNER_KEY]]]> - schema[Relation::OUTER_KEY]]]> + define(SchemaInterface::PRIMARY_KEY)]]> + schema[Relation::INNER_KEY]]]> + schema[Relation::OUTER_KEY]]]> @@ -1971,7 +1971,7 @@ columnNames()]]> - ormSchema->define($this->parent->getTarget(), SchemaInterface::PRIMARY_KEY)]]> + ormSchema->define($this->parent->getTarget(), SchemaInterface::PRIMARY_KEY)]]> bool @@ -1996,9 +1996,9 @@ columnNames()]]> - define(SchemaInterface::PRIMARY_KEY)]]> - schema[Relation::INNER_KEY]]]> - schema[Relation::OUTER_KEY]]]> + define(SchemaInterface::PRIMARY_KEY)]]> + schema[Relation::INNER_KEY]]]> + schema[Relation::OUTER_KEY]]]> @@ -2007,9 +2007,9 @@ columnNames()]]> - define(SchemaInterface::PRIMARY_KEY)]]> - schema[Relation::INNER_KEY]]]> - schema[Relation::OUTER_KEY]]]> + define(SchemaInterface::PRIMARY_KEY)]]> + schema[Relation::INNER_KEY]]]> + schema[Relation::OUTER_KEY]]]> @@ -2037,9 +2037,9 @@ $relation columnNames()]]> - define(SchemaInterface::PRIMARY_KEY)]]> - schema[Relation::OUTER_KEY]]]> - schema[Relation::THROUGH_OUTER_KEY]]]> + define(SchemaInterface::PRIMARY_KEY)]]> + schema[Relation::OUTER_KEY]]]> + schema[Relation::THROUGH_OUTER_KEY]]]> $key @@ -2086,9 +2086,9 @@ columnNames()]]> - define(SchemaInterface::PRIMARY_KEY)]]> - schema[Relation::INNER_KEY]]]> - schema[Relation::OUTER_KEY]]]> + define(SchemaInterface::PRIMARY_KEY)]]> + schema[Relation::INNER_KEY]]]> + schema[Relation::OUTER_KEY]]]> @@ -2097,9 +2097,9 @@ columnNames()]]> - define(SchemaInterface::PRIMARY_KEY)]]> - schema[Relation::INNER_KEY]]]> - schema[Relation::THROUGH_INNER_KEY]]]> + define(SchemaInterface::PRIMARY_KEY)]]> + schema[Relation::INNER_KEY]]]> + schema[Relation::THROUGH_INNER_KEY]]]> string @@ -2137,9 +2137,9 @@ columnNames()]]> - define(SchemaInterface::PRIMARY_KEY)]]> - schema[Relation::INNER_KEY]]]> - schema[Relation::OUTER_KEY]]]> + define(SchemaInterface::PRIMARY_KEY)]]> + schema[Relation::INNER_KEY]]]> + schema[Relation::OUTER_KEY]]]> @@ -2170,7 +2170,7 @@ getParentLoader - + @@ -2188,7 +2188,7 @@ }]]> - define(SchemaInterface::PRIMARY_KEY)]]> + define(SchemaInterface::PRIMARY_KEY)]]> $key @@ -2200,7 +2200,7 @@ $relation columnNames()]]> - define(SchemaInterface::PRIMARY_KEY)]]> + define(SchemaInterface::PRIMARY_KEY)]]> $key diff --git a/src/Collection/DoctrineCollectionFactory.php b/src/Collection/DoctrineCollectionFactory.php index 24fd7904..1b95400d 100644 --- a/src/Collection/DoctrineCollectionFactory.php +++ b/src/Collection/DoctrineCollectionFactory.php @@ -20,21 +20,21 @@ */ final class DoctrineCollectionFactory implements CollectionFactoryInterface { + /** @var class-string */ + private string $class = ArrayCollection::class; + public function __construct() { - if (!class_exists(ArrayCollection::class, true)) { + if (!\class_exists(ArrayCollection::class, true)) { throw new CollectionFactoryException( - sprintf( + \sprintf( 'There is no %s class. To resolve this issue you can install `doctrine/collections` package.', - ArrayCollection::class - ) + ArrayCollection::class, + ), ); } } - /** @var class-string */ - private string $class = ArrayCollection::class; - public function getInterface(): ?string { return Collection::class; @@ -54,7 +54,7 @@ public function collect(iterable $data): Collection return new PivotedCollection($data->getElements(), $data->getContext()); } - if (is_a($this->class, PivotedCollection::class)) { + if (\is_a($this->class, PivotedCollection::class)) { return new $this->class($data->getElements(), $data->getContext()); } } diff --git a/src/Collection/IlluminateCollectionFactory.php b/src/Collection/IlluminateCollectionFactory.php index 799e1b7a..148676e0 100644 --- a/src/Collection/IlluminateCollectionFactory.php +++ b/src/Collection/IlluminateCollectionFactory.php @@ -19,12 +19,12 @@ final class IlluminateCollectionFactory implements CollectionFactoryInterface public function __construct() { - if (!class_exists(Collection::class, true)) { + if (!\class_exists(Collection::class, true)) { throw new CollectionFactoryException( - sprintf( + \sprintf( 'There is no %s class. To resolve this issue you can install `illuminate/collections` package.', - Collection::class - ) + Collection::class, + ), ); } } diff --git a/src/Collection/LoophpCollectionFactory.php b/src/Collection/LoophpCollectionFactory.php index 99add7a4..247ae398 100644 --- a/src/Collection/LoophpCollectionFactory.php +++ b/src/Collection/LoophpCollectionFactory.php @@ -29,8 +29,8 @@ public function __construct() throw new CollectionFactoryException( \sprintf( 'There is no %s class. To resolve this issue you can install `loophp/collection` package.', - Collection::class - ) + Collection::class, + ), ); } @@ -59,7 +59,7 @@ public function withCollectionClass(string $class): static if ($class !== Collection::class) { throw new CollectionFactoryException(\sprintf( 'Unsupported collection class `%s`.', - $class + $class, )); } diff --git a/src/Collection/Pivoted/LoophpPivotedCollection.php b/src/Collection/Pivoted/LoophpPivotedCollection.php index 5c5ddc41..86065c73 100644 --- a/src/Collection/Pivoted/LoophpPivotedCollection.php +++ b/src/Collection/Pivoted/LoophpPivotedCollection.php @@ -6,7 +6,6 @@ use loophp\collection\Collection; use loophp\collection\CollectionDecorator; -use SplObjectStorage; /** * Collection with associated relation context. Attention, pivot context is lost when collection is partitioned or @@ -22,17 +21,22 @@ */ class LoophpPivotedCollection extends CollectionDecorator implements PivotedCollectionInterface, \Countable { - /** @var SplObjectStorage */ - protected SplObjectStorage $pivotContext; + /** @var \SplObjectStorage */ + protected \SplObjectStorage $pivotContext; /** * @param array $elements - * @param SplObjectStorage|null $pivotData + * @param \SplObjectStorage|null $pivotData */ - final public function __construct(array $elements = [], SplObjectStorage $pivotData = null) + final public function __construct(array $elements = [], ?\SplObjectStorage $pivotData = null) { parent::__construct(Collection::fromIterable($elements)); - $this->pivotContext = $pivotData ?? new SplObjectStorage(); + $this->pivotContext = $pivotData ?? new \SplObjectStorage(); + } + + public static function fromIterable(iterable $iterable): static + { + return new static($iterable instanceof \Traversable ? \iterator_to_array($iterable) : $iterable); } public function hasPivot(object $element): bool @@ -50,7 +54,7 @@ public function setPivot(object $element, mixed $pivot): void $this->pivotContext[$element] = $pivot; } - public function getPivotContext(): SplObjectStorage + public function getPivotContext(): \SplObjectStorage { return $this->pivotContext; } @@ -60,11 +64,6 @@ public function count(): int return \iterator_count($this->innerCollection); } - public static function fromIterable(iterable $iterable): static - { - return new static($iterable instanceof \Traversable ? \iterator_to_array($iterable) : $iterable); - } - /** * @param array $elements * diff --git a/src/Collection/Pivoted/PivotedCollection.php b/src/Collection/Pivoted/PivotedCollection.php index 71039103..26dc701e 100644 --- a/src/Collection/Pivoted/PivotedCollection.php +++ b/src/Collection/Pivoted/PivotedCollection.php @@ -5,7 +5,6 @@ namespace Cycle\ORM\Collection\Pivoted; use Doctrine\Common\Collections\ArrayCollection; -use SplObjectStorage; /** * Collection with associated relation context. Attention, pivot context is lost when collection is partitioned or @@ -21,17 +20,17 @@ */ class PivotedCollection extends ArrayCollection implements PivotedCollectionInterface { - /** @var SplObjectStorage */ - protected SplObjectStorage $pivotContext; + /** @var \SplObjectStorage */ + protected \SplObjectStorage $pivotContext; /** * @param array $elements - * @param SplObjectStorage|null $pivotData + * @param \SplObjectStorage|null $pivotData */ - final public function __construct(array $elements = [], SplObjectStorage $pivotData = null) + final public function __construct(array $elements = [], ?\SplObjectStorage $pivotData = null) { parent::__construct($elements); - $this->pivotContext = $pivotData ?? new SplObjectStorage(); + $this->pivotContext = $pivotData ?? new \SplObjectStorage(); } public function hasPivot(object $element): bool @@ -49,7 +48,7 @@ public function setPivot(object $element, mixed $pivot): void $this->pivotContext[$element] = $pivot; } - public function getPivotContext(): SplObjectStorage + public function getPivotContext(): \SplObjectStorage { return $this->pivotContext; } diff --git a/src/Collection/Pivoted/PivotedCollectionInterface.php b/src/Collection/Pivoted/PivotedCollectionInterface.php index fd446ca4..1cab4b18 100644 --- a/src/Collection/Pivoted/PivotedCollectionInterface.php +++ b/src/Collection/Pivoted/PivotedCollectionInterface.php @@ -4,8 +4,6 @@ namespace Cycle\ORM\Collection\Pivoted; -use SplObjectStorage; - /** * Carries pivot data associated with each element. * @@ -41,5 +39,5 @@ public function setPivot(object $element, mixed $pivot): void; /** * Get all associated pivot data. */ - public function getPivotContext(): SplObjectStorage; + public function getPivotContext(): \SplObjectStorage; } diff --git a/src/Collection/Pivoted/PivotedStorage.php b/src/Collection/Pivoted/PivotedStorage.php index 94de3f8c..4c49e3b6 100644 --- a/src/Collection/Pivoted/PivotedStorage.php +++ b/src/Collection/Pivoted/PivotedStorage.php @@ -4,8 +4,6 @@ namespace Cycle\ORM\Collection\Pivoted; -use SplObjectStorage; - /** * Carry information about ordered list of entities and associated pivot context. * @@ -17,17 +15,17 @@ class PivotedStorage implements \IteratorAggregate, \Countable /** @var TEntity[] */ private array $elements; - /** @var SplObjectStorage */ - private SplObjectStorage $context; + /** @var \SplObjectStorage */ + private \SplObjectStorage $context; /** * @param TEntity[] $elements - * @param SplObjectStorage|null $context + * @param \SplObjectStorage|null $context */ - public function __construct(array $elements = [], SplObjectStorage $context = null) + public function __construct(array $elements = [], ?\SplObjectStorage $context = null) { $this->elements = $elements; - $this->context = $context ?? new SplObjectStorage(); + $this->context = $context ?? new \SplObjectStorage(); } /** @@ -43,7 +41,7 @@ public function getIterator(): \Generator yield from $this->getElements(); } - public function getContext(): SplObjectStorage + public function getContext(): \SplObjectStorage { return $this->context; } @@ -53,7 +51,7 @@ public function getContext(): SplObjectStorage */ public function has(object $entity): bool { - return in_array($entity, $this->elements, true); + return \in_array($entity, $this->elements, true); } /** diff --git a/src/Command/Database/Delete.php b/src/Command/Database/Delete.php index 3f5e36cf..bf30acbc 100644 --- a/src/Command/Database/Delete.php +++ b/src/Command/Database/Delete.php @@ -25,7 +25,7 @@ public function __construct( DatabaseInterface $db, string $table, private State $state, - ?MapperInterface $mapper + ?MapperInterface $mapper, ) { parent::__construct($db, $table); $this->mapper = $mapper; @@ -49,7 +49,7 @@ public function execute(): void $this->affectedRows = $this->db->delete( $this->table, - $this->prepareData($scope) + $this->prepareData($scope), )->run(); $this->state->setStatus(Node::DELETED); diff --git a/src/Command/Database/Insert.php b/src/Command/Database/Insert.php index 2e3fe6b5..d2b48827 100644 --- a/src/Command/Database/Insert.php +++ b/src/Command/Database/Insert.php @@ -62,7 +62,7 @@ public function getStoreData(): array $this->appendix = []; } $data = $this->state->getData(); - return array_merge($this->columns, $this->mapper?->mapColumns($data) ?? $data); + return \array_merge($this->columns, $this->mapper?->mapColumns($data) ?? $data); } /** @@ -135,7 +135,7 @@ public function execute(): void if (!isset($data[$fpk])) { $state->register( $fpk, - $this->mapper === null ? $insertID : $this->mapper->cast([$fpk => $insertID])[$fpk] + $this->mapper === null ? $insertID : $this->mapper->cast([$fpk => $insertID])[$fpk], ); } } diff --git a/src/Command/Database/Update.php b/src/Command/Database/Update.php index 7066b1e2..0cc6e615 100644 --- a/src/Command/Database/Update.php +++ b/src/Command/Database/Update.php @@ -31,7 +31,7 @@ public function __construct( State $state, ?MapperInterface $mapper, /** @var string[] */ - array $primaryKeys + array $primaryKeys, ) { parent::__construct($db, $table, $state); $this->mapper = $mapper; @@ -68,9 +68,9 @@ public function getStoreData(): array $data = $this->state->getChanges(); - return array_merge( + return \array_merge( $this->columns, - $this->mapper?->mapColumns($data) ?? $data + $this->mapper?->mapColumns($data) ?? $data, ); } @@ -96,13 +96,13 @@ public function execute(): void ->update( $this->table, \array_merge($this->columns, $data), - $this->prepareData($scope) + $this->prepareData($scope), ) ->run(); } $this->state->updateTransactionData( - $fields !== [] && \count($fields) === \count($allChanges) ? null : $fields + $fields !== [] && \count($fields) === \count($allChanges) ? null : $fields, ); parent::execute(); diff --git a/src/Command/DatabaseCommand.php b/src/Command/DatabaseCommand.php index 512039ad..def57b16 100644 --- a/src/Command/DatabaseCommand.php +++ b/src/Command/DatabaseCommand.php @@ -13,9 +13,8 @@ abstract class DatabaseCommand implements CommandInterface public function __construct( /** @internal */ protected DatabaseInterface $db, - protected ?string $table = null - ) { - } + protected ?string $table = null, + ) {} public function getDatabase(): ?DatabaseInterface { diff --git a/src/Command/Special/MergeCommand.php b/src/Command/Special/MergeCommand.php index 9c6caa58..1f67f3ca 100644 --- a/src/Command/Special/MergeCommand.php +++ b/src/Command/Special/MergeCommand.php @@ -28,9 +28,9 @@ public function __construct(CommandInterface $primary) $primary = $primary->getPrimaryCommand(); } if (!$primary instanceof StoreCommandInterface) { - throw new \InvalidArgumentException(sprintf( + throw new \InvalidArgumentException(\sprintf( 'Parameter `$primary` must be instance of %s.', - StoreCommandInterface::class + StoreCommandInterface::class, )); } $this->primary = $primary; diff --git a/src/Command/Special/WrappedCommand.php b/src/Command/Special/WrappedCommand.php index 99610c37..bc4078b0 100644 --- a/src/Command/Special/WrappedCommand.php +++ b/src/Command/Special/WrappedCommand.php @@ -4,7 +4,6 @@ namespace Cycle\ORM\Command\Special; -use Closure; use Cycle\ORM\Command\CommandInterface; use Cycle\ORM\Command\Database\Insert; use Cycle\ORM\Command\Database\Update; @@ -14,14 +13,12 @@ class WrappedCommand implements CommandInterface { - private ?Closure $beforeExecute = null; - - private ?Closure $afterExecute = null; + private ?\Closure $beforeExecute = null; + private ?\Closure $afterExecute = null; protected function __construct( - protected CommandInterface $command - ) { - } + protected CommandInterface $command, + ) {} public static function createInsert( DatabaseInterface $db, @@ -29,7 +26,7 @@ public static function createInsert( State $state, ?MapperInterface $mapper, array $primaryKeys = [], - string $pkColumn = null + ?string $pkColumn = null, ): WrappedStoreCommand { return new WrappedStoreCommand(new Insert($db, $table, $state, $mapper, $primaryKeys, $pkColumn)); } @@ -39,7 +36,7 @@ public static function createUpdate( string $table, State $state, ?MapperInterface $mapper, - array $primaryKeys = [] + array $primaryKeys = [], ): WrappedStoreCommand { return new WrappedStoreCommand(new Update($db, $table, $state, $mapper, $primaryKeys)); } @@ -52,14 +49,14 @@ public static function wrapCommand(CommandInterface $command): static public function withBeforeExecution(?callable $callable): static { $clone = clone $this; - $clone->beforeExecute = $callable instanceof Closure ? $callable : Closure::fromCallable($callable); + $clone->beforeExecute = $callable instanceof \Closure ? $callable : \Closure::fromCallable($callable); return $clone; } public function withAfterExecution(?callable $callable): static { $clone = clone $this; - $clone->afterExecute = $callable instanceof Closure ? $callable : Closure::fromCallable($callable); + $clone->afterExecute = $callable instanceof \Closure ? $callable : \Closure::fromCallable($callable); return $clone; } @@ -76,11 +73,11 @@ public function isExecuted(): bool public function execute(): void { if ($this->beforeExecute !== null) { - Closure::bind($this->beforeExecute, null, static::class)($this->command); + \Closure::bind($this->beforeExecute, null, static::class)($this->command); } $this->command->execute(); if ($this->afterExecute !== null) { - Closure::bind($this->afterExecute, null, static::class)($this->command); + \Closure::bind($this->afterExecute, null, static::class)($this->command); } } diff --git a/src/Command/StoreCommand.php b/src/Command/StoreCommand.php index cdcfd4a0..80227b41 100644 --- a/src/Command/StoreCommand.php +++ b/src/Command/StoreCommand.php @@ -10,13 +10,12 @@ abstract class StoreCommand extends DatabaseCommand implements StoreCommandInterface { protected array $columns = []; - protected array $appendix = []; public function __construct( DatabaseInterface $db, ?string $table, - protected State $state + protected State $state, ) { parent::__construct($db, $table); } diff --git a/src/Command/Traits/ErrorTrait.php b/src/Command/Traits/ErrorTrait.php index f975845b..a6a7b58b 100644 --- a/src/Command/Traits/ErrorTrait.php +++ b/src/Command/Traits/ErrorTrait.php @@ -14,18 +14,18 @@ trait ErrorTrait public function __toError() { $missing = []; - if (property_exists($this, 'waitScope')) { + if (\property_exists($this, 'waitScope')) { foreach ($this->waitScope ?? [] as $name => $n) { $missing[] = "scope:{$name}"; } } - if (property_exists($this, 'waitContext')) { + if (\property_exists($this, 'waitContext')) { foreach ($this->waitContext ?? [] as $name => $n) { $missing[] = "{$name}"; } } - return sprintf('%s(%s)', $this::class, implode(', ', $missing)); + return \sprintf('%s(%s)', $this::class, \implode(', ', $missing)); } } diff --git a/src/Config/RelationConfig.php b/src/Config/RelationConfig.php index ce0d4573..d0b69792 100644 --- a/src/Config/RelationConfig.php +++ b/src/Config/RelationConfig.php @@ -17,24 +17,6 @@ final class RelationConfig extends InjectableConfig public const RELATION = 'relation'; public const SCHEMA = 'schema'; - public function getLoader(int|string $type): Autowire - { - if (!isset($this->config[$type][self::LOADER])) { - throw new ConfigException("Unable to get relation loader `{$type}`."); - } - - return new Autowire($this->config[$type][self::LOADER]); - } - - public function getRelation(int|string $type): Autowire - { - if (!isset($this->config[$type][self::RELATION])) { - throw new ConfigException("Unable to get relation `{$type}`."); - } - - return new Autowire($this->config[$type][self::RELATION]); - } - #[Pure] public static function getDefault(): self { @@ -76,4 +58,22 @@ public static function getDefault(): self ], ]); } + + public function getLoader(int|string $type): Autowire + { + if (!isset($this->config[$type][self::LOADER])) { + throw new ConfigException("Unable to get relation loader `{$type}`."); + } + + return new Autowire($this->config[$type][self::LOADER]); + } + + public function getRelation(int|string $type): Autowire + { + if (!isset($this->config[$type][self::RELATION])) { + throw new ConfigException("Unable to get relation `{$type}`."); + } + + return new Autowire($this->config[$type][self::RELATION]); + } } diff --git a/src/EntityProxyInterface.php b/src/EntityProxyInterface.php index 0b8bd844..e6de7f33 100644 --- a/src/EntityProxyInterface.php +++ b/src/EntityProxyInterface.php @@ -11,6 +11,4 @@ * * @internal */ -interface EntityProxyInterface -{ -} +interface EntityProxyInterface {} diff --git a/src/Exception/BuilderException.php b/src/Exception/BuilderException.php index 6dbda6b8..0dfd6572 100644 --- a/src/Exception/BuilderException.php +++ b/src/Exception/BuilderException.php @@ -4,6 +4,4 @@ namespace Cycle\ORM\Exception; -class BuilderException extends ORMException -{ -} +class BuilderException extends ORMException {} diff --git a/src/Exception/CollectionFactoryException.php b/src/Exception/CollectionFactoryException.php index 8b390ea4..bea46995 100644 --- a/src/Exception/CollectionFactoryException.php +++ b/src/Exception/CollectionFactoryException.php @@ -4,6 +4,4 @@ namespace Cycle\ORM\Exception; -class CollectionFactoryException extends ORMException -{ -} +class CollectionFactoryException extends ORMException {} diff --git a/src/Exception/CommandException.php b/src/Exception/CommandException.php index f89b3688..9a5d9413 100644 --- a/src/Exception/CommandException.php +++ b/src/Exception/CommandException.php @@ -4,6 +4,4 @@ namespace Cycle\ORM\Exception; -class CommandException extends ORMException -{ -} +class CommandException extends ORMException {} diff --git a/src/Exception/ConfigException.php b/src/Exception/ConfigException.php index 8cbac7df..bda91d84 100644 --- a/src/Exception/ConfigException.php +++ b/src/Exception/ConfigException.php @@ -4,6 +4,4 @@ namespace Cycle\ORM\Exception; -class ConfigException extends ORMException -{ -} +class ConfigException extends ORMException {} diff --git a/src/Exception/FactoryException.php b/src/Exception/FactoryException.php index 1821a090..cddc0e1b 100644 --- a/src/Exception/FactoryException.php +++ b/src/Exception/FactoryException.php @@ -4,6 +4,4 @@ namespace Cycle\ORM\Exception; -class FactoryException extends ORMException -{ -} +class FactoryException extends ORMException {} diff --git a/src/Exception/FactoryTypecastException.php b/src/Exception/FactoryTypecastException.php index 3b523eb6..284ead2d 100644 --- a/src/Exception/FactoryTypecastException.php +++ b/src/Exception/FactoryTypecastException.php @@ -4,6 +4,4 @@ namespace Cycle\ORM\Exception; -class FactoryTypecastException extends FactoryException -{ -} +class FactoryTypecastException extends FactoryException {} diff --git a/src/Exception/HeapException.php b/src/Exception/HeapException.php index 7a6b7752..2a14e355 100644 --- a/src/Exception/HeapException.php +++ b/src/Exception/HeapException.php @@ -4,6 +4,4 @@ namespace Cycle\ORM\Exception; -class HeapException extends \Exception -{ -} +class HeapException extends \Exception {} diff --git a/src/Exception/LoaderException.php b/src/Exception/LoaderException.php index 3eeadd39..87b8239d 100644 --- a/src/Exception/LoaderException.php +++ b/src/Exception/LoaderException.php @@ -4,6 +4,4 @@ namespace Cycle\ORM\Exception; -class LoaderException extends ORMException -{ -} +class LoaderException extends ORMException {} diff --git a/src/Exception/MapperException.php b/src/Exception/MapperException.php index 2199c5f9..83719f86 100644 --- a/src/Exception/MapperException.php +++ b/src/Exception/MapperException.php @@ -4,6 +4,4 @@ namespace Cycle\ORM\Exception; -class MapperException extends ORMException -{ -} +class MapperException extends ORMException {} diff --git a/src/Exception/ORMException.php b/src/Exception/ORMException.php index 5b41380f..c254be72 100644 --- a/src/Exception/ORMException.php +++ b/src/Exception/ORMException.php @@ -4,6 +4,4 @@ namespace Cycle\ORM\Exception; -class ORMException extends \RuntimeException -{ -} +class ORMException extends \RuntimeException {} diff --git a/src/Exception/ParserException.php b/src/Exception/ParserException.php index 43a0404f..5c6e0637 100644 --- a/src/Exception/ParserException.php +++ b/src/Exception/ParserException.php @@ -4,6 +4,4 @@ namespace Cycle\ORM\Exception; -class ParserException extends ORMException -{ -} +class ParserException extends ORMException {} diff --git a/src/Exception/PoolException.php b/src/Exception/PoolException.php index e81cee64..a6ac1ad7 100644 --- a/src/Exception/PoolException.php +++ b/src/Exception/PoolException.php @@ -4,6 +4,4 @@ namespace Cycle\ORM\Exception; -class PoolException extends ORMException -{ -} +class PoolException extends ORMException {} diff --git a/src/Exception/PromiseException.php b/src/Exception/PromiseException.php index 67ef4798..625eb1bd 100644 --- a/src/Exception/PromiseException.php +++ b/src/Exception/PromiseException.php @@ -4,6 +4,4 @@ namespace Cycle\ORM\Exception; -class PromiseException extends ORMException -{ -} +class PromiseException extends ORMException {} diff --git a/src/Exception/Relation/BadRelationValueException.php b/src/Exception/Relation/BadRelationValueException.php index 5efbd44c..bf98ad32 100644 --- a/src/Exception/Relation/BadRelationValueException.php +++ b/src/Exception/Relation/BadRelationValueException.php @@ -6,6 +6,4 @@ use Cycle\ORM\Exception\RelationException; -class BadRelationValueException extends RelationException -{ -} +class BadRelationValueException extends RelationException {} diff --git a/src/Exception/Relation/NullException.php b/src/Exception/Relation/NullException.php index 8c6a9f50..d5587320 100644 --- a/src/Exception/Relation/NullException.php +++ b/src/Exception/Relation/NullException.php @@ -6,6 +6,4 @@ use Cycle\ORM\Exception\RelationException; -class NullException extends RelationException -{ -} +class NullException extends RelationException {} diff --git a/src/Exception/RelationException.php b/src/Exception/RelationException.php index 5c2860bc..9fe65baf 100644 --- a/src/Exception/RelationException.php +++ b/src/Exception/RelationException.php @@ -4,6 +4,4 @@ namespace Cycle\ORM\Exception; -class RelationException extends ORMException -{ -} +class RelationException extends ORMException {} diff --git a/src/Exception/RunnerException.php b/src/Exception/RunnerException.php index 99cf53e9..ebb8f53d 100644 --- a/src/Exception/RunnerException.php +++ b/src/Exception/RunnerException.php @@ -4,6 +4,4 @@ namespace Cycle\ORM\Exception; -class RunnerException extends ORMException -{ -} +class RunnerException extends ORMException {} diff --git a/src/Exception/SchemaException.php b/src/Exception/SchemaException.php index c98a4663..f5aeba9f 100644 --- a/src/Exception/SchemaException.php +++ b/src/Exception/SchemaException.php @@ -4,6 +4,4 @@ namespace Cycle\ORM\Exception; -class SchemaException extends ORMException -{ -} +class SchemaException extends ORMException {} diff --git a/src/Exception/SelectorException.php b/src/Exception/SelectorException.php index 763982a1..87e45c7d 100644 --- a/src/Exception/SelectorException.php +++ b/src/Exception/SelectorException.php @@ -4,6 +4,4 @@ namespace Cycle\ORM\Exception; -class SelectorException extends ORMException -{ -} +class SelectorException extends ORMException {} diff --git a/src/Exception/SuccessTransactionRetryException.php b/src/Exception/SuccessTransactionRetryException.php index c970a67d..dd73e29b 100644 --- a/src/Exception/SuccessTransactionRetryException.php +++ b/src/Exception/SuccessTransactionRetryException.php @@ -4,6 +4,4 @@ namespace Cycle\ORM\Exception; -class SuccessTransactionRetryException extends TransactionException -{ -} +class SuccessTransactionRetryException extends TransactionException {} diff --git a/src/Exception/TransactionException.php b/src/Exception/TransactionException.php index f3904de0..97ce0650 100644 --- a/src/Exception/TransactionException.php +++ b/src/Exception/TransactionException.php @@ -33,12 +33,12 @@ public static function unresolvedRelations( if ($relationStatus === RelationInterface::STATUS_RESOLVED) { continue; } - $message .= sprintf("\n - %s (%s)", $name, $relation::class); + $message .= \sprintf("\n - %s (%s)", $name, $relation::class); } $messages[] = $message; } $messages = \array_unique($messages); - $message = "Transaction can't be finished. Some relations can't be resolved:\n" . implode("\n", $messages); + $message = "Transaction can't be finished. Some relations can't be resolved:\n" . \implode("\n", $messages); return new self($message, 0, $e); } diff --git a/src/Exception/TypecastException.php b/src/Exception/TypecastException.php index c83db393..43bd086f 100644 --- a/src/Exception/TypecastException.php +++ b/src/Exception/TypecastException.php @@ -4,6 +4,4 @@ namespace Cycle\ORM\Exception; -class TypecastException extends ORMException -{ -} +class TypecastException extends ORMException {} diff --git a/src/Factory.php b/src/Factory.php index 80d27e5c..d573d0bb 100644 --- a/src/Factory.php +++ b/src/Factory.php @@ -55,9 +55,9 @@ final class Factory implements FactoryInterface public function __construct( private DatabaseProviderInterface $dbal, - RelationConfig $config = null, - CoreFactory $factory = null, - CollectionFactoryInterface $defaultCollectionFactory = null + ?RelationConfig $config = null, + ?CoreFactory $factory = null, + ?CollectionFactoryInterface $defaultCollectionFactory = null, ) { $this->config = $config ?? RelationConfig::getDefault(); $this->factory = $factory ?? new Container(); @@ -66,7 +66,7 @@ public function __construct( public function make( string $alias, - array $parameters = [] + array $parameters = [], ): mixed { return $this->factory->make($alias, $parameters); } @@ -79,7 +79,7 @@ public function typecast(SchemaInterface $schema, DatabaseInterface $database, s $handlers = []; // Schema's `typecast` option - $rules = (array)$schema->define($role, SchemaInterface::TYPECAST); + $rules = (array) $schema->define($role, SchemaInterface::TYPECAST); $handler = $schema->define($role, SchemaInterface::TYPECAST_HANDLER) ?? $this->defaults[SchemaInterface::TYPECAST_HANDLER]; @@ -103,13 +103,13 @@ public function typecast(SchemaInterface $schema, DatabaseInterface $database, s message: \sprintf( 'Bad typecast handler declaration for the `%s` role. %s', $role, - $e->getMessage() + $e->getMessage(), ), code: $e->getCode(), previous: $e, ); } - $handler = count($handlers) === 1 ? reset($handlers) : new CompositeTypecast(...$handlers); + $handler = \count($handlers) === 1 ? \reset($handlers) : new CompositeTypecast(...$handlers); $handler->setRules($rules); return $parentHandler === null ? $handler @@ -122,7 +122,7 @@ public function mapper(ORMInterface $orm, string $role): MapperInterface $class = $schema->define($role, SchemaInterface::MAPPER) ?? $this->defaults[SchemaInterface::MAPPER]; if (!\is_subclass_of($class, MapperInterface::class)) { - throw new TypecastException(sprintf('%s does not implement %s.', $class, MapperInterface::class)); + throw new TypecastException(\sprintf('%s does not implement %s.', $class, MapperInterface::class)); } return $this->factory->make( @@ -131,7 +131,7 @@ public function mapper(ORMInterface $orm, string $role): MapperInterface 'orm' => $orm, 'role' => $role, 'schema' => $schema->define($role, SchemaInterface::SCHEMA), - ] + ], ); } @@ -139,7 +139,7 @@ public function loader( SchemaInterface $schema, SourceProviderInterface $sourceProvider, string $role, - string $relation + string $relation, ): LoaderInterface { if ($relation === self::PARENT_LOADER) { $parent = $schema->define($role, SchemaInterface::PARENT); @@ -161,17 +161,17 @@ public function loader( 'name' => $relation, 'target' => $definition[Relation::TARGET], 'schema' => $definition[Relation::SCHEMA], - ] + ], ); } public function collection( - string $name = null + ?string $name = null, ): CollectionFactoryInterface { if ($name === null) { return $this->defaultCollectionFactory; } - if (array_key_exists($name, $this->collectionFactoryAlias)) { + if (\array_key_exists($name, $this->collectionFactoryAlias)) { return $this->collectionFactoryAlias[$name]; } // Find by interface @@ -189,7 +189,7 @@ public function relation( ORMInterface $orm, SchemaInterface $schema, string $role, - string $relation + string $relation, ): RelationInterface { $relSchema = $schema->defineRelation($role, $relation); $type = $relSchema[Relation::TYPE]; @@ -204,11 +204,11 @@ public function relation( 'schema' => $relSchema[Relation::SCHEMA] + [Relation::LOAD => $relSchema[Relation::LOAD] ?? null] + [Relation::COLLECTION_TYPE => $relSchema[Relation::COLLECTION_TYPE] ?? null], - ] + ], ); } - public function database(string $database = null): DatabaseInterface + public function database(?string $database = null): DatabaseInterface { return $this->dbal->database($database); } @@ -217,7 +217,7 @@ public function repository( ORMInterface $orm, SchemaInterface $schema, string $role, - ?Select $select + ?Select $select, ): RepositoryInterface { $class = $schema->define($role, SchemaInterface::REPOSITORY) ?? $this->defaults[SchemaInterface::REPOSITORY]; @@ -231,13 +231,13 @@ public function repository( 'select' => $select, 'orm' => $orm, 'role' => $role, - ] + ], ); } public function source( SchemaInterface $schema, - string $role + string $role, ): SourceInterface { /** @var class-string $source */ $source = $schema->define($role, SchemaInterface::SOURCE) ?? $this->defaults[SchemaInterface::SOURCE]; @@ -261,7 +261,7 @@ public function source( } if (!\is_subclass_of($scope, ScopeInterface::class)) { - throw new TypecastException(sprintf('%s does not implement %s.', $scope, ScopeInterface::class)); + throw new TypecastException(\sprintf('%s does not implement %s.', $scope, ScopeInterface::class)); } return $source->withScope(\is_object($scope) ? $scope : $this->factory->make($scope)); @@ -279,7 +279,7 @@ public function withDefaultSchemaClasses(array $defaults): self public function withCollectionFactory( string $alias, CollectionFactoryInterface $factory, - string $interface = null + ?string $interface = null, ): self { $clone = clone $this; $interface = $interface ?? $factory->getInterface(); @@ -294,17 +294,15 @@ public function withCollectionFactory( /** * Make typecast handler from giver string or object - * - * @return TypecastInterface */ private function makeTypecastHandler( string|TypecastInterface $handler, DatabaseInterface $database, SchemaInterface $schema, - string $role + string $role, ): TypecastInterface { // If handler is an object we don't need to use factory, we should return it as is - if (is_object($handler)) { + if (\is_object($handler)) { return $handler; } diff --git a/src/FactoryInterface.php b/src/FactoryInterface.php index 3a6676b8..70a73c03 100644 --- a/src/FactoryInterface.php +++ b/src/FactoryInterface.php @@ -27,7 +27,7 @@ interface FactoryInterface extends DatabaseProviderInterface, CoreFactory */ public function mapper( ORMInterface $orm, - string $role + string $role, ): MapperInterface; /** @@ -37,7 +37,7 @@ public function loader( SchemaInterface $schema, SourceProviderInterface $sourceProvider, string $role, - string $relation + string $relation, ): LoaderInterface; /** @@ -47,7 +47,7 @@ public function repository( ORMInterface $orm, SchemaInterface $schema, string $role, - ?Select $select + ?Select $select, ): RepositoryInterface; /** @@ -56,7 +56,7 @@ public function repository( public function typecast( SchemaInterface $schema, DatabaseInterface $database, - string $role + string $role, ): ?TypecastInterface; /** @@ -64,7 +64,7 @@ public function typecast( */ public function source( SchemaInterface $schema, - string $role + string $role, ): SourceInterface; /** @@ -72,7 +72,7 @@ public function source( * Can be class name or alias that can be configured in the {@see withCollectionFactory()} method. */ public function collection( - string $name = null + ?string $name = null, ): CollectionFactoryInterface; /** @@ -82,7 +82,7 @@ public function relation( ORMInterface $orm, SchemaInterface $schema, string $role, - string $relation + string $relation, ): RelationInterface; /** @@ -99,6 +99,6 @@ public function withDefaultSchemaClasses(array $defaults): self; public function withCollectionFactory( string $alias, CollectionFactoryInterface $factory, - string $interface = null + ?string $interface = null, ): self; } diff --git a/src/Heap/Heap.php b/src/Heap/Heap.php index cef40672..68521a95 100644 --- a/src/Heap/Heap.php +++ b/src/Heap/Heap.php @@ -4,16 +4,11 @@ namespace Cycle\ORM\Heap; -use IteratorAggregate; -use SplObjectStorage; -use UnexpectedValueException; - -final class Heap implements HeapInterface, IteratorAggregate +final class Heap implements HeapInterface, \IteratorAggregate { private const INDEX_KEY_SEPARATOR = ':'; - private ?SplObjectStorage $storage = null; - + private ?\SplObjectStorage $storage = null; private array $paths = []; public function __construct() @@ -21,17 +16,7 @@ public function __construct() $this->clean(); } - public function __destruct() - { - $this->clean(); - } - - public function __clone() - { - $this->storage = clone $this->storage; - } - - public function getIterator(): SplObjectStorage + public function getIterator(): \SplObjectStorage { return $this->storage; } @@ -45,14 +30,14 @@ public function get(object $entity): ?Node { try { return $this->storage->offsetGet($entity); - } catch (UnexpectedValueException) { + } catch (\UnexpectedValueException) { return null; } } public function find(string $role, array $scope): ?object { - if (!array_key_exists($role, $this->paths) || $this->paths[$role] === []) { + if (!\array_key_exists($role, $this->paths) || $this->paths[$role] === []) { return null; } @@ -61,26 +46,26 @@ public function find(string $role, array $scope): ?object case 0: return null; case 1: - $indexName = key($scope); + $indexName = \key($scope); break; default: $isComposite = true; - $indexName = implode(self::INDEX_KEY_SEPARATOR, array_keys($scope)); + $indexName = \implode(self::INDEX_KEY_SEPARATOR, \array_keys($scope)); } if (!$isComposite) { - $value = (string) current($scope); + $value = (string) \current($scope); return $this->paths[$role][$indexName][$value] ?? null; } $result = null; // Find index - if (!array_key_exists($indexName, $this->paths[$role])) { - $scopeKeys = array_keys($scope); + if (!\array_key_exists($indexName, $this->paths[$role])) { + $scopeKeys = \array_keys($scope); $scopeCount = \count($scopeKeys); foreach ($this->paths[$role] as $indexName => $values) { - $indexKeys = explode(self::INDEX_KEY_SEPARATOR, $indexName); + $indexKeys = \explode(self::INDEX_KEY_SEPARATOR, $indexName); $keysCount = \count($indexKeys); - if ($keysCount <= $scopeCount && \count(array_intersect($indexKeys, $scopeKeys)) === $keysCount) { + if ($keysCount <= $scopeCount && \count(\array_intersect($indexKeys, $scopeKeys)) === $keysCount) { $result = &$this->paths[$role][$indexName]; break; } @@ -92,7 +77,7 @@ public function find(string $role, array $scope): ?object } else { $result = &$this->paths[$role][$indexName]; } - $indexKeys ??= explode(self::INDEX_KEY_SEPARATOR, $indexName); + $indexKeys ??= \explode(self::INDEX_KEY_SEPARATOR, $indexName); foreach ($indexKeys as $key) { $value = (string) $scope[$key]; if (!isset($result[$value])) { @@ -125,11 +110,11 @@ public function attach(object $entity, Node $node, array $index = []): void case 0: continue 2; case 1: - $indexName = current($key); + $indexName = \current($key); break; default: $isComposite = true; - $indexName = implode(self::INDEX_KEY_SEPARATOR, $key); + $indexName = \implode(self::INDEX_KEY_SEPARATOR, $key); } } else { $indexName = $key; @@ -143,7 +128,7 @@ public function attach(object $entity, Node $node, array $index = []): void if (!isset($data[$k])) { continue 2; } - $value = (string)$data[$k]; + $value = (string) $data[$k]; $rolePath = &$rolePath[$value]; } $rolePath = $entity; @@ -151,7 +136,7 @@ public function attach(object $entity, Node $node, array $index = []): void if (!isset($data[$indexName])) { continue; } - $value = (string)$data[$indexName]; + $value = (string) $data[$indexName]; $rolePath[$value] = $entity; } } @@ -178,7 +163,17 @@ public function detach(object $entity): void public function clean(): void { $this->paths = []; - $this->storage = new SplObjectStorage(); + $this->storage = new \SplObjectStorage(); + } + + public function __clone() + { + $this->storage = clone $this->storage; + } + + public function __destruct() + { + $this->clean(); } private function eraseIndexes(string $role, array $data, object $entity): void @@ -190,13 +185,13 @@ private function eraseIndexes(string $role, array $data, object $entity): void if (empty($values)) { continue; } - $keys = explode(self::INDEX_KEY_SEPARATOR, $index); + $keys = \explode(self::INDEX_KEY_SEPARATOR, $index); $j = \count($keys) - 1; $next = &$values; $removeFrom = &$next; // Walk index foreach ($keys as $i => $key) { - $value = isset($data[$key]) ? (string)$data[$key] : null; + $value = isset($data[$key]) ? (string) $data[$key] : null; if ($value === null || !isset($next[$value])) { continue 2; } diff --git a/src/Heap/Node.php b/src/Heap/Node.php index 16e5c2c8..cca8bdb9 100644 --- a/src/Heap/Node.php +++ b/src/Heap/Node.php @@ -8,14 +8,7 @@ use Cycle\ORM\Heap\Traits\RelationTrait; use Cycle\ORM\Reference\ReferenceInterface; use Cycle\ORM\RelationMap; -use DateTimeImmutable; -use DateTimeInterface; use JetBrains\PhpStorm\ExpectedValues; -use Stringable; - -use const FILTER_NULL_ON_FAILURE; -use const FILTER_VALIDATE_BOOLEAN; -use const SORT_STRING; /** * Node (metadata) carries meta information about entity state, changes forwards data to other points through @@ -43,17 +36,85 @@ public function __construct( #[ExpectedValues(valuesFromClass: self::class)] private int $status, private array $data, - private string $role + private string $role, ) { $this->updateRawData(); } /** - * Reset state. + * @internal */ - public function __destruct() + public static function convertToSolid(mixed $value): mixed { - unset($this->data, $this->rawData, $this->state, $this->relations); + if (!\is_object($value)) { + return $value; + } + if ($value instanceof \DateTimeInterface) { + return $value instanceof \DateTimeImmutable ? $value : \DateTimeImmutable::createFromInterface($value); + } + return $value instanceof \Stringable ? $value->__toString() : $value; + } + + public static function compare(mixed $a, mixed $b): int + { + if ($a === $b) { + return 0; + } + if ($a === null xor $b === null) { + return 1; + } + + $ta = [\gettype($a), \gettype($b)]; + + // array, boolean, double, integer, object, string + \sort($ta, \SORT_STRING); + + if ($ta[0] === 'object' || $ta[1] === 'object') { + // Both are objects + if ($ta[0] === $ta[1]) { + if ($a instanceof \DateTimeInterface && $b instanceof \DateTimeInterface) { + return $a <=> $b; + } + if ($a instanceof ValueInterface && $b instanceof ValueInterface) { + return $a->rawValue() <=> $b->rawValue(); + } + if ($a instanceof \Stringable && $b instanceof \Stringable) { + return $a->__toString() <=> $b->__toString(); + } + return (int) ($a::class !== $b::class || (array) $a !== (array) $b); + } + // Object and string/int + if ($ta[1] === 'string' || $ta[0] === 'integer') { + $a = $a instanceof \Stringable ? $a->__toString() : (string) $a; + $b = $b instanceof \Stringable ? $b->__toString() : (string) $b; + return $a <=> $b; + } + return -1; + } + + if ($ta[1] === 'string') { + if ($a === '' || $b === '') { + return -1; + } + if ($ta[0] === 'integer') { + return \is_numeric($a) && \is_numeric($b) ? (int) ((string) $a !== (string) $b) : -1; + } + if ($ta[0] === 'double') { + return \is_numeric($a) && \is_numeric($b) ? (int) ((float) $a !== (float) $b) : -1; + } + } + + if ($ta[0] === 'boolean') { + $a = \filter_var($a, \FILTER_VALIDATE_BOOLEAN, \FILTER_NULL_ON_FAILURE); + $b = \filter_var($b, \FILTER_VALIDATE_BOOLEAN, \FILTER_NULL_ON_FAILURE); + return (int) ($a !== $b); + } + + if ($ta === ['double', 'integer']) { + return (int) ((float) $a !== (float) $b); + } + + return 1; } public function getRole(): string @@ -127,7 +188,7 @@ public function getData(): array */ public function syncState(RelationMap $relMap, State $state): array { - $changes = array_udiff_assoc($state->getTransactionData(), $this->data, [self::class, 'compare']); + $changes = \array_udiff_assoc($state->getTransactionData(), $this->data, [self::class, 'compare']); foreach ($state->getRelations() as $name => $value) { if ($value instanceof ReferenceInterface) { @@ -146,79 +207,11 @@ public function syncState(RelationMap $relMap, State $state): array } /** - * @internal + * Reset state. */ - public static function convertToSolid(mixed $value): mixed - { - if (!\is_object($value)) { - return $value; - } - if ($value instanceof DateTimeInterface) { - return $value instanceof DateTimeImmutable ? $value : DateTimeImmutable::createFromInterface($value); - } - return $value instanceof Stringable ? $value->__toString() : $value; - } - - public static function compare(mixed $a, mixed $b): int + public function __destruct() { - if ($a === $b) { - return 0; - } - if ($a === null xor $b === null) { - return 1; - } - - $ta = [\gettype($a), \gettype($b)]; - - // array, boolean, double, integer, object, string - \sort($ta, SORT_STRING); - - if ($ta[0] === 'object' || $ta[1] === 'object') { - // Both are objects - if ($ta[0] === $ta[1]) { - if ($a instanceof DateTimeInterface && $b instanceof DateTimeInterface) { - return $a <=> $b; - } - if ($a instanceof ValueInterface && $b instanceof ValueInterface) { - return $a->rawValue() <=> $b->rawValue(); - } - if ($a instanceof Stringable && $b instanceof Stringable) { - return $a->__toString() <=> $b->__toString(); - } - return (int)($a::class !== $b::class || (array)$a !== (array)$b); - } - // Object and string/int - if ($ta[1] === 'string' || $ta[0] === 'integer') { - $a = $a instanceof Stringable ? $a->__toString() : (string)$a; - $b = $b instanceof Stringable ? $b->__toString() : (string)$b; - return $a <=> $b; - } - return -1; - } - - if ($ta[1] === 'string') { - if ($a === '' || $b === '') { - return -1; - } - if ($ta[0] === 'integer') { - return \is_numeric($a) && \is_numeric($b) ? (int)((string)$a !== (string)$b) : -1; - } - if ($ta[0] === 'double') { - return \is_numeric($a) && \is_numeric($b) ? (int)((float)$a !== (float)$b) : -1; - } - } - - if ($ta[0] === 'boolean') { - $a = \filter_var($a, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE); - $b = \filter_var($b, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE); - return (int)($a !== $b); - } - - if ($ta === ['double', 'integer']) { - return (int)((float)$a !== (float)$b); - } - - return 1; + unset($this->data, $this->rawData, $this->state, $this->relations); } private function updateRawData(): void diff --git a/src/Heap/NullHeap.php b/src/Heap/NullHeap.php index aa354fa0..2e311a3b 100644 --- a/src/Heap/NullHeap.php +++ b/src/Heap/NullHeap.php @@ -30,15 +30,9 @@ public function find(string $role, array $scope): ?object return null; } - public function attach(object $entity, Node $node, array $index = []): void - { - } + public function attach(object $entity, Node $node, array $index = []): void {} - public function detach(object $entity): void - { - } + public function detach(object $entity): void {} - public function clean(): void - { - } + public function clean(): void {} } diff --git a/src/Heap/State.php b/src/Heap/State.php index 05338e6c..8e1a6eda 100644 --- a/src/Heap/State.php +++ b/src/Heap/State.php @@ -33,7 +33,7 @@ public function __construct( #[ExpectedValues(valuesFromClass: Node::class)] private int $state, private array $data, - private array $transactionRaw = [] + private array $transactionRaw = [], ) { $this->transactionData = $state === Node::NEW ? [] : $data; } @@ -55,7 +55,7 @@ public function addToStorage(string $type, self $node): void $this->storage[$type][] = $node; } - public function clearStorage(string $type = null): void + public function clearStorage(?string $type = null): void { if ($type === null) { $this->storage = []; @@ -106,7 +106,7 @@ public function getTransactionData(): array return $this->transactionData; } - public function updateTransactionData(array $fields = null): void + public function updateTransactionData(?array $fields = null): void { if ($fields === null) { foreach ($this->data as $field => $value) { @@ -120,7 +120,7 @@ public function updateTransactionData(array $fields = null): void } $changes = false; foreach ($this->data as $field => $value) { - if (in_array($field, $fields, true)) { + if (\in_array($field, $fields, true)) { $this->transactionData[$field] = $this->data[$field]; if (\array_key_exists($field, $this->transactionRaw)) { $this->transactionRaw[$field] = Node::convertToSolid($this->data[$field]); @@ -152,7 +152,7 @@ public function getChanges(): array } $c = Node::compare( $value, - \array_key_exists($field, $this->transactionRaw) ? $this->transactionRaw[$field] : $this->transactionData[$field] + \array_key_exists($field, $this->transactionRaw) ? $this->transactionRaw[$field] : $this->transactionData[$field], ); if ($c !== 0) { $result[$field] = $value; @@ -185,15 +185,10 @@ public function isReady(): bool return $this->waitingFields === []; } - public function __destruct() - { - unset($this->relations, $this->storage, $this->data, $this->transactionData); - } - public function setRelationStatus( string $name, #[ExpectedValues(valuesFromClass: RelationInterface::class)] - int $status + int $status, ): void { $this->relationStatus[$name] = $status; } @@ -203,4 +198,9 @@ public function getRelationStatus(string $name): int { return $this->relationStatus[$name] ?? RelationInterface::STATUS_PREPARE; } + + public function __destruct() + { + unset($this->relations, $this->storage, $this->data, $this->transactionData); + } } diff --git a/src/Heap/Traits/RelationTrait.php b/src/Heap/Traits/RelationTrait.php index 6d8fc6ce..1e450737 100644 --- a/src/Heap/Traits/RelationTrait.php +++ b/src/Heap/Traits/RelationTrait.php @@ -16,7 +16,7 @@ public function setRelation(string $name, mixed $context): void public function hasRelation(string $name): bool { - return array_key_exists($name, $this->relations); + return \array_key_exists($name, $this->relations); } public function getRelation(string $name): mixed diff --git a/src/Iterator.php b/src/Iterator.php index 2cd31bc4..31f9f1c9 100644 --- a/src/Iterator.php +++ b/src/Iterator.php @@ -8,7 +8,6 @@ use Cycle\ORM\Heap\Node; use Cycle\ORM\Service\EntityFactoryInterface; use Cycle\ORM\Select\LoaderInterface; -use Generator; use IteratorAggregate; /** @@ -18,7 +17,7 @@ * * @template-implements IteratorAggregate */ -final class Iterator implements IteratorAggregate +final class Iterator implements \IteratorAggregate { private function __construct( private string $role, @@ -27,9 +26,8 @@ private function __construct( private EntityFactoryInterface $entityFactory, private iterable $source, private bool $findInHeap = false, - private bool $typecast = false - ) { - } + private bool $typecast = false, + ) {} /** * @param class-string|string $class @@ -40,7 +38,7 @@ public static function createWithOrm( string $class, iterable $source, bool $findInHeap = false, - bool $typecast = false + bool $typecast = false, ): self { return new self( $orm->resolveRole($class), @@ -49,7 +47,7 @@ public static function createWithOrm( $orm->getService(EntityFactoryInterface::class), $source, $findInHeap, - $typecast + $typecast, ); } @@ -64,7 +62,7 @@ public static function createWithServices( string $role, iterable $source, bool $findInHeap = false, - bool $typecast = false + bool $typecast = false, ): self { return new self( $role, @@ -73,7 +71,7 @@ public static function createWithServices( $entityProvider, $source, $findInHeap, - $typecast + $typecast, ); } @@ -81,9 +79,9 @@ public static function createWithServices( * Generate entities using incoming data stream. Pivoted data would be * returned as key value if set. * - * @return Generator + * @return \Generator */ - public function getIterator(): Generator + public function getIterator(): \Generator { foreach ($this->source as $index => $data) { // through-like relations diff --git a/src/Mapper/ClasslessMapper.php b/src/Mapper/ClasslessMapper.php index 87c8e9b5..9aaf2599 100644 --- a/src/Mapper/ClasslessMapper.php +++ b/src/Mapper/ClasslessMapper.php @@ -18,9 +18,9 @@ public function __construct(ORMInterface $orm, string $role) $this->entityFactory = new ClasslessProxyFactory(); } - public function init(array $data, string $role = null): object + public function init(array $data, ?string $role = null): object { - return $this->entityFactory->create($this->relationMap, $this->role, array_keys($this->columns + $this->parentColumns)); + return $this->entityFactory->create($this->relationMap, $this->role, \array_keys($this->columns + $this->parentColumns)); } public function hydrate($entity, array $data): object @@ -39,9 +39,9 @@ public function extract($entity): array */ public function fetchFields(object $entity): array { - return array_intersect_key( + return \array_intersect_key( $this->entityFactory->extractData($this->relationMap, $entity), - $this->columns + $this->parentColumns + $this->columns + $this->parentColumns, ); } diff --git a/src/Mapper/DatabaseMapper.php b/src/Mapper/DatabaseMapper.php index 167698e6..9cd151df 100644 --- a/src/Mapper/DatabaseMapper.php +++ b/src/Mapper/DatabaseMapper.php @@ -27,9 +27,7 @@ abstract class DatabaseMapper implements MapperInterface { protected SourceInterface $source; - protected array $columns = []; - protected array $parentColumns = []; /** @var string[] */ @@ -37,14 +35,16 @@ abstract class DatabaseMapper implements MapperInterface /** @var string[] */ protected array $primaryKeys; - private ?TypecastInterface $typecast; + protected RelationMap $relationMap; + private ?TypecastInterface $typecast; + /** @var array */ private array $generatedFields; public function __construct( ORMInterface $orm, - protected string $role + protected string $role, ) { $this->source = $orm->getSource($role); $this->typecast = $orm->getService(TypecastProviderInterface::class)->getTypecast($role); @@ -65,7 +65,7 @@ public function __construct( $parent = $schema->define($parent, SchemaInterface::PARENT); } - $this->primaryKeys = (array)$schema->define($role, SchemaInterface::PRIMARY_KEY); + $this->primaryKeys = (array) $schema->define($role, SchemaInterface::PRIMARY_KEY); foreach ($this->primaryKeys as $PK) { $this->primaryColumns[] = $this->columns[$PK] ?? $PK; } @@ -84,11 +84,11 @@ public function cast(array $data): array // Cast relations foreach ($this->relationMap->getRelations() as $field => $relation) { - if (!array_key_exists($field, $data)) { + if (!\array_key_exists($field, $data)) { continue; } $value = $data[$field]; - if (!is_array($value) && null !== $value) { + if (!\is_array($value) && $value !== null) { continue; } // break links @@ -144,7 +144,7 @@ public function queueUpdate(object $entity, Node $node, State $state): CommandIn $this->source->getTable(), $state, $this, - $this->primaryKeys + $this->primaryKeys, ); foreach ($this->primaryKeys as $pk) { @@ -161,7 +161,7 @@ public function queueDelete(object $entity, Node $node, State $state): CommandIn $this->source->getDatabase(), $this->source->getTable(), $state, - $this + $this, ); $state->setStatus(Node::SCHEDULED_DELETE); @@ -176,14 +176,6 @@ public function queueDelete(object $entity, Node $node, State $state): CommandIn return $delete; } - /** - * Generate next sequential entity ID. Return null to use autoincrement value. - */ - protected function nextPrimaryKey(): ?array - { - return null; - } - public function mapColumns(array &$values): array { $result = []; @@ -197,4 +189,12 @@ public function mapColumns(array &$values): array return $result; } + + /** + * Generate next sequential entity ID. Return null to use autoincrement value. + */ + protected function nextPrimaryKey(): ?array + { + return null; + } } diff --git a/src/Mapper/Mapper.php b/src/Mapper/Mapper.php index 92d10645..26acb0dd 100644 --- a/src/Mapper/Mapper.php +++ b/src/Mapper/Mapper.php @@ -26,7 +26,7 @@ class Mapper extends DatabaseMapper public function __construct( ORMInterface $orm, protected ProxyEntityFactory $entityFactory, - string $role + string $role, ) { parent::__construct($orm, $role); @@ -36,7 +36,7 @@ public function __construct( $this->discriminator = $this->schema->define($role, SchemaInterface::DISCRIMINATOR) ?? $this->discriminator; } - public function init(array $data, string $role = null): object + public function init(array $data, ?string $role = null): object { $class = $this->resolveClass($data, $role); return $this->entityFactory->create($this->relationMap, $class); @@ -56,9 +56,9 @@ public function extract(object $entity): array public function fetchFields(object $entity): array { - $values = array_intersect_key( + $values = \array_intersect_key( $this->entityFactory->extractData($this->relationMap, $entity), - $this->columns + $this->parentColumns + $this->columns + $this->parentColumns, ); return $values + $this->getDiscriminatorValues($entity); } diff --git a/src/Mapper/Proxy/ClasslessProxyFactory.php b/src/Mapper/Proxy/ClasslessProxyFactory.php index ffee8670..09f0d5df 100644 --- a/src/Mapper/Proxy/ClasslessProxyFactory.php +++ b/src/Mapper/Proxy/ClasslessProxyFactory.php @@ -27,7 +27,7 @@ class ClasslessProxyFactory public function create( RelationMap $relMap, string $role, - array $data + array $data, ): object { $class = $this->defineClass($role, $relMap, $data); $proxy = new $class(); @@ -37,7 +37,7 @@ public function create( public function upgrade( object $entity, - array $data + array $data, ): object { foreach ($data as $key => $value) { $entity->$key = $value; @@ -47,12 +47,12 @@ public function upgrade( public function extractRelations(RelationMap $relMap, object $entity): array { - if (!property_exists($entity, '__cycle_orm_rel_data')) { - return array_intersect_key($this->entityToArray($entity), $relMap->getRelations()); + if (!\property_exists($entity, '__cycle_orm_rel_data')) { + return \array_intersect_key($this->entityToArray($entity), $relMap->getRelations()); } $currentData = $entity->__cycle_orm_rel_data; foreach ($relMap->getRelations() as $key => $relation) { - if (!array_key_exists($key, $currentData)) { + if (!\array_key_exists($key, $currentData)) { $arrayData ??= $this->entityToArray($entity); $currentData[$key] = $arrayData[$key]; } @@ -62,14 +62,14 @@ public function extractRelations(RelationMap $relMap, object $entity): array public function extractData(RelationMap $relMap, object $entity): array { - return array_diff_key($this->entityToArray($entity), $relMap->getRelations()); + return \array_diff_key($this->entityToArray($entity), $relMap->getRelations()); } public function entityToArray(object $entity): array { $result = []; - foreach ((array)$entity as $key => $value) { - $result[$key[0] === "\0" ? substr($key, strrpos($key, "\0", 1) + 1) : $key] = $value; + foreach ((array) $entity as $key => $value) { + $result[$key[0] === "\0" ? \substr($key, \strrpos($key, "\0", 1) + 1) : $key] = $value; } $relations = $result['__cycle_orm_rel_data']; unset($result['__cycle_orm_rel_map'], $result['__cycle_orm_rel_data']); @@ -93,7 +93,7 @@ private function defineClass(string $role, RelationMap $relMap, array $fields): $namespace = 'Cycle\\ORM\\ClasslessProxy'; $class = $namespace . '\\' . $className; ++$i; - } while (class_exists($class, false)); + } while (\class_exists($class, false)); $properties = []; // Generate properties @@ -103,7 +103,7 @@ private function defineClass(string $role, RelationMap $relMap, array $fields): foreach ($relMap->getRelations() as $field => $relation) { $properties[] = "private \${$field};"; } - $properties = implode("\n ", $properties); + $properties = \implode("\n ", $properties); $this->classMap[$role] = $class; /** @see \Cycle\ORM\Mapper\Proxy\ClasslessProxyTrait */ diff --git a/src/Mapper/Proxy/ClasslessProxyTrait.php b/src/Mapper/Proxy/ClasslessProxyTrait.php index b477ce5e..58387979 100644 --- a/src/Mapper/Proxy/ClasslessProxyTrait.php +++ b/src/Mapper/Proxy/ClasslessProxyTrait.php @@ -6,7 +6,6 @@ use Cycle\ORM\Reference\ReferenceInterface; use Cycle\ORM\RelationMap; -use RuntimeException; /** * @internal @@ -20,7 +19,7 @@ public function __get(string $name) { $relation = $this->__cycle_orm_rel_map->getRelations()[$name] ?? null; if ($relation === null) { - throw new RuntimeException(sprintf('Undefined property %s.%s.', static::class, $name)); + throw new \RuntimeException(\sprintf('Undefined property %s.%s.', static::class, $name)); } $value = $this->__cycle_orm_rel_data[$name] ?? null; if ($value instanceof ReferenceInterface) { @@ -33,7 +32,7 @@ public function __get(string $name) public function __set(string $name, mixed $value): void { - if (!array_key_exists($name, $this->__cycle_orm_rel_map->getRelations())) { + if (!\array_key_exists($name, $this->__cycle_orm_rel_map->getRelations())) { $this->$name = $value; return; } @@ -49,7 +48,7 @@ public function __set(string $name, mixed $value): void public function __debugInfo(): array { - $result = (array)$this; + $result = (array) $this; unset($result['__cycle_orm_rel_map'], $result['__cycle_orm_rel_data'], $result['__cycle_orm_relation_props']); return $result; } diff --git a/src/Mapper/Proxy/EntityProxyTrait.php b/src/Mapper/Proxy/EntityProxyTrait.php index b975f561..31f8e44d 100644 --- a/src/Mapper/Proxy/EntityProxyTrait.php +++ b/src/Mapper/Proxy/EntityProxyTrait.php @@ -4,11 +4,9 @@ namespace Cycle\ORM\Mapper\Proxy; -use Closure; use Cycle\ORM\Mapper\Proxy\Hydrator\PropertyMap; use Cycle\ORM\Reference\ReferenceInterface; use Cycle\ORM\RelationMap; -use RuntimeException; /** * @internal @@ -23,7 +21,7 @@ public function __get(string $name) { $relation = $this->__cycle_orm_rel_map->getRelations()[$name] ?? null; if ($relation === null) { - return method_exists(parent::class, '__get') + return \method_exists(parent::class, '__get') ? parent::__get($name) : $this->$name; } @@ -36,7 +34,7 @@ public function __get(string $name) return $value; } - throw new RuntimeException(sprintf('Property %s.%s is not initialized.', get_parent_class(static::class), $name)); + throw new \RuntimeException(\sprintf('Property %s.%s is not initialized.', \get_parent_class(static::class), $name)); } public function __unset(string $name): void @@ -46,7 +44,7 @@ public function __unset(string $name): void if ($propertyClass === PropertyMap::PUBLIC_CLASS) { unset($this->$name); } else { - Closure::bind(static function (object $object, string $property): void { + \Closure::bind(static function (object $object, string $property): void { unset($object->{$property}); }, null, $propertyClass)($this, $name); } @@ -58,8 +56,8 @@ public function __unset(string $name): void public function __set(string $name, $value): void { - if (!array_key_exists($name, $this->__cycle_orm_rel_map->getRelations())) { - if (method_exists(parent::class, '__set')) { + if (!\array_key_exists($name, $this->__cycle_orm_rel_map->getRelations())) { + if (\method_exists(parent::class, '__set')) { parent::__set($name, $value); } return; @@ -75,7 +73,7 @@ public function __set(string $name, $value): void if ($propertyClass === PropertyMap::PUBLIC_CLASS) { $this->$name = $value; } else { - Closure::bind(static function (object $object, string $property, $value): void { + \Closure::bind(static function (object $object, string $property, $value): void { $object->{$property} = $value; }, null, $propertyClass)($this, $name, $value); } @@ -83,7 +81,7 @@ public function __set(string $name, $value): void public function __debugInfo(): array { - $result = method_exists(parent::class, '__debugInfo') ? parent::__debugInfo() : (array)$this; + $result = \method_exists(parent::class, '__debugInfo') ? parent::__debugInfo() : (array) $this; unset($result['__cycle_orm_rel_map'], $result['__cycle_orm_rel_data'], $result['__cycle_orm_relation_props']); return $result; } diff --git a/src/Mapper/Proxy/Hydrator/ClassPropertiesExtractor.php b/src/Mapper/Proxy/Hydrator/ClassPropertiesExtractor.php index d54a1852..9ecf74bf 100644 --- a/src/Mapper/Proxy/Hydrator/ClassPropertiesExtractor.php +++ b/src/Mapper/Proxy/Hydrator/ClassPropertiesExtractor.php @@ -4,9 +4,6 @@ namespace Cycle\ORM\Mapper\Proxy\Hydrator; -use ReflectionClass; -use ReflectionProperty; - /** * @internal */ @@ -20,16 +17,15 @@ class ClassPropertiesExtractor * * @param string[] $relations * - * @throws \ReflectionException - * * @return array + * @throws \ReflectionException */ public function extract(string|object $objectOrClass, array $relations): array { $classProperties = []; $relationProperties = []; - $reflection = new ReflectionClass($objectOrClass); + $reflection = new \ReflectionClass($objectOrClass); $properties = $this->findAllInstanceProperties($reflection); foreach ($properties as $property) { @@ -54,9 +50,9 @@ public function extract(string|object $objectOrClass, array $relations): array * Find all class properties recursively using class hierarchy without * removing name redefinitions * - * @return ReflectionProperty[] + * @return \ReflectionProperty[] */ - private function findAllInstanceProperties(?ReflectionClass $class = null): array + private function findAllInstanceProperties(?\ReflectionClass $class = null): array { if ($class === null) { return []; @@ -66,8 +62,8 @@ private function findAllInstanceProperties(?ReflectionClass $class = null): arra $this->findAllInstanceProperties($class->getParentClass() ?: null), \array_filter( $class->getProperties(), - static fn (ReflectionProperty $property): bool => !$property->isStatic() - ) + static fn(\ReflectionProperty $property): bool => !$property->isStatic(), + ), ); } } diff --git a/src/Mapper/Proxy/Hydrator/ClosureHydrator.php b/src/Mapper/Proxy/Hydrator/ClosureHydrator.php index 20054c39..2dd695d4 100644 --- a/src/Mapper/Proxy/Hydrator/ClosureHydrator.php +++ b/src/Mapper/Proxy/Hydrator/ClosureHydrator.php @@ -4,7 +4,6 @@ namespace Cycle\ORM\Mapper\Proxy\Hydrator; -use Closure; use Cycle\ORM\EntityProxyInterface; use Cycle\ORM\Exception\MapperException; use Cycle\ORM\Reference\ReferenceInterface; @@ -43,7 +42,7 @@ public function hydrate(RelationMap $relMap, array $propertyMaps, object $object if ($e::class === \TypeError::class) { throw new MapperException( "Can't hydrate an entity because property and value types are incompatible.", - previous: $e + previous: $e, ); } } @@ -62,9 +61,9 @@ private function setEntityProperties(array $properties, object $object, array &$ continue; } - Closure::bind(static function (object $object, array $props, array &$data): void { + \Closure::bind(static function (object $object, array $props, array &$data): void { foreach ($props as $property) { - if (!array_key_exists($property, $data)) { + if (!\array_key_exists($property, $data)) { continue; } @@ -76,7 +75,7 @@ private function setEntityProperties(array $properties, object $object, array &$ if ($e::class === \TypeError::class) { throw new MapperException( "Can't hydrate an entity because property and value types are incompatible.", - previous: $e + previous: $e, ); } } @@ -138,7 +137,7 @@ private function setRelationProperties(array $properties, RelationMap $relMap, o continue; } - Closure::bind($setter, null, $class)($object, $props, $data); + \Closure::bind($setter, null, $class)($object, $props, $data); } } } diff --git a/src/Mapper/Proxy/Hydrator/PropertyMap.php b/src/Mapper/Proxy/Hydrator/PropertyMap.php index c4797e65..936c4d4d 100644 --- a/src/Mapper/Proxy/Hydrator/PropertyMap.php +++ b/src/Mapper/Proxy/Hydrator/PropertyMap.php @@ -13,9 +13,8 @@ class PropertyMap public function __construct( private string $class, - private array $properties - ) { - } + private array $properties, + ) {} public function isPublicProperty(string $name): bool { diff --git a/src/Mapper/Proxy/ProxyEntityFactory.php b/src/Mapper/Proxy/ProxyEntityFactory.php index 46ab592b..feb3d10a 100644 --- a/src/Mapper/Proxy/ProxyEntityFactory.php +++ b/src/Mapper/Proxy/ProxyEntityFactory.php @@ -4,7 +4,6 @@ namespace Cycle\ORM\Mapper\Proxy; -use Closure; use Cycle\ORM\Mapper\Proxy\Hydrator\ClassPropertiesExtractor; use Cycle\ORM\Mapper\Proxy\Hydrator\ClosureHydrator; use Cycle\ORM\Mapper\Proxy\Hydrator\PropertyMap; @@ -27,11 +26,11 @@ class ProxyEntityFactory private array $classProperties = []; private Instantiator $instantiator; - private Closure $initializer; + private \Closure $initializer; public function __construct( private ClosureHydrator $hydrator, - private ClassPropertiesExtractor $propertiesExtractor + private ClassPropertiesExtractor $propertiesExtractor, ) { $this->instantiator = new Instantiator(); $this->initializer = static function (object $entity, array $properties): void { @@ -59,7 +58,7 @@ public function create( // init foreach ($scopes[ClassPropertiesExtractor::KEY_RELATIONS]->getProperties() as $scope => $properties) { - Closure::bind($this->initializer, null, $scope === '' ? $class : $scope)($proxy, $properties); + \Closure::bind($this->initializer, null, $scope === '' ? $class : $scope)($proxy, $properties); } return $proxy; @@ -73,7 +72,7 @@ public function create( public function upgrade( RelationMap $relMap, object $entity, - array $data + array $data, ): object { $properties = $this->getEntityProperties($entity, $relMap); @@ -82,7 +81,7 @@ public function upgrade( $relMap, $properties, $entity, - $data + $data, ); } @@ -93,13 +92,13 @@ public function upgrade( */ public function extractRelations(RelationMap $relMap, object $entity): array { - if (!property_exists($entity, '__cycle_orm_rel_data')) { - return array_intersect_key($this->entityToArray($entity), $relMap->getRelations()); + if (!\property_exists($entity, '__cycle_orm_rel_data')) { + return \array_intersect_key($this->entityToArray($entity), $relMap->getRelations()); } $currentData = $entity->__cycle_orm_rel_data; foreach ($relMap->getRelations() as $key => $relation) { - if (!array_key_exists($key, $currentData)) { + if (!\array_key_exists($key, $currentData)) { $arrayData ??= $this->entityToArray($entity); if (\array_key_exists($key, $arrayData)) { @@ -118,20 +117,20 @@ public function extractRelations(RelationMap $relMap, object $entity): array */ public function extractData(RelationMap $relMap, object $entity): array { - return array_diff_key($this->entityToArray($entity), $relMap->getRelations()); + return \array_diff_key($this->entityToArray($entity), $relMap->getRelations()); } private function entityToArray(object $entity): array { $result = []; - foreach ((array)$entity as $key => $value) { - $result[$key[0] === "\0" ? substr($key, strrpos($key, "\0", 1) + 1) : $key] = $value; + foreach ((array) $entity as $key => $value) { + $result[$key[0] === "\0" ? \substr($key, \strrpos($key, "\0", 1) + 1) : $key] = $value; } unset( $result['__cycle_orm_rel_map'], $result['__cycle_orm_rel_data'], - $result['__cycle_orm_relation_props'] + $result['__cycle_orm_relation_props'], ); return $result; @@ -139,29 +138,29 @@ private function entityToArray(object $entity): array private function defineClass(string $class): string { - if (!class_exists($class, true)) { - throw new \RuntimeException(sprintf( + if (!\class_exists($class, true)) { + throw new \RuntimeException(\sprintf( 'The entity `%s` class does not exist. Proxy factory can not create classless entities.', - $class + $class, )); } - if (array_key_exists($class, $this->classMap)) { + if (\array_key_exists($class, $this->classMap)) { return $this->classMap[$class]; } $reflection = new \ReflectionClass($class); if ($reflection->isFinal()) { - throw new \RuntimeException(sprintf('The entity `%s` class is final and can\'t be extended.', $class)); + throw new \RuntimeException(\sprintf('The entity `%s` class is final and can\'t be extended.', $class)); } $className = "{$class} Cycle ORM Proxy"; $this->classMap[$class] = $className; - if (!class_exists($className, false)) { - if (str_contains($className, '\\')) { - $pos = strrpos($className, '\\'); - $namespaceStr = sprintf("namespace %s;\n", substr($className, 0, $pos)); - $classNameStr = substr($className, $pos + 1); + if (!\class_exists($className, false)) { + if (\str_contains($className, '\\')) { + $pos = \strrpos($className, '\\'); + $namespaceStr = \sprintf("namespace %s;\n", \substr($className, 0, $pos)); + $classNameStr = \substr($className, $pos + 1); } else { $namespaceStr = ''; $classNameStr = $className; @@ -185,13 +184,12 @@ class {$classNameStr} extends \\{$class} implements \\Cycle\\ORM\\EntityProxyInt /** * Gets property map (primitive fields, relations) for given Entity. * - * @throws \ReflectionException - * * @return PropertyMap[] + * @throws \ReflectionException */ private function getEntityProperties(object $entity, RelationMap $relMap): array { return $this->classProperties[$entity::class] ??= $this->propertiesExtractor - ->extract($entity, array_keys($relMap->getRelations())); + ->extract($entity, \array_keys($relMap->getRelations())); } } diff --git a/src/Mapper/StdMapper.php b/src/Mapper/StdMapper.php index 896c683e..6e7d0110 100644 --- a/src/Mapper/StdMapper.php +++ b/src/Mapper/StdMapper.php @@ -12,7 +12,7 @@ */ final class StdMapper extends DatabaseMapper { - public function init(array $data, string $role = null): object + public function init(array $data, ?string $role = null): object { return new \stdClass(); } @@ -38,7 +38,7 @@ public function hydrate($entity, array $data): object public function extract($entity): array { - return get_object_vars($entity); + return \get_object_vars($entity); } /** @@ -46,17 +46,17 @@ public function extract($entity): array */ public function fetchFields(object $entity): array { - return array_intersect_key( + return \array_intersect_key( $this->extract($entity), - $this->columns + $this->parentColumns + $this->columns + $this->parentColumns, ); } public function fetchRelations(object $entity): array { - return array_intersect_key( + return \array_intersect_key( $this->extract($entity), - $this->relationMap->getRelations() + $this->relationMap->getRelations(), ); } } diff --git a/src/Mapper/Traits/SingleTableTrait.php b/src/Mapper/Traits/SingleTableTrait.php index 8f1277cd..08b9e1f9 100644 --- a/src/Mapper/Traits/SingleTableTrait.php +++ b/src/Mapper/Traits/SingleTableTrait.php @@ -17,7 +17,7 @@ trait SingleTableTrait /** * Classname to represent entity. */ - protected function resolveClass(array $data, string $role = null): string + protected function resolveClass(array $data, ?string $role = null): string { if ($role !== null && $role !== $this->role && $role !== $this->entity) { return $this->resolveChildClassByRole($role); @@ -47,9 +47,9 @@ protected function getDiscriminatorValues(object $entity): array private function resolveChildClassByRole(string $role): string { $class = $this->schema->define($role, SchemaInterface::ENTITY); - if (!in_array($class, $this->children, true)) { + if (!\in_array($class, $this->children, true)) { throw new \InvalidArgumentException( - sprintf('Role `%s` does not have a child role `%s`.', $this->role, $role) + \sprintf('Role `%s` does not have a child role `%s`.', $this->role, $role), ); } return $class; diff --git a/src/MapperInterface.php b/src/MapperInterface.php index 61b6f331..cf843729 100644 --- a/src/MapperInterface.php +++ b/src/MapperInterface.php @@ -24,7 +24,7 @@ public function getRole(): string; * * @param array $data Raw data. You shouldn't apply typecasting to it. */ - public function init(array $data, string $role = null): object; + public function init(array $data, ?string $role = null): object; /** * Cast raw data to configured types. @@ -44,9 +44,8 @@ public function uncast(array $data): array; * @param object $entity * @param array $data Prepared (typecasted) data * - * @throws MapperException - * * @return T + * @throws MapperException */ public function hydrate(object $entity, array $data): object; diff --git a/src/ORM.php b/src/ORM.php index 4dc8fb00..a29fe460 100644 --- a/src/ORM.php +++ b/src/ORM.php @@ -26,7 +26,6 @@ use Cycle\ORM\Service\TypecastProviderInterface; use Cycle\ORM\Transaction\CommandGenerator; use Cycle\ORM\Transaction\CommandGeneratorInterface; -use InvalidArgumentException; use JetBrains\PhpStorm\ExpectedValues; /** @@ -35,9 +34,7 @@ final class ORM implements ORMInterface { private HeapInterface $heap; - private CommandGeneratorInterface $commandGenerator; - private RelationProvider $relationProvider; private SourceProvider $sourceProvider; private TypecastProvider $typecastProvider; @@ -50,32 +47,14 @@ final class ORM implements ORMInterface public function __construct( private FactoryInterface $factory, private SchemaInterface $schema, - CommandGeneratorInterface $commandGenerator = null, - HeapInterface $heap = null + ?CommandGeneratorInterface $commandGenerator = null, + ?HeapInterface $heap = null, ) { $this->heap = $heap ?? new Heap(); $this->commandGenerator = $commandGenerator ?? new CommandGenerator(); $this->resetRegistry(); } - /** - * Reset related objects cache. - */ - public function __clone() - { - $this->heap = clone $this->heap; - $this->heap->clean(); - - $this->resetRegistry(); - } - - public function __debugInfo(): array - { - return [ - 'schema' => $this->schema, - ]; - } - public function resolveRole(string|object $entity): string { return $this->entityFactory->resolveRole($entity); @@ -112,7 +91,7 @@ public function getService( SourceProviderInterface::class, TypecastProviderInterface::class, ])] - string $class + string $class, ): object { return match ($class) { EntityFactoryInterface::class => $this->entityFactory, @@ -123,7 +102,7 @@ public function getService( MapperProviderInterface::class => $this->mapperProvider, RelationProviderInterface::class => $this->relationProvider, RepositoryProviderInterface::class => $this->repositoryProvider, - default => throw new InvalidArgumentException("Undefined service `$class`.") + default => throw new \InvalidArgumentException("Undefined service `$class`."), }; } @@ -140,28 +119,28 @@ public function getHeap(): HeapInterface public function getMapper(string|object $entity): MapperInterface { return $this->mapperProvider->getMapper( - $this->resolveRole($entity) + $this->resolveRole($entity), ); } public function getRepository(string|object $entity): RepositoryInterface { return $this->repositoryProvider->getRepository( - $this->resolveRole($entity) + $this->resolveRole($entity), ); } public function getSource(string $entity): SourceInterface { return $this->sourceProvider->getSource( - $this->resolveRole($entity) + $this->resolveRole($entity), ); } public function getIndexes(string $entity): array { return $this->indexProvider->getIndexes( - $this->resolveRole($entity) + $this->resolveRole($entity), ); } @@ -171,14 +150,14 @@ public function getIndexes(string $entity): array public function getRelationMap(string $entity): RelationMap { return $this->relationProvider->getRelationMap( - $this->resolveRole($entity) + $this->resolveRole($entity), ); } public function with( ?SchemaInterface $schema = null, ?FactoryInterface $factory = null, - ?HeapInterface $heap = null + ?HeapInterface $heap = null, ): ORMInterface { $heap ??= clone $this->heap; $heap->clean(); @@ -187,7 +166,7 @@ public function with( factory: $factory ?? $this->factory, schema: $schema ?? $this->schema, commandGenerator: $this->commandGenerator, - heap: $heap + heap: $heap, ); } @@ -229,6 +208,24 @@ public function withHeap(HeapInterface $heap): ORMInterface return $this->with(heap: $heap); } + /** + * Reset related objects cache. + */ + public function __clone() + { + $this->heap = clone $this->heap; + $this->heap->clean(); + + $this->resetRegistry(); + } + + public function __debugInfo(): array + { + return [ + 'schema' => $this->schema, + ]; + } + private function resetRegistry(): void { $this->indexProvider = new IndexProvider($this->schema); @@ -242,7 +239,7 @@ private function resetRegistry(): void $this, $this->sourceProvider, $this->schema, - $this->factory + $this->factory, ); $this->entityProvider = new EntityProvider($this->heap, $this->repositoryProvider); @@ -251,7 +248,7 @@ private function resetRegistry(): void $this->schema, $this->mapperProvider, $this->relationProvider, - $this->indexProvider + $this->indexProvider, ); } } diff --git a/src/ORMInterface.php b/src/ORMInterface.php index 815e1bed..6f673a93 100644 --- a/src/ORMInterface.php +++ b/src/ORMInterface.php @@ -80,7 +80,7 @@ public function getHeap(): HeapInterface; public function with( ?SchemaInterface $schema = null, ?FactoryInterface $factory = null, - ?HeapInterface $heap = null + ?HeapInterface $heap = null, ): self; /** diff --git a/src/Parser/AbstractMergeNode.php b/src/Parser/AbstractMergeNode.php index ca47a969..b54230d3 100644 --- a/src/Parser/AbstractMergeNode.php +++ b/src/Parser/AbstractMergeNode.php @@ -26,17 +26,12 @@ public function __construct( array $columns, array $primaryKeys, protected array $innerKeys, - ?array $outerKeys + ?array $outerKeys, ) { parent::__construct($columns, $outerKeys); $this->setDuplicateCriteria($primaryKeys); } - protected function push(array &$data): void - { - $this->results[] = &$data; - } - public function mergeInheritanceNodes(bool $includeRole = false): void { if ($this->parent === null) { @@ -54,12 +49,17 @@ public function mergeInheritanceNodes(bool $includeRole = false): void $this->indexName, $this->intersectData($this->innerKeys, $item), $item + $roleField, - static::OVERWRITE_DATA + static::OVERWRITE_DATA, ); } $this->results = []; } + protected function push(array &$data): void + { + $this->results[] = &$data; + } + /** * @psalm-pure */ diff --git a/src/Parser/AbstractNode.php b/src/Parser/AbstractNode.php index 3af539f2..8e77e042 100644 --- a/src/Parser/AbstractNode.php +++ b/src/Parser/AbstractNode.php @@ -6,7 +6,6 @@ use Cycle\ORM\Exception\ParserException; use Cycle\ORM\Parser\Traits\DuplicateTrait; -use Throwable; /** * Represents data node in a tree with ability to parse line of results, split it into sub @@ -72,21 +71,13 @@ abstract class AbstractNode */ public function __construct( protected array $columns, - array $outerKeys = null + ?array $outerKeys = null, ) { - $this->indexName = empty($outerKeys) ? null : implode(':', $outerKeys); + $this->indexName = empty($outerKeys) ? null : \implode(':', $outerKeys); $this->outerKeys = $outerKeys ?? []; $this->indexedData = new MultiKeyCollection(); } - public function __destruct() - { - $this->parent = null; - $this->nodes = []; - $this->indexedData = null; - $this->duplicates = []; - } - /** * Parse given row of data and populate reference tree. * @@ -100,7 +91,7 @@ public function parseRow(int $offset, array $row): int $relatedNodes = \array_merge( $this->mergeParent === null ? [] : [$this->mergeParent], $this->nodes, - $this->mergeSubclass + $this->mergeSubclass, ); if ($this->isEmptyPrimaryKey($data)) { @@ -108,7 +99,7 @@ public function parseRow(int $offset, array $row): int return \count($this->columns) + \array_reduce( $relatedNodes, - static fn (int $cnt, AbstractNode $node): int => $cnt + \count($node->columns), + static fn(int $cnt, AbstractNode $node): int => $cnt + \count($node->columns), 0, ); } @@ -117,7 +108,7 @@ public function parseRow(int $offset, array $row): int foreach ($this->indexedData->getIndexes() as $index) { try { $this->indexedData->addItem($index, $data); - } catch (Throwable) { + } catch (\Throwable) { } } @@ -203,7 +194,7 @@ public function linkNode(?string $container, self $node): void if ($node->indexName !== null) { foreach ($node->outerKeys as $key) { // foreach ($node->indexValues->getIndex($this->indexName) as $key) { - if (!in_array($key, $this->columns, true)) { + if (!\in_array($key, $this->columns, true)) { throw new ParserException("Unable to create reference, key `{$key}` does not exist."); } } @@ -260,6 +251,14 @@ public function mergeInheritanceNodes(bool $includeRole = false): void } } + public function __destruct() + { + $this->parent = null; + $this->nodes = []; + $this->indexedData = null; + $this->duplicates = []; + } + /** * Mount record data into internal data storage under specified container using reference key * (inner key) and reference criteria (outer key value). @@ -289,7 +288,7 @@ protected function mount(string $container, string $index, array $criteria, arra } if ($this->indexedData->getItemsCount($index, $criteria) === 0) { - throw new ParserException(sprintf('Undefined reference `%s` "%s".', $index, implode(':', $criteria))); + throw new ParserException(\sprintf('Undefined reference `%s` "%s".', $index, \implode(':', $criteria))); } foreach ($this->indexedData->getItemsSubset($index, $criteria) as &$subset) { @@ -330,7 +329,7 @@ protected function mountArray(string $container, string $index, mixed $criteria, } foreach ($this->indexedData->getItemsSubset($index, $criteria) as &$subset) { - if (!in_array($data, $subset[$container], true)) { + if (!\in_array($data, $subset[$container], true)) { $subset[$container][] = &$data; } } @@ -350,11 +349,11 @@ protected function mergeData(string $index, array $criteria, array $data, bool $ } if ($this->indexedData->getItemsCount($index, $criteria) === 0) { - throw new ParserException(sprintf('Undefined reference `%s` "%s".', $index, implode(':', $criteria))); + throw new ParserException(\sprintf('Undefined reference `%s` "%s".', $index, \implode(':', $criteria))); } foreach ($this->indexedData->getItemsSubset($index, $criteria) as &$subset) { - $subset = $overwrite ? array_merge($subset, $data) : array_merge($data, $subset); + $subset = $overwrite ? \array_merge($subset, $data) : \array_merge($data, $subset); unset($subset); } } @@ -373,13 +372,13 @@ protected function fetchData(int $dataOffset, array $line): array //Combine column names with sliced piece of row return \array_combine( $this->columns, - \array_slice($line, $dataOffset, \count($this->columns)) + \array_slice($line, $dataOffset, \count($this->columns)), ); - } catch (Throwable $e) { + } catch (\Throwable $e) { throw new ParserException( 'Unable to parse incoming row: ' . $e->getMessage(), $e->getCode(), - $e + $e, ); } } diff --git a/src/Parser/ArrayNode.php b/src/Parser/ArrayNode.php index a2548146..be09032c 100644 --- a/src/Parser/ArrayNode.php +++ b/src/Parser/ArrayNode.php @@ -23,15 +23,12 @@ public function __construct( array $columns, array $primaryKeys, protected array $innerKeys, - ?array $outerKeys + ?array $outerKeys, ) { parent::__construct($columns, $outerKeys); $this->setDuplicateCriteria($primaryKeys); } - /** - * {@inheritdoc} - */ protected function push(array &$data): void { if ($this->parent === null) { @@ -49,7 +46,7 @@ protected function push(array &$data): void $this->container, $this->indexName, $this->intersectData($this->innerKeys, $data), - $data + $data, ); } } diff --git a/src/Parser/EmbeddedNode.php b/src/Parser/EmbeddedNode.php index a79eae59..83ab2d96 100644 --- a/src/Parser/EmbeddedNode.php +++ b/src/Parser/EmbeddedNode.php @@ -21,7 +21,7 @@ protected function push(array &$data): void $this->container, $this->indexName, self::LAST_REFERENCE, - $data + $data, ); } } diff --git a/src/Parser/MultiKeyCollection.php b/src/Parser/MultiKeyCollection.php index e16df330..7c385c46 100644 --- a/src/Parser/MultiKeyCollection.php +++ b/src/Parser/MultiKeyCollection.php @@ -38,12 +38,12 @@ public function createIndex(string $name, array $keys): void public function getIndexes(): array { - return array_keys($this->indexes); + return \array_keys($this->indexes); } public function hasIndex(string $index): bool { - return array_key_exists($index, $this->indexes); + return \array_key_exists($index, $this->indexes); } public function getItemsCount(string $index, array $values): int @@ -75,7 +75,7 @@ public function addItem(string $index, array &$data): void throw new \InvalidArgumentException("Invalid value on the key `$key`."); } $itemKeys[] = $keyValue; - if (!array_key_exists($keyValue, $pool)) { + if (!\array_key_exists($keyValue, $pool)) { $pool[$keyValue] = []; } $pool = &$pool[$keyValue]; @@ -91,7 +91,7 @@ public function getCriteria(string $index, bool $useParameter = false): array $base = [$this->indexes[$index][0] => $key]; $result[] = $this->extractAssoc($data, $base, $this->indexes[$index], 1, true); } - return $result === [] ? [] : array_merge(...$result); + return $result === [] ? [] : \array_merge(...$result); } public function getItems(string $indexName): \Generator @@ -122,7 +122,7 @@ private function extractAssoc(array $data, array $base, array $keys, int $level, // instead of: // (key1="1" AND key2="1") OR (key1="1" AND key2="2") OR (key1="1" AND key2="3") if ($useParameter && $level === \count($keys) - 1 && \count($data) > 1) { - return [$base + [$keys[$level] => new Parameter(array_keys($data))]]; + return [$base + [$keys[$level] => new Parameter(\array_keys($data))]]; } if ($level >= \count($keys)) { @@ -134,14 +134,14 @@ private function extractAssoc(array $data, array $base, array $keys, int $level, $base[$field] = $key; $result[] = $this->extractAssoc($value, $base, $keys, $level + 1, $useParameter); } - return array_merge(...$result); + return \array_merge(...$result); } private function getValues(array &$dataSet, array $keys): array { $value = &$dataSet; foreach ($keys as $key) { - if (!array_key_exists($key, $value)) { + if (!\array_key_exists($key, $value)) { throw new ParserException('Value not found.'); } $value = &$value[$key]; diff --git a/src/Parser/OutputNode.php b/src/Parser/OutputNode.php index 49f9d4c5..ce736d85 100644 --- a/src/Parser/OutputNode.php +++ b/src/Parser/OutputNode.php @@ -17,20 +17,20 @@ abstract class OutputNode extends AbstractNode protected array $result = []; /** - * Destructing. + * Get resulted data tree. */ - public function __destruct() + public function getResult(): array { - $this->result = []; - parent::__destruct(); + return $this->result; } /** - * Get resulted data tree. + * Destructing. */ - public function getResult(): array + public function __destruct() { - return $this->result; + $this->result = []; + parent::__destruct(); } protected function push(array &$data): void diff --git a/src/Parser/SingularNode.php b/src/Parser/SingularNode.php index 88746a7b..95c2f043 100644 --- a/src/Parser/SingularNode.php +++ b/src/Parser/SingularNode.php @@ -23,7 +23,7 @@ public function __construct( array $columns, array $primaryKeys, protected array $innerKeys, - ?array $outerKeys + ?array $outerKeys, ) { parent::__construct($columns, $outerKeys); $this->setDuplicateCriteria($primaryKeys); @@ -46,7 +46,7 @@ protected function push(array &$data): void $this->container, $this->indexName, $this->intersectData($this->innerKeys, $data), - $data + $data, ); } } diff --git a/src/Parser/Traits/DuplicateTrait.php b/src/Parser/Traits/DuplicateTrait.php index 3b29c164..f45e6c60 100644 --- a/src/Parser/Traits/DuplicateTrait.php +++ b/src/Parser/Traits/DuplicateTrait.php @@ -47,7 +47,7 @@ final protected function deduplicate(array &$data): bool } return \count($this->duplicateCriteria) === 1 - ? $this->deduplicateSingle(current($this->duplicateCriteria), $data) + ? $this->deduplicateSingle(\current($this->duplicateCriteria), $data) : $this->deduplicateMultiple($this->duplicateCriteria, $data); } @@ -58,9 +58,9 @@ private function deduplicateMultiple(array $keys, array &$data): bool $count = \count($keys); foreach ($keys as $key) { --$count; - $criteria = (string)$data[$key]; + $criteria = (string) $data[$key]; - if (!$search || !array_key_exists($criteria, $zoom)) { + if (!$search || !\array_key_exists($criteria, $zoom)) { $search = false; if ($count === 0) { $zoom[$criteria] = &$data; @@ -78,7 +78,7 @@ private function deduplicateMultiple(array $keys, array &$data): bool private function deduplicateSingle(string $key, array &$data): bool { - $criteria = (string)$data[$key]; + $criteria = (string) $data[$key]; if (isset($this->duplicates[$criteria])) { // duplicate is presented, let's reduplicate diff --git a/src/Parser/Typecast.php b/src/Parser/Typecast.php index 49deccd0..f4e6fb32 100644 --- a/src/Parser/Typecast.php +++ b/src/Parser/Typecast.php @@ -4,12 +4,8 @@ namespace Cycle\ORM\Parser; -use BackedEnum; use Cycle\ORM\Exception\TypecastException; -use DateTimeImmutable; use Cycle\Database\DatabaseInterface; -use ReflectionEnum; -use Throwable; final class Typecast implements CastableInterface, UncastableInterface { @@ -18,16 +14,15 @@ final class Typecast implements CastableInterface, UncastableInterface /** @var array */ private array $callableRules = []; - /** @var array> */ + /** @var array> */ private array $enumClasses = []; - /** @var array|string> */ + /** @var array|string> */ private array $rules = []; public function __construct( private DatabaseInterface $database, - ) { - } + ) {} public function setRules(array $rules): array { @@ -35,9 +30,9 @@ public function setRules(array $rules): array if (\in_array($rule, self::RULES, true)) { $this->rules[$key] = $rule; unset($rules[$key]); - } elseif (\is_string($rule) && \is_subclass_of($rule, BackedEnum::class, true)) { - $reflection = new ReflectionEnum($rule); - $this->enumClasses[$key] = (string)$reflection->getBackingType(); + } elseif (\is_string($rule) && \is_subclass_of($rule, \BackedEnum::class, true)) { + $reflection = new \ReflectionEnum($rule); + $this->enumClasses[$key] = (string) $reflection->getBackingType(); $this->rules[$key] = $rule; unset($rules[$key]); } elseif (\is_callable($rule)) { @@ -64,15 +59,15 @@ public function cast(array $data): array } if (isset($this->enumClasses[$key])) { - /** @var class-string $rule */ + /** @var class-string<\BackedEnum> $rule */ $type = $this->enumClasses[$key]; $value = $data[$key]; $data[$key] = match (true) { !\is_scalar($value) => null, $type === 'string' && (\is_string($type) || \is_numeric($value)) - => $rule::tryFrom((string)$value), + => $rule::tryFrom((string) $value), $type === 'int' && (\is_int($value) || \preg_match('/^\\d++$/', $value) === 1) - => $rule::tryFrom((int)$value), + => $rule::tryFrom((int) $value), default => null, }; continue; @@ -80,11 +75,11 @@ public function cast(array $data): array $data[$key] = $this->castPrimitive($rule, $data[$key]); } - } catch (Throwable $e) { + } catch (\Throwable $e) { throw new TypecastException( \sprintf('Unable to typecast the `%s` field. %s', $key, $e->getMessage()), $e->getCode(), - $e + $e, ); } @@ -104,9 +99,9 @@ public function uncast(array $data): array $data[$column] = match ($rule) { 'json' => \json_encode( $data[$column], - \JSON_UNESCAPED_UNICODE | \JSON_THROW_ON_ERROR | JSON_INVALID_UTF8_SUBSTITUTE + \JSON_UNESCAPED_UNICODE | \JSON_THROW_ON_ERROR | JSON_INVALID_UTF8_SUBSTITUTE, ), - default => $data[$column] + default => $data[$column], }; } @@ -119,12 +114,12 @@ public function uncast(array $data): array private function castPrimitive(mixed $rule, mixed $value): mixed { return match ($rule) { - 'int' => (int)$value, - 'bool' => (bool)$value, - 'float' => (float)$value, - 'datetime' => new DateTimeImmutable( + 'int' => (int) $value, + 'bool' => (bool) $value, + 'float' => (float) $value, + 'datetime' => new \DateTimeImmutable( $value, - $this->database->getDriver()->getTimezone() + $this->database->getDriver()->getTimezone(), ), 'json' => \json_decode($value, true, 512, \JSON_THROW_ON_ERROR), default => $value, diff --git a/src/Reference/EmptyReference.php b/src/Reference/EmptyReference.php index 4f393062..49e0be23 100644 --- a/src/Reference/EmptyReference.php +++ b/src/Reference/EmptyReference.php @@ -8,9 +8,8 @@ final class EmptyReference implements ReferenceInterface { public function __construct( private string $role, - private mixed $value - ) { - } + private mixed $value, + ) {} public function getRole(): string { diff --git a/src/Reference/Promise.php b/src/Reference/Promise.php index b39c2bd3..60e3ee01 100644 --- a/src/Reference/Promise.php +++ b/src/Reference/Promise.php @@ -10,9 +10,8 @@ final class Promise implements ReferenceInterface { public function __construct( private ActiveRelationInterface $relation, - private ReferenceInterface $origin - ) { - } + private ReferenceInterface $origin, + ) {} public function fetch(): object|iterable|null { diff --git a/src/Reference/Reference.php b/src/Reference/Reference.php index d56aeb02..7c4de5c7 100644 --- a/src/Reference/Reference.php +++ b/src/Reference/Reference.php @@ -7,14 +7,12 @@ class Reference implements ReferenceInterface { private bool $loaded = false; - private mixed $value; public function __construct( protected string $role, - protected array $scope - ) { - } + protected array $scope, + ) {} final public function getRole(): string { diff --git a/src/Relation/AbstractRelation.php b/src/Relation/AbstractRelation.php index 05c1fc66..48f21e3e 100644 --- a/src/Relation/AbstractRelation.php +++ b/src/Relation/AbstractRelation.php @@ -33,7 +33,6 @@ abstract class AbstractRelation implements ActiveRelationInterface, \Stringable protected array $outerKeys; protected ?string $inversion; - protected MapperProviderInterface $mapperProvider; protected SchemaInterface $ormSchema; @@ -45,12 +44,12 @@ public function __construct( private string $role, protected string $name, protected string $target, - protected array $schema + protected array $schema, ) { $this->ormSchema = $orm->getSchema(); $this->mapperProvider = $orm->getService(MapperProviderInterface::class); - $this->innerKeys = (array)$schema[Relation::INNER_KEY]; - $this->outerKeys = (array)$schema[Relation::OUTER_KEY]; + $this->innerKeys = (array) $schema[Relation::INNER_KEY]; + $this->outerKeys = (array) $schema[Relation::OUTER_KEY]; $this->inversion = $schema[Relation::INVERSION] ?? null; } @@ -59,12 +58,6 @@ public function getInnerKeys(): array return $this->innerKeys; } - public function __toString(): string - { - // this is incorrect class - return sprintf('`%s` (%s)->%s', $this->name, $this::class, $this->target); - } - public function getName(): string { return $this->name; @@ -80,6 +73,12 @@ public function isCascade(): bool return $this->schema[Relation::CASCADE] ?? false; } + public function __toString(): string + { + // this is incorrect class + return \sprintf('`%s` (%s)->%s', $this->name, $this::class, $this->target); + } + protected function isNullable(): bool { // return $this->schema[Relation::NULLABLE] ?? false; @@ -98,7 +97,7 @@ protected function getTargetRelationName(): string */ protected function assertValid(Node $related): void { - if ($related->getRole() === $this->target || in_array($related->getRole(), $this->targets, true)) { + if ($related->getRole() === $this->target || \in_array($related->getRole(), $this->targets, true)) { return; } $role = $this->ormSchema->resolveAlias($related->getRole()); @@ -115,7 +114,7 @@ protected function assertValid(Node $related): void } $role = $parent; } while ($parent !== null); - throw new RelationException(sprintf('Unable to link %s, given `%s`.', (string)$this, $related->getRole())); + throw new RelationException(\sprintf('Unable to link %s, given `%s`.', (string) $this, $related->getRole())); } protected function registerWaitingFields(State $state, bool $required = true): void diff --git a/src/Relation/BelongsTo.php b/src/Relation/BelongsTo.php index 0517ecc0..498a8067 100644 --- a/src/Relation/BelongsTo.php +++ b/src/Relation/BelongsTo.php @@ -82,7 +82,7 @@ public function queue(Pool $pool, Tuple $tuple): void } if ($related instanceof ReferenceInterface) { $scope = $related->getScope(); - if (array_intersect($this->outerKeys, array_keys($scope))) { + if (\array_intersect($this->outerKeys, \array_keys($scope))) { foreach ($this->outerKeys as $i => $outerKey) { $state->register($this->innerKeys[$i], $scope[$outerKey]); } @@ -125,7 +125,7 @@ private function shouldPull(Tuple $tuple, Tuple $rTuple): bool $toReference = []; foreach ($this->outerKeys as $i => $outerKey) { $innerKey = $this->innerKeys[$i]; - if (!array_key_exists($innerKey, $oldData) || $oldData[$innerKey] !== $newData[$outerKey]) { + if (!\array_key_exists($innerKey, $oldData) || $oldData[$innerKey] !== $newData[$outerKey]) { return true; } $toReference[$outerKey] = $current[$innerKey]; @@ -140,7 +140,7 @@ private function shouldPull(Tuple $tuple, Tuple $rTuple): bool if ($this->isNullable()) { $isNull = true; foreach ($this->innerKeys as $innerKey) { - if (!array_key_exists($innerKey, $current) || $current[$innerKey] !== null) { + if (!\array_key_exists($innerKey, $current) || $current[$innerKey] !== null) { $isNull = false; break; } @@ -215,7 +215,7 @@ private function setNullFromRelated(Tuple $tuple, bool $isPreparing): void } $tuple->state->setRelationStatus($this->getName(), RelationInterface::STATUS_PROCESS); } elseif (!$this->checkNullValuePossibility($tuple)) { - throw new NullException(sprintf('Relation `%s`.%s can not be null.', $node->getRole(), (string)$this)); + throw new NullException(\sprintf('Relation `%s`.%s can not be null.', $node->getRole(), (string) $this)); } return; } diff --git a/src/Relation/DependencyInterface.php b/src/Relation/DependencyInterface.php index 22d17c2e..44028457 100644 --- a/src/Relation/DependencyInterface.php +++ b/src/Relation/DependencyInterface.php @@ -9,6 +9,4 @@ * * @internal */ -interface DependencyInterface extends RelationInterface -{ -} +interface DependencyInterface extends RelationInterface {} diff --git a/src/Relation/Embedded.php b/src/Relation/Embedded.php index bf141f4b..5a71d988 100644 --- a/src/Relation/Embedded.php +++ b/src/Relation/Embedded.php @@ -40,14 +40,14 @@ public function __construct( /** @internal */ ORMInterface $orm, private string $name, - private string $target + private string $target, ) { $this->mapperProvider = $orm->getService(MapperProviderInterface::class); $this->entityProvider = $orm->getService(EntityProviderInterface::class); $this->mapper = $this->mapperProvider->getMapper($target); // this relation must manage column association manually, bypassing related mapper - $this->primaryKeys = (array)$orm->getSchema()->define($target, SchemaInterface::PRIMARY_KEY); + $this->primaryKeys = (array) $orm->getSchema()->define($target, SchemaInterface::PRIMARY_KEY); $this->columns = $orm->getSchema()->define($target, SchemaInterface::COLUMNS); } @@ -109,27 +109,13 @@ public function initReference(Node $node): ReferenceInterface return $scope === [] ? new EmptyReference($this->target, null) : new Reference($this->target, $scope); } - private function getReferenceScope(Node $node): ?array - { - $scope = []; - $nodeData = $node->getData(); - foreach ($this->primaryKeys as $key) { - $value = $nodeData[$key] ?? null; - if (empty($value)) { - return null; - } - $scope[$key] = $value; - } - return $scope; - } - public function prepare(Pool $pool, Tuple $tuple, mixed $related, bool $load = true): void { // $related = $tuple->state->getRelation($this->getName()); // $pool->attach($related, Tuple::TASK_STORE, false); } - public function queue(Pool $pool, Tuple $tuple, StoreCommandInterface $command = null): void + public function queue(Pool $pool, Tuple $tuple, ?StoreCommandInterface $command = null): void { if ($tuple->task !== Tuple::TASK_STORE) { return; @@ -180,17 +166,6 @@ public function queue(Pool $pool, Tuple $tuple, StoreCommandInterface $command = $tuple->state->setRelationStatus($rTuple->node->getRole() . ':' . $this->getName(), RelationInterface::STATUS_RESOLVED); } - private function getChanges(object $related, State $state): array - { - $data = array_intersect_key($this->mapper->extract($related), $this->columns); - // Embedded entity does not override PK values of the parent - foreach ($this->primaryKeys as $key) { - unset($data[$key]); - } - - return array_udiff_assoc($data, $state->getTransactionData(), [Node::class, 'compare']); - } - /** * Resolve the reference to the object. */ @@ -206,4 +181,29 @@ public function resolve(ReferenceInterface $reference, bool $load): ?object } return $result; } + + private function getReferenceScope(Node $node): ?array + { + $scope = []; + $nodeData = $node->getData(); + foreach ($this->primaryKeys as $key) { + $value = $nodeData[$key] ?? null; + if (empty($value)) { + return null; + } + $scope[$key] = $value; + } + return $scope; + } + + private function getChanges(object $related, State $state): array + { + $data = \array_intersect_key($this->mapper->extract($related), $this->columns); + // Embedded entity does not override PK values of the parent + foreach ($this->primaryKeys as $key) { + unset($data[$key]); + } + + return \array_udiff_assoc($data, $state->getTransactionData(), [Node::class, 'compare']); + } } diff --git a/src/Relation/HasMany.php b/src/Relation/HasMany.php index bbd160c8..9c31beb9 100644 --- a/src/Relation/HasMany.php +++ b/src/Relation/HasMany.php @@ -170,19 +170,6 @@ public function initReference(Node $node): ReferenceInterface : new Reference($this->target, $scope); } - protected function getReferenceScope(Node $node): ?array - { - $scope = []; - $nodeData = $node->getData(); - foreach ($this->innerKeys as $i => $key) { - if (!isset($nodeData[$key])) { - return null; - } - $scope[$this->outerKeys[$i]] = $nodeData[$key]; - } - return $scope; - } - public function resolve(ReferenceInterface $reference, bool $load): ?iterable { if ($reference->hasValue()) { @@ -197,7 +184,7 @@ public function resolve(ReferenceInterface $reference, bool $load): ?iterable return null; } - $scope = array_merge($reference->getScope(), $this->schema[Relation::WHERE] ?? []); + $scope = \array_merge($reference->getScope(), $this->schema[Relation::WHERE] ?? []); $iterator = (clone $this->select)->where($scope)->getIterator(findInHeap: true); $result = \iterator_to_array($iterator, false); @@ -213,7 +200,7 @@ public function collect(mixed $data): iterable throw new \InvalidArgumentException('Collected data in the HasMany relation should be iterable.'); } return $this->factory->collection( - $this->schema[Relation::COLLECTION_TYPE] ?? null + $this->schema[Relation::COLLECTION_TYPE] ?? null, )->collect($data); } @@ -231,6 +218,19 @@ public function extract(mixed $data): array return \is_array($data) ? $data : []; } + protected function getReferenceScope(Node $node): ?array + { + $scope = []; + $nodeData = $node->getData(); + foreach ($this->innerKeys as $i => $key) { + if (!isset($nodeData[$key])) { + return null; + } + $scope[$this->outerKeys[$i]] = $nodeData[$key]; + } + return $scope; + } + /** * Return objects which are subject of removal. */ @@ -238,11 +238,11 @@ protected function calcDeleted(iterable $related, iterable $original): array { $related = $this->extract($related); $original = $this->extract($original); - return array_udiff( + return \array_udiff( $original ?? [], $related, // static fn(object $a, object $b): int => strcmp(spl_object_hash($a), spl_object_hash($b)) - static fn (object $a, object $b): int => (int)($a === $b) - 1 + static fn(object $a, object $b): int => (int) ($a === $b) - 1, ); } } diff --git a/src/Relation/ManyToMany.php b/src/Relation/ManyToMany.php index 2296ce0d..dc212fcb 100644 --- a/src/Relation/ManyToMany.php +++ b/src/Relation/ManyToMany.php @@ -26,8 +26,6 @@ use Cycle\ORM\Service\SourceProviderInterface; use Cycle\ORM\Transaction\Pool; use Cycle\ORM\Transaction\Tuple; -use SplObjectStorage; -use Traversable; /** * @internal @@ -41,7 +39,6 @@ class ManyToMany extends Relation\AbstractRelation protected array $throughOuterKeys; protected string $pivotRole; - protected EntityFactoryInterface $entityFactory; protected SourceProviderInterface $sourceProvider; protected FactoryInterface $factory; @@ -52,7 +49,7 @@ public function __construct( private string $role, string $name, string $target, - array $schema + array $schema, ) { parent::__construct($orm, $role, $name, $target, $schema); $this->heap = $orm->getHeap(); @@ -61,8 +58,8 @@ public function __construct( $this->factory = $orm->getFactory(); $this->pivotRole = $this->schema[Relation::THROUGH_ENTITY]; - $this->throughInnerKeys = (array)$this->schema[Relation::THROUGH_INNER_KEY]; - $this->throughOuterKeys = (array)$this->schema[Relation::THROUGH_OUTER_KEY]; + $this->throughInnerKeys = (array) $this->schema[Relation::THROUGH_INNER_KEY]; + $this->throughOuterKeys = (array) $this->schema[Relation::THROUGH_OUTER_KEY]; } public function prepare(Pool $pool, Tuple $tuple, mixed $related, bool $load = true): void @@ -128,7 +125,7 @@ public function queue(Pool $pool, Tuple $tuple): void public function init(EntityFactoryInterface $factory, Node $node, array $data): iterable { $elements = []; - $pivotData = new SplObjectStorage(); + $pivotData = new \SplObjectStorage(); $iterator = Iterator::createWithServices( $this->heap, @@ -136,7 +133,7 @@ public function init(EntityFactoryInterface $factory, Node $node, array $data): $this->entityFactory, $this->target, $data, - true + true, ); foreach ($iterator as $pivot => $entity) { if (!\is_array($pivot)) { @@ -187,7 +184,7 @@ public function cast(?array $data): array public function collect(mixed $data): iterable { return $this->factory->collection( - $this->schema[Relation::COLLECTION_TYPE] ?? null + $this->schema[Relation::COLLECTION_TYPE] ?? null, )->collect($data); } @@ -197,12 +194,12 @@ public function extract(?iterable $data): PivotedStorage $data instanceof PivotedStorage => $data, $data instanceof PivotedCollectionInterface => new PivotedStorage( $data->toArray(), - $data->getPivotContext() + $data->getPivotContext(), ), $data instanceof \Doctrine\Common\Collections\Collection => new PivotedStorage($data->toArray()), $data === null => new PivotedStorage(), - $data instanceof Traversable => new PivotedStorage(iterator_to_array($data)), - default => new PivotedStorage((array)$data), + $data instanceof \Traversable => new PivotedStorage(\iterator_to_array($data)), + default => new PivotedStorage((array) $data), }; } @@ -270,7 +267,7 @@ public function resolve(ReferenceInterface $reference, bool $load): ?iterable $this->factory, $source->getTable(), $this->target, - $this->schema + $this->schema, ); /** @var ManyToManyLoader $loader */ @@ -284,8 +281,8 @@ public function resolve(ReferenceInterface $reference, bool $load): ?iterable // we are going to add pivot node into virtual root node (only ID) to aggregate the results $root = new RootNode( - (array)$this->schema[Relation::INNER_KEY], - (array)$this->schema[Relation::INNER_KEY] + (array) $this->schema[Relation::INNER_KEY], + (array) $this->schema[Relation::INNER_KEY], ); $node = $loader->createNode(); @@ -304,7 +301,7 @@ public function resolve(ReferenceInterface $reference, bool $load): ?iterable $loader->withContext($loader, ['method' => JoinableLoader::INLOAD])->loadData($node); $elements = []; - $pivotData = new SplObjectStorage(); + $pivotData = new \SplObjectStorage(); $iterator = Iterator::createWithServices( $this->heap, $this->ormSchema, @@ -312,14 +309,14 @@ public function resolve(ReferenceInterface $reference, bool $load): ?iterable $this->target, $root->getResult()[0]['output'], true, - typecast: true + typecast: true, ); foreach ($iterator as $pivot => $entity) { $pivotData[$entity] = $this->entityFactory->make( $this->schema[Relation::THROUGH_ENTITY], $pivot, Node::MANAGED, - typecast: true + typecast: true, ); $elements[] = $entity; @@ -336,15 +333,6 @@ protected function applyPivotChanges(State $parentState, State $state): void } } - private function deleteChild(Pool $pool, ?object $pivot, object $child, ?Node $relatedNode = null): void - { - // todo: add supporting for nullable pivot entities? - if ($pivot !== null) { - $pool->attachDelete($pivot, $this->isCascade()); - } - $pool->attachStore($child, true); - } - protected function newLink(Pool $pool, Tuple $tuple, PivotedStorage $storage, object $related): void { $rTuple = $pool->attachStore($related, $this->isCascade()); @@ -395,6 +383,15 @@ protected function initPivot(object $parent, PivotedStorage $storage, Tuple $rTu return $entity; } + private function deleteChild(Pool $pool, ?object $pivot, object $child, ?Node $relatedNode = null): void + { + // todo: add supporting for nullable pivot entities? + if ($pivot !== null) { + $pool->attachDelete($pivot, $this->isCascade()); + } + $pool->attachStore($child, true); + } + private function finalize(Pool $pool, Tuple $tuple, mixed $related): void { $tuple->state->setRelationStatus($this->getName(), RelationInterface::STATUS_RESOLVED); diff --git a/src/Relation/Morphed/MorphedHasOne.php b/src/Relation/Morphed/MorphedHasOne.php index 8ea26180..24395628 100644 --- a/src/Relation/Morphed/MorphedHasOne.php +++ b/src/Relation/Morphed/MorphedHasOne.php @@ -29,11 +29,6 @@ public function __construct(ORMInterface $orm, string $role, string $name, strin $this->morphKey = $schema[Relation::MORPH_KEY]; } - protected function getReferenceScope(Node $node): ?array - { - return parent::getReferenceScope($node) + [$this->morphKey => $node->getRole()]; - } - public function queue(Pool $pool, Tuple $tuple): void { parent::queue($pool, $tuple); @@ -55,6 +50,11 @@ public function queue(Pool $pool, Tuple $tuple): void } } + protected function getReferenceScope(Node $node): ?array + { + return parent::getReferenceScope($node) + [$this->morphKey => $node->getRole()]; + } + protected function getTargetRelationName(): string { return '~morphed~:' . $this->name; diff --git a/src/Relation/RefersTo.php b/src/Relation/RefersTo.php index 9858cd80..0cf86614 100644 --- a/src/Relation/RefersTo.php +++ b/src/Relation/RefersTo.php @@ -66,7 +66,7 @@ public function queue(Pool $pool, Tuple $tuple): void } if ($related instanceof ReferenceInterface) { $scope = $related->getScope(); - if (array_intersect($this->outerKeys, array_keys($scope))) { + if (\array_intersect($this->outerKeys, \array_keys($scope))) { foreach ($this->outerKeys as $i => $outerKey) { $tuple->state->register($this->innerKeys[$i], $scope[$outerKey]); } diff --git a/src/Relation/ReversedRelationInterface.php b/src/Relation/ReversedRelationInterface.php index 14b63b89..0cf6748f 100644 --- a/src/Relation/ReversedRelationInterface.php +++ b/src/Relation/ReversedRelationInterface.php @@ -9,6 +9,4 @@ * * @internal */ -interface ReversedRelationInterface extends RelationInterface -{ -} +interface ReversedRelationInterface extends RelationInterface {} diff --git a/src/Relation/SameRowRelationInterface.php b/src/Relation/SameRowRelationInterface.php index 739e955a..ce001a81 100644 --- a/src/Relation/SameRowRelationInterface.php +++ b/src/Relation/SameRowRelationInterface.php @@ -13,5 +13,5 @@ */ interface SameRowRelationInterface extends ActiveRelationInterface { - public function queue(Pool $pool, Tuple $tuple, StoreCommandInterface $command = null): void; + public function queue(Pool $pool, Tuple $tuple, ?StoreCommandInterface $command = null): void; } diff --git a/src/Relation/ShadowBelongsTo.php b/src/Relation/ShadowBelongsTo.php index 4d86deaf..57390ed8 100644 --- a/src/Relation/ShadowBelongsTo.php +++ b/src/Relation/ShadowBelongsTo.php @@ -17,7 +17,6 @@ class ShadowBelongsTo implements ReversedRelationInterface, DependencyInterface private string $name; private string $target; private array $schema; - private array $innerKeys; private bool $cascade; @@ -26,8 +25,8 @@ public function __construct(string $name, string $target, array $schema) $this->name = $target . '.' . $name . ':' . $schema[Relation::TARGET]; $this->target = $target; $this->schema = $schema; - $this->innerKeys = (array)($schema[Relation::SCHEMA][Relation::OUTER_KEY] ?? []); - $this->cascade = (bool)($schema[Relation::SCHEMA][Relation::CASCADE] ?? false); + $this->innerKeys = (array) ($schema[Relation::SCHEMA][Relation::OUTER_KEY] ?? []); + $this->cascade = (bool) ($schema[Relation::SCHEMA][Relation::CASCADE] ?? false); } public function getInnerKeys(): array @@ -73,7 +72,7 @@ public function isCascade(): bool public function isNullable(): bool { - return (bool)($this->schema[Relation::SCHEMA][Relation::NULLABLE] ?? false); + return (bool) ($this->schema[Relation::SCHEMA][Relation::NULLABLE] ?? false); } private function checkFieldsExists(State $state): bool diff --git a/src/Relation/ShadowHasMany.php b/src/Relation/ShadowHasMany.php index bb836927..c42b46d6 100644 --- a/src/Relation/ShadowHasMany.php +++ b/src/Relation/ShadowHasMany.php @@ -23,7 +23,7 @@ public function __construct( private string $name, private string $target, private array $innerKeys, - private array $outerKeys + private array $outerKeys, ) { $this->targetContainer = $name . ':' . $target; } @@ -58,19 +58,12 @@ public function queue(Pool $pool, Tuple $tuple): void foreach ($related as $item) { $rTuple = $pool->offsetGet($item); - assert($rTuple !== null); + \assert($rTuple !== null); $this->applyChanges($tuple->state, $rTuple->state); $rTuple->state->setRelationStatus($this->targetContainer, RelationInterface::STATUS_RESOLVED); } } - private function applyChanges(State $from, State $to): void - { - foreach ($this->innerKeys as $i => $innerKey) { - $to->register($this->outerKeys[$i], $from->getValue($innerKey)); - } - } - public function getName(): string { return $this->name; @@ -85,4 +78,11 @@ public function isCascade(): bool { return true; } + + private function applyChanges(State $from, State $to): void + { + foreach ($this->innerKeys as $i => $innerKey) { + $to->register($this->outerKeys[$i], $from->getValue($innerKey)); + } + } } diff --git a/src/Relation/Traits/ToOneTrait.php b/src/Relation/Traits/ToOneTrait.php index a26a866b..af5ac5d5 100644 --- a/src/Relation/Traits/ToOneTrait.php +++ b/src/Relation/Traits/ToOneTrait.php @@ -71,7 +71,7 @@ protected function getReferenceScope(Node $node): ?array $scope = []; $nodeData = $node->getData(); foreach ($this->innerKeys as $i => $key) { - if (!array_key_exists($key, $nodeData)) { + if (!\array_key_exists($key, $nodeData)) { return []; } if ($nodeData[$key] === null) { diff --git a/src/RelationMap.php b/src/RelationMap.php index 1260d0ac..fb7a6630 100644 --- a/src/RelationMap.php +++ b/src/RelationMap.php @@ -25,8 +25,10 @@ final class RelationMap /** @var DependencyInterface[] */ private array $dependencies = []; + /** @var RelationInterface[] */ private array $slaves = []; + /** @var SameRowRelationInterface[] */ private array $embedded = []; @@ -83,39 +85,6 @@ public static function build(OrmInterface $orm, string $role): self return $result; } - private function registerOuterRelation(string $role, string $container, array $relationSchema): void - { - // todo: it better to check instanceOf \Cycle\ORM\Relation\DependencyInterface instead of int - $relationType = $relationSchema[Relation::TYPE]; - // skip dependencies - if ($relationType === Relation::BELONGS_TO || $relationType === Relation::REFERS_TO) { - return; - } - if ($relationType === Relation::MANY_TO_MANY) { - $handshaked = \is_string($relationSchema[Relation::SCHEMA][Relation::INVERSION] ?? null); - // Create ShadowHasMany - if (!$handshaked) { - $relation = new ShadowHasMany( - $role . '.' . $container . ':' . $relationSchema[Relation::TARGET], - $relationSchema[Relation::SCHEMA][Relation::THROUGH_ENTITY], - (array)$relationSchema[Relation::SCHEMA][Relation::OUTER_KEY], - (array)$relationSchema[Relation::SCHEMA][Relation::THROUGH_OUTER_KEY] - ); - $this->slaves[$relation->getName()] = $relation; - } - return; - } - if ($relationType === Relation::MORPHED_HAS_ONE || $relationType === Relation::MORPHED_HAS_MANY) { - // todo: find morphed collisions, decide handshake - $relation = new ShadowBelongsTo('~morphed~' . $container, $role, $relationSchema); - $this->dependencies[$relation->getName()] ??= $relation; - return; - } - - $relation = new ShadowBelongsTo($container, $role, $relationSchema); - $this->dependencies[$relation->getName()] = $relation; - } - public function hasDependencies(): bool { return $this->dependencies !== []; @@ -137,7 +106,7 @@ public function hasEmbedded(): bool public function init(EntityFactoryInterface $factory, Node $node, array $data): array { foreach ($this->innerRelations as $name => $relation) { - if (!array_key_exists($name, $data)) { + if (!\array_key_exists($name, $data)) { if ($node->hasRelation($name)) { continue; } @@ -192,4 +161,37 @@ public function getRelations(): array { return $this->innerRelations; } + + private function registerOuterRelation(string $role, string $container, array $relationSchema): void + { + // todo: it better to check instanceOf \Cycle\ORM\Relation\DependencyInterface instead of int + $relationType = $relationSchema[Relation::TYPE]; + // skip dependencies + if ($relationType === Relation::BELONGS_TO || $relationType === Relation::REFERS_TO) { + return; + } + if ($relationType === Relation::MANY_TO_MANY) { + $handshaked = \is_string($relationSchema[Relation::SCHEMA][Relation::INVERSION] ?? null); + // Create ShadowHasMany + if (!$handshaked) { + $relation = new ShadowHasMany( + $role . '.' . $container . ':' . $relationSchema[Relation::TARGET], + $relationSchema[Relation::SCHEMA][Relation::THROUGH_ENTITY], + (array) $relationSchema[Relation::SCHEMA][Relation::OUTER_KEY], + (array) $relationSchema[Relation::SCHEMA][Relation::THROUGH_OUTER_KEY], + ); + $this->slaves[$relation->getName()] = $relation; + } + return; + } + if ($relationType === Relation::MORPHED_HAS_ONE || $relationType === Relation::MORPHED_HAS_MANY) { + // todo: find morphed collisions, decide handshake + $relation = new ShadowBelongsTo('~morphed~' . $container, $role, $relationSchema); + $this->dependencies[$relation->getName()] ??= $relation; + return; + } + + $relation = new ShadowBelongsTo($container, $role, $relationSchema); + $this->dependencies[$relation->getName()] = $relation; + } } diff --git a/src/Schema.php b/src/Schema.php index 599a4a07..9494931b 100644 --- a/src/Schema.php +++ b/src/Schema.php @@ -12,6 +12,7 @@ final class Schema implements SchemaInterface { private array $aliases; + /** * @var string[] * @@ -30,23 +31,14 @@ public function __construct(array $schema) [$this->schema, $this->aliases] = $this->normalize($schema); } - public static function __set_state(array $an_array): self - { - $schema = new self([]); - $schema->schema = $an_array['schema']; - $schema->aliases = $an_array['aliases']; - - return $schema; - } - public function getRoles(): array { - return array_keys($this->schema); + return \array_keys($this->schema); } public function getRelations(string $role): array { - return array_keys($this->define($role, self::RELATIONS)); + return \array_keys($this->define($role, self::RELATIONS)); } /** @@ -154,6 +146,15 @@ public function getInheritedRoles(string $parent): array return $this->subclasses[$parent] ?? []; } + public static function __set_state(array $an_array): self + { + $schema = new self([]); + $schema->schema = $an_array['schema']; + $schema->aliases = $an_array['aliases']; + + return $schema; + } + /** * Automatically replace class names with their aliases. * @@ -170,14 +171,14 @@ private function normalize(array $schema): array $item[self::ENTITY] = $key; } - if (class_exists($key)) { + if (\class_exists($key)) { $role = $item[self::ROLE] ?? $key; if ($role !== $key) { $aliases[$key] = $role; } } - if ($item[self::ENTITY] !== $role && class_exists($item[self::ENTITY])) { + if ($item[self::ENTITY] !== $role && \class_exists($item[self::ENTITY])) { $aliases[$item[self::ENTITY]] = $role; $this->classes[$role] = $item[self::ENTITY]; } @@ -189,7 +190,7 @@ private function normalize(array $schema): array // Normalize PARENT option foreach ($result as $role => &$item) { if (isset($item[self::PARENT])) { - if (class_exists($item[self::PARENT])) { + if (\class_exists($item[self::PARENT])) { $parent = $item[self::PARENT]; while (isset($aliases[$parent])) { $parent = $aliases[$parent]; @@ -206,7 +207,7 @@ private function normalize(array $schema): array foreach ($result as $role => $item) { if (isset($item[self::CHILDREN])) { foreach ($item[self::CHILDREN] as $child) { - if (isset($aliases[$child]) && class_exists($child)) { + if (isset($aliases[$child]) && \class_exists($child)) { $aliases[$aliases[$child]] = $role; } $aliases[$child] = $role; @@ -217,9 +218,9 @@ private function normalize(array $schema): array // Normalize relation associations foreach ($result as &$item) { if (isset($item[self::RELATIONS])) { - $item[self::RELATIONS] = iterator_to_array($this->normalizeRelations( + $item[self::RELATIONS] = \iterator_to_array($this->normalizeRelations( $item[self::RELATIONS], - $aliases + $aliases, )); } } @@ -265,34 +266,34 @@ private function linkRelations(array $schemaArray, array $aliases): array foreach ($result as $role => $item) { foreach ($item[self::RELATIONS] ?? [] as $container => $relation) { $target = $relation[Relation::TARGET]; - if (!array_key_exists($target, $result)) { + if (!\array_key_exists($target, $result)) { continue; } $targetSchema = $result[$target]; $targetRelations = $targetSchema[self::RELATIONS] ?? []; $inversion = $relation[Relation::SCHEMA][Relation::INVERSION] ?? null; if ($inversion !== null) { - if (!array_key_exists($inversion, $targetRelations)) { + if (!\array_key_exists($inversion, $targetRelations)) { throw new SchemaException( - sprintf( + \sprintf( 'Relation `%s` as inversion of `%s.%s` not found in the `%s` role.', $inversion, $role, $container, - $target - ) + $target, + ), ); } $targetHandshake = $targetRelations[$inversion][Relation::SCHEMA][Relation::INVERSION] ?? null; if ($targetHandshake !== null && $container !== $targetHandshake) { throw new SchemaException( - sprintf( + \sprintf( 'Relation `%s.%s` can\'t be inversion of `%s.%s` because they have different relation values.', $role, $container, $target, $inversion, - ) + ), ); } $result[$target][self::RELATIONS][$inversion][Relation::SCHEMA][Relation::INVERSION] = $container; @@ -315,7 +316,7 @@ private function findInvertedRelation( string $role, string $container, array $relation, - array $targetRelations + array $targetRelations, ): ?string { $nullable = $relation[Relation::SCHEMA][Relation::NULLABLE] ?? null; /** @var callable $compareCallback */ @@ -360,8 +361,8 @@ private function compareManyToMany(array $relation, array $targetRelation): bool return false; } // Same keys - if ((array)$schema[Relation::INNER_KEY] !== (array)$targetSchema[Relation::OUTER_KEY] - || (array)$schema[Relation::OUTER_KEY] !== (array)$targetSchema[Relation::INNER_KEY]) { + if ((array) $schema[Relation::INNER_KEY] !== (array) $targetSchema[Relation::OUTER_KEY] + || (array) $schema[Relation::OUTER_KEY] !== (array) $targetSchema[Relation::INNER_KEY]) { return false; } // Optional fields @@ -374,12 +375,12 @@ private function checkBelongsToInversion(array $relation, array $targetRelation) $schema = $relation[Relation::SCHEMA]; $targetSchema = $targetRelation[Relation::SCHEMA]; // MTM connects with MTM only - if (!in_array($targetRelation[Relation::TYPE], [Relation::HAS_MANY, Relation::HAS_ONE], true)) { + if (!\in_array($targetRelation[Relation::TYPE], [Relation::HAS_MANY, Relation::HAS_ONE], true)) { return false; } // Same keys - if ((array)$schema[Relation::INNER_KEY] !== (array)$targetSchema[Relation::OUTER_KEY] - || (array)$schema[Relation::OUTER_KEY] !== (array)$targetSchema[Relation::INNER_KEY]) { + if ((array) $schema[Relation::INNER_KEY] !== (array) $targetSchema[Relation::OUTER_KEY] + || (array) $schema[Relation::OUTER_KEY] !== (array) $targetSchema[Relation::INNER_KEY]) { return false; } // Optional fields @@ -391,7 +392,7 @@ private function checkBelongsToInversion(array $relation, array $targetRelation) */ private function defineEntityClass(string $role): ?string { - if (array_key_exists($role, $this->classes)) { + if (\array_key_exists($role, $this->classes)) { return $this->classes[$role]; } $rr = $this->resolveAlias($role) ?? $role; diff --git a/src/Select.php b/src/Select.php index 04c5adb4..15a248d0 100644 --- a/src/Select.php +++ b/src/Select.php @@ -4,7 +4,6 @@ namespace Cycle\ORM; -use Countable; use Cycle\Database\Injection\Parameter; use Cycle\Database\Query\SelectQuery; use Cycle\ORM\Heap\Node; @@ -15,8 +14,6 @@ use Cycle\ORM\Select\QueryBuilder; use Cycle\ORM\Select\RootLoader; use Cycle\ORM\Select\ScopeInterface; -use InvalidArgumentException; -use IteratorAggregate; use Spiral\Pagination\PaginableInterface; /** @@ -52,7 +49,7 @@ * * @template-covariant TEntity of object */ -class Select implements IteratorAggregate, Countable, PaginableInterface +class Select implements \IteratorAggregate, \Countable, PaginableInterface { // load relation data within same query public const SINGLE_QUERY = JoinableLoader::INLOAD; @@ -61,7 +58,6 @@ class Select implements IteratorAggregate, Countable, PaginableInterface public const OUTER_QUERY = JoinableLoader::POSTLOAD; private RootLoader $loader; - private QueryBuilder $builder; private MapperProviderInterface $mapperProvider; private Heap\HeapInterface $heap; @@ -73,7 +69,7 @@ class Select implements IteratorAggregate, Countable, PaginableInterface */ public function __construct( ORMInterface $orm, - string $role + string $role, ) { $this->heap = $orm->getHeap(); $this->schema = $orm->getSchema(); @@ -83,56 +79,17 @@ public function __construct( $orm->getSchema(), $orm->getService(SourceProviderInterface::class), $orm->getFactory(), - $orm->resolveRole($role) + $orm->resolveRole($role), ); $this->builder = new QueryBuilder($this->loader->getQuery(), $this->loader); } - /** - * Remove nested loaders and clean ORM link. - */ - public function __destruct() - { - unset($this->loader, $this->builder); - } - - /** - * Bypassing call to primary select query. - */ - public function __call(string $name, array $arguments): mixed - { - if (in_array(strtoupper($name), ['AVG', 'MIN', 'MAX', 'SUM', 'COUNT'])) { - // aggregations - return $this->builder->withQuery( - $this->loader->buildQuery() - )->__call($name, $arguments); - } - - $result = $this->builder->__call($name, $arguments); - if ($result instanceof QueryBuilder) { - return $this; - } - - return $result; - } - - /** - * Cloning with loader tree cloning. - * - * @attention at this moment binded query parameters would't be cloned! - */ - public function __clone() - { - $this->loader = clone $this->loader; - $this->builder = new QueryBuilder($this->loader->getQuery(), $this->loader); - } - /** * Create new Selector with applied scope. By default no scope used. * * @return static */ - public function scope(ScopeInterface $scope = null): self + public function scope(?ScopeInterface $scope = null): self { $this->loader->setScope($scope); @@ -173,7 +130,7 @@ public function wherePK(string|int|array|object ...$ids): self return \count($ids) > 1 ? $this->__call('where', [$pk, new Parameter($ids)]) - : $this->__call('where', [$pk, current($ids)]); + : $this->__call('where', [$pk, \current($ids)]); } /** @@ -181,7 +138,7 @@ public function wherePK(string|int|array|object ...$ids): self * * @param string|null $column When column is null DISTINCT(PK) will be generated. */ - public function count(string $column = null): int + public function count(?string $column = null): int { if ($column === null) { // @tuneyourserver solves the issue with counting on queries with joins. @@ -409,7 +366,7 @@ public function with(string|array $relation, array $options = []): self * * @return TEntity|null */ - public function fetchOne(array $query = null): ?object + public function fetchOne(?array $query = null): ?object { $select = (clone $this)->where($query)->limit(1); $node = $select->loader->createNode(); @@ -449,7 +406,7 @@ public function getIterator(bool $findInHeap = false): Iterator $this->loader->getTarget(), $node->getResult(), $findInHeap, - typecast: true + typecast: true, ); } @@ -486,6 +443,45 @@ public function loadSubclasses(bool $load = true): self return $this; } + /** + * Bypassing call to primary select query. + */ + public function __call(string $name, array $arguments): mixed + { + if (\in_array(\strtoupper($name), ['AVG', 'MIN', 'MAX', 'SUM', 'COUNT'])) { + // aggregations + return $this->builder->withQuery( + $this->loader->buildQuery(), + )->__call($name, $arguments); + } + + $result = $this->builder->__call($name, $arguments); + if ($result instanceof QueryBuilder) { + return $this; + } + + return $result; + } + + /** + * Cloning with loader tree cloning. + * + * @attention at this moment binded query parameters would't be cloned! + */ + public function __clone() + { + $this->loader = clone $this->loader; + $this->builder = new QueryBuilder($this->loader->getQuery(), $this->loader); + } + + /** + * Remove nested loaders and clean ORM link. + */ + public function __destruct() + { + unset($this->loader, $this->builder); + } + /** * @param list $pk * @param list $args @@ -498,18 +494,18 @@ private function buildCompositePKQuery(array $pk, array $args): self foreach ($args as $index => $values) { $values = $values instanceof Parameter ? $values->getValue() : $values; if (!\is_array($values)) { - throw new InvalidArgumentException('Composite primary key must be defined using an array.'); + throw new \InvalidArgumentException('Composite primary key must be defined using an array.'); } if (\count($pk) !== \count($values)) { - throw new InvalidArgumentException( - \sprintf('Primary key should contain %d values.', \count($pk)) + throw new \InvalidArgumentException( + \sprintf('Primary key should contain %d values.', \count($pk)), ); } $isAssoc = !\array_is_list($values); foreach ($values as $key => $value) { if ($isAssoc && !\in_array($key, $pk, true)) { - throw new InvalidArgumentException(\sprintf('Primary key `%s` not found.', $key)); + throw new \InvalidArgumentException(\sprintf('Primary key `%s` not found.', $key)); } $key = $isAssoc ? $key : $pk[$key]; @@ -517,7 +513,7 @@ private function buildCompositePKQuery(array $pk, array $args): self } } - $this->__call('where', [static function (Select\QueryBuilder $q) use ($prepared) { + $this->__call('where', [static function (Select\QueryBuilder $q) use ($prepared): void { foreach ($prepared as $set) { $q->orWhere($set); } diff --git a/src/Select/AbstractLoader.php b/src/Select/AbstractLoader.php index 8644e1e6..7b6f5616 100644 --- a/src/Select/AbstractLoader.php +++ b/src/Select/AbstractLoader.php @@ -84,45 +84,19 @@ abstract class AbstractLoader implements LoaderInterface * @var array */ protected array $children; + protected SourceInterface $source; public function __construct( protected SchemaInterface $ormSchema, protected SourceProviderInterface $sourceProvider, protected FactoryInterface $factory, - protected string $target + protected string $target, ) { $this->children = $this->ormSchema->getInheritedRoles($target); $this->source = $this->sourceProvider->getSource($target); } - final public function __destruct() - { - unset($this->parent, $this->inherit, $this->subclasses, $this->load, $this->join); - } - - /** - * Ensure state of every nested loader. - */ - public function __clone() - { - $this->parent = null; - - foreach ($this->load as $name => $loader) { - $this->load[$name] = $loader->withContext($this); - } - - foreach ($this->join as $name => $loader) { - $this->join[$name] = $loader->withContext($this); - } - - $this->inherit = $this->inherit?->withContext($this); - - foreach ($this->subclasses as $i => $loader) { - $this->subclasses[$i] = $loader->withContext($this); - } - } - public function isHierarchical(): bool { return $this->inherit !== null || ($this->loadSubclasses && $this->children !== []); @@ -141,13 +115,13 @@ public function getTarget(): string public function withContext(LoaderInterface $parent, array $options = []): static { // check that given options are known - if (!empty($wrong = array_diff(array_keys($options), array_keys($this->options)))) { + if (!empty($wrong = \array_diff(\array_keys($options), \array_keys($this->options)))) { throw new LoaderException( - sprintf( + \sprintf( 'Relation %s does not support option: %s', $this::class, - implode(',', $wrong) - ) + \implode(',', $wrong), + ), ); } @@ -167,9 +141,8 @@ public function withContext(LoaderInterface $parent, array $options = []): stati * @param bool $join When set to true loaders will be forced into JOIN mode. * @param bool $load Load relation data. * - * @throws LoaderException - * * @return LoaderInterface Must return loader for a requested relation. + * @throws LoaderException */ public function loadRelation( string|LoaderInterface $relation, @@ -220,7 +193,7 @@ public function loadRelation( } if ($join) { - if (empty($options['method']) || !in_array($options['method'], [self::JOIN, self::LEFT_JOIN], true)) { + if (empty($options['method']) || !\in_array($options['method'], [self::JOIN, self::LEFT_JOIN], true)) { // let's tell our loaded that it's method is JOIN (forced) $options['method'] = self::JOIN; } @@ -232,16 +205,16 @@ public function loadRelation( $this->ormSchema, $this->sourceProvider, $this->target, - $relation + $relation, ); } catch (SchemaException | FactoryException $e) { if ($this->inherit instanceof self) { return $this->inherit->loadRelation($relation, $options, $join, $load, $alias); } throw new LoaderException( - sprintf('Unable to create loader: %s', $e->getMessage()), + \sprintf('Unable to create loader: %s', $e->getMessage()), $e->getCode(), - $e + $e, ); } @@ -297,6 +270,33 @@ public function getParentLoader(): ?LoaderInterface */ abstract public function isLoaded(): bool; + /** + * Ensure state of every nested loader. + */ + public function __clone() + { + $this->parent = null; + + foreach ($this->load as $name => $loader) { + $this->load[$name] = $loader->withContext($this); + } + + foreach ($this->join as $name => $loader) { + $this->join[$name] = $loader->withContext($this); + } + + $this->inherit = $this->inherit?->withContext($this); + + foreach ($this->subclasses as $i => $loader) { + $this->subclasses[$i] = $loader->withContext($this); + } + } + + final public function __destruct() + { + unset($this->parent, $this->inherit, $this->subclasses, $this->load, $this->join); + } + protected function loadChild(AbstractNode $node, bool $includeRole = false): void { foreach ($this->load as $relation => $loader) { @@ -389,7 +389,7 @@ protected function define(int $property) /** * Returns list of relations to be automatically joined with parent object. */ - protected function getEagerLoaders(string $role = null): \Generator + protected function getEagerLoaders(?string $role = null): \Generator { $role ??= $this->target; $parentLoader = $this->generateParentLoader($role); diff --git a/src/Select/JoinableLoader.php b/src/Select/JoinableLoader.php index 60c77c46..aaf88414 100644 --- a/src/Select/JoinableLoader.php +++ b/src/Select/JoinableLoader.php @@ -64,7 +64,7 @@ public function __construct( FactoryInterface $factory, protected string $name, string $target, - protected array $schema + protected array $schema, ) { parent::__construct($ormSchema, $sourceProvider, $factory, $target); $this->columns = $this->normalizeColumns($this->define(SchemaInterface::COLUMNS)); @@ -173,7 +173,7 @@ public function isJoined(): bool return true; } - return in_array($this->getMethod(), [self::INLOAD, self::JOIN, self::LEFT_JOIN], true); + return \in_array($this->getMethod(), [self::INLOAD, self::JOIN, self::LEFT_JOIN], true); } /** @@ -189,17 +189,7 @@ public function isSubQueried(): bool */ public function isLoaded(): bool { - return $this->options['load'] || in_array($this->getMethod(), [self::INLOAD, self::POSTLOAD], true); - } - - protected function configureSubQuery(SelectQuery $query): SelectQuery - { - if (!$this->isJoined()) { - return $this->configureQuery($query); - } - - $loader = new SubQueryLoader($this->ormSchema, $this->sourceProvider, $this->factory, $this, $this->options); - return $loader->configureQuery($query); + return $this->options['load'] || \in_array($this->getMethod(), [self::INLOAD, self::POSTLOAD], true); } /** @@ -230,6 +220,16 @@ public function configureQuery(SelectQuery $query, array $outerKeys = []): Selec return parent::configureQuery($query); } + protected function configureSubQuery(SelectQuery $query): SelectQuery + { + if (!$this->isJoined()) { + return $this->configureQuery($query); + } + + $loader = new SubQueryLoader($this->ormSchema, $this->sourceProvider, $this->factory, $this, $this->options); + return $loader->configureQuery($query); + } + protected function applyScope(SelectQuery $query): SelectQuery { $this->scope?->apply($this->makeQueryBuilder($query)); diff --git a/src/Select/Loader/BelongsToLoader.php b/src/Select/Loader/BelongsToLoader.php index 0f91ac79..c567f7fe 100644 --- a/src/Select/Loader/BelongsToLoader.php +++ b/src/Select/Loader/BelongsToLoader.php @@ -49,7 +49,7 @@ public function configureQuery(SelectQuery $query, array $outerKeys = []): Selec $this->setWhere( $query, $this->isJoined() ? 'onWhere' : 'where', - $this->options['where'] ?? $this->schema[Relation::WHERE] ?? [] + $this->options['where'] ?? $this->schema[Relation::WHERE] ?? [], ); return parent::configureQuery($query); @@ -59,9 +59,9 @@ protected function initNode(): AbstractNode { return new SingularNode( $this->columnNames(), - (array)$this->define(SchemaInterface::PRIMARY_KEY), - (array)$this->schema[Relation::OUTER_KEY], - (array)$this->schema[Relation::INNER_KEY] + (array) $this->define(SchemaInterface::PRIMARY_KEY), + (array) $this->schema[Relation::OUTER_KEY], + (array) $this->schema[Relation::INNER_KEY], ); } } diff --git a/src/Select/Loader/EmbeddedLoader.php b/src/Select/Loader/EmbeddedLoader.php index 6d8f8430..5ef999df 100644 --- a/src/Select/Loader/EmbeddedLoader.php +++ b/src/Select/Loader/EmbeddedLoader.php @@ -22,7 +22,6 @@ final class EmbeddedLoader implements JoinableInterface use ColumnsTrait; private ?LoaderInterface $parent = null; - private array $options = [ 'load' => false, 'minify' => true, @@ -30,10 +29,10 @@ final class EmbeddedLoader implements JoinableInterface public function __construct( private SchemaInterface $ormSchema, - private string $target + private string $target, ) { // never duplicate primary key in data selection - $primaryKey = (array)$this->define(SchemaInterface::PRIMARY_KEY); + $primaryKey = (array) $this->define(SchemaInterface::PRIMARY_KEY); foreach ($this->normalizeColumns($this->define(SchemaInterface::COLUMNS)) as $internal => $external) { if (!\in_array($internal, $primaryKey, true)) { $this->columns[$internal] = $external; @@ -41,22 +40,6 @@ public function __construct( } } - /** - * Destruct loader. - */ - public function __destruct() - { - unset($this->parent); - } - - /** - * Ensure state of every nested loader. - */ - public function __clone() - { - $this->parent = null; - } - public function getAlias(): string { // always fallback to parent table name @@ -103,7 +86,7 @@ public function createNode(): AbstractNode { return new EmbeddedNode( $this->columnNames(), - (array)$this->ormSchema->define($this->parent->getTarget(), SchemaInterface::PRIMARY_KEY) + (array) $this->ormSchema->define($this->parent->getTarget(), SchemaInterface::PRIMARY_KEY), ); } @@ -112,23 +95,37 @@ public function loadData(AbstractNode $node, bool $includeRole = false): void // embedded entities does not support inner loaders... for now! :) } + public function setSubclassesLoading(bool $enabled): void {} + + public function isHierarchical(): bool + { + // Embedded can't be hierarchical + return false; + } + /** - * Define schema option associated with the entity. - * - * @return mixed + * Ensure state of every nested loader. */ - protected function define(int $property) + public function __clone() { - return $this->ormSchema->define($this->target, $property); + $this->parent = null; } - public function setSubclassesLoading(bool $enabled): void + /** + * Destruct loader. + */ + public function __destruct() { + unset($this->parent); } - public function isHierarchical(): bool + /** + * Define schema option associated with the entity. + * + * @return mixed + */ + protected function define(int $property) { - // Embedded can't be hierarchical - return false; + return $this->ormSchema->define($this->target, $property); } } diff --git a/src/Select/Loader/HasManyLoader.php b/src/Select/Loader/HasManyLoader.php index 39ccf802..fed2ab3f 100644 --- a/src/Select/Loader/HasManyLoader.php +++ b/src/Select/Loader/HasManyLoader.php @@ -46,7 +46,7 @@ public function __construct( FactoryInterface $factory, string $name, string $target, - array $schema + array $schema, ) { parent::__construct($ormSchema, $sourceProvider, $factory, $name, $target, $schema); $this->options['where'] = $schema[Relation::WHERE] ?? []; @@ -70,14 +70,14 @@ public function configureQuery(SelectQuery $query, array $outerKeys = []): Selec $this->setWhere( $query, $this->isJoined() ? 'onWhere' : 'where', - $this->options['where'] ?? $this->schema[Relation::WHERE] ?? [] + $this->options['where'] ?? $this->schema[Relation::WHERE] ?? [], ); // user specified ORDER_BY rules $this->setOrderBy( $query, $this->getAlias(), - $this->options['orderBy'] ?? $this->schema[Relation::ORDER_BY] ?? [] + $this->options['orderBy'] ?? $this->schema[Relation::ORDER_BY] ?? [], ); return parent::configureQuery($query); @@ -87,9 +87,9 @@ protected function initNode(): AbstractNode { return new ArrayNode( $this->columnNames(), - (array)$this->define(SchemaInterface::PRIMARY_KEY), - (array)$this->schema[Relation::OUTER_KEY], - (array)$this->schema[Relation::INNER_KEY] + (array) $this->define(SchemaInterface::PRIMARY_KEY), + (array) $this->schema[Relation::OUTER_KEY], + (array) $this->schema[Relation::INNER_KEY], ); } } diff --git a/src/Select/Loader/HasOneLoader.php b/src/Select/Loader/HasOneLoader.php index fbb3f35c..c27df54d 100644 --- a/src/Select/Loader/HasOneLoader.php +++ b/src/Select/Loader/HasOneLoader.php @@ -53,7 +53,7 @@ public function configureQuery(SelectQuery $query, array $outerKeys = []): Selec $this->setWhere( $query, $this->isJoined() ? 'onWhere' : 'where', - $this->options['where'] ?? $this->schema[Relation::WHERE] ?? [] + $this->options['where'] ?? $this->schema[Relation::WHERE] ?? [], ); return parent::configureQuery($query); @@ -63,9 +63,9 @@ protected function initNode(): AbstractNode { return new SingularNode( $this->columnNames(), - (array)$this->define(SchemaInterface::PRIMARY_KEY), - (array)$this->schema[Relation::OUTER_KEY], - (array)$this->schema[Relation::INNER_KEY] + (array) $this->define(SchemaInterface::PRIMARY_KEY), + (array) $this->schema[Relation::OUTER_KEY], + (array) $this->schema[Relation::INNER_KEY], ); } } diff --git a/src/Select/Loader/ManyToManyLoader.php b/src/Select/Loader/ManyToManyLoader.php index 30beeb05..e0655d94 100644 --- a/src/Select/Loader/ManyToManyLoader.php +++ b/src/Select/Loader/ManyToManyLoader.php @@ -49,7 +49,7 @@ public function __construct( FactoryInterface $factory, string $name, string $target, - array $schema + array $schema, ) { parent::__construct($ormSchema, $sourceProvider, $factory, $name, $target, $schema); $this->pivot = new PivotLoader( @@ -58,21 +58,12 @@ public function __construct( $factory, 'pivot', $schema[Relation::THROUGH_ENTITY], - $schema + $schema, ); $this->options['where'] = $schema[Relation::WHERE] ?? []; $this->options['orderBy'] = $schema[Relation::ORDER_BY] ?? []; } - /** - * Make sure that pivot loader is always carried with parent relation. - */ - public function __clone() - { - parent::__clone(); - $this->pivot = clone $this->pivot; - } - public function withContext(LoaderInterface $parent, array $options = []): static { /** @var ManyToManyLoader $loader */ @@ -82,7 +73,7 @@ public function withContext(LoaderInterface $parent, array $options = []): stati [ 'load' => $loader->isLoaded(), 'method' => $options['method'] ?? self::JOIN, - ] + ($options['pivot'] ?? []) + ] + ($options['pivot'] ?? []), ); return $loader; @@ -124,61 +115,61 @@ public function configureQuery(SelectQuery $query, array $outerKeys = []): Selec // Manually join pivoted table if ($this->isJoined()) { - $parentKeys = (array)$this->schema[Relation::INNER_KEY]; - $throughOuterKeys = (array)$this->pivot->schema[Relation::THROUGH_OUTER_KEY]; + $parentKeys = (array) $this->schema[Relation::INNER_KEY]; + $throughOuterKeys = (array) $this->pivot->schema[Relation::THROUGH_OUTER_KEY]; $parentPrefix = $this->parent->getAlias() . '.'; $on = []; - foreach ((array)$this->pivot->schema[Relation::THROUGH_INNER_KEY] as $i => $key) { + foreach ((array) $this->pivot->schema[Relation::THROUGH_INNER_KEY] as $i => $key) { $field = $pivotPrefix . $this->pivot->fieldAlias($key); $on[$field] = $parentPrefix . $this->parent->fieldAlias($parentKeys[$i]); } $query->join( $this->getJoinMethod(), - $this->pivot->getJoinTable() + $this->pivot->getJoinTable(), )->on($on); $on = []; - foreach ((array)$this->schema[Relation::OUTER_KEY] as $i => $key) { + foreach ((array) $this->schema[Relation::OUTER_KEY] as $i => $key) { $field = $localPrefix . $this->fieldAlias($key); $on[$field] = $pivotPrefix . $this->pivot->fieldAlias($throughOuterKeys[$i]); } $query->join( $this->getJoinMethod(), - $this->getJoinTable() + $this->getJoinTable(), )->on($on); } elseif ($outerKeys !== []) { // reset all the columns when query is isolated (we have to do it manually // since underlying loader believes it's loaded) $query->columns([]); - $outerKeyList = (array)$this->schema[Relation::OUTER_KEY]; + $outerKeyList = (array) $this->schema[Relation::OUTER_KEY]; $on = []; - foreach ((array)$this->pivot->schema[Relation::THROUGH_OUTER_KEY] as $i => $key) { + foreach ((array) $this->pivot->schema[Relation::THROUGH_OUTER_KEY] as $i => $key) { $field = $pivotPrefix . $this->pivot->fieldAlias($key); $on[$field] = $localPrefix . $this->fieldAlias($outerKeyList[$i]); } $query->join( $this->getJoinMethod(), - $this->pivot->getJoinTable() + $this->pivot->getJoinTable(), )->on($on); $fields = []; - foreach ((array)$this->pivot->schema[Relation::THROUGH_INNER_KEY] as $key) { + foreach ((array) $this->pivot->schema[Relation::THROUGH_INNER_KEY] as $key) { $fields[] = $pivotPrefix . $this->pivot->fieldAlias($key); } if (\count($fields) === 1) { - $query->andWhere($fields[0], 'IN', new Parameter(array_column($outerKeys, key($outerKeys[0])))); + $query->andWhere($fields[0], 'IN', new Parameter(\array_column($outerKeys, \key($outerKeys[0])))); } else { $query->andWhere( - static function (SelectQuery $select) use ($outerKeys, $fields) { + static function (SelectQuery $select) use ($outerKeys, $fields): void { foreach ($outerKeys as $set) { - $select->orWhere(array_combine($fields, array_values($set))); + $select->orWhere(\array_combine($fields, \array_values($set))); } - } + }, ); } } @@ -187,14 +178,14 @@ static function (SelectQuery $select) use ($outerKeys, $fields) { $this->setWhere( $query, $this->isJoined() ? 'onWhere' : 'where', - $this->options['where'] ?? $this->schema[Relation::WHERE] ?? [] + $this->options['where'] ?? $this->schema[Relation::WHERE] ?? [], ); // user specified ORDER_BY rules $this->setOrderBy( $query, $this->getAlias(), - $this->options['orderBy'] ?? $this->schema[Relation::ORDER_BY] ?? [] + $this->options['orderBy'] ?? $this->schema[Relation::ORDER_BY] ?? [], ); return parent::configureQuery($this->pivot->configureQuery($query)); @@ -208,6 +199,15 @@ public function createNode(): AbstractNode return $node; } + /** + * Make sure that pivot loader is always carried with parent relation. + */ + public function __clone() + { + parent::__clone(); + $this->pivot = clone $this->pivot; + } + protected function loadChild(AbstractNode $node, bool $includeRole = false): void { $rootNode = $node->getNode('@'); @@ -222,7 +222,7 @@ protected function mountColumns( SelectQuery $query, bool $minify = false, string $prefix = '', - bool $overwrite = false + bool $overwrite = false, ): SelectQuery { // columns are reset on earlier stage to allow pivot loader mount it's own aliases return parent::mountColumns($query, $minify, $prefix, false); @@ -232,9 +232,9 @@ protected function initNode(): AbstractNode { return new SingularNode( $this->columnNames(), - (array)$this->define(SchemaInterface::PRIMARY_KEY), - (array)$this->schema[Relation::OUTER_KEY], - (array)$this->schema[Relation::THROUGH_OUTER_KEY] + (array) $this->define(SchemaInterface::PRIMARY_KEY), + (array) $this->schema[Relation::OUTER_KEY], + (array) $this->schema[Relation::THROUGH_OUTER_KEY], ); } } diff --git a/src/Select/Loader/Morphed/MorphedHasManyLoader.php b/src/Select/Loader/Morphed/MorphedHasManyLoader.php index c91c5512..d19095eb 100644 --- a/src/Select/Loader/Morphed/MorphedHasManyLoader.php +++ b/src/Select/Loader/Morphed/MorphedHasManyLoader.php @@ -21,7 +21,7 @@ public function configureQuery(SelectQuery $query, array $outerKeys = []): Selec return $this->setWhere( parent::configureQuery($query, $outerKeys), $this->isJoined() ? 'onWhere' : 'where', - [$this->localKey(Relation::MORPH_KEY) => $this->parent->getTarget()] + [$this->localKey(Relation::MORPH_KEY) => $this->parent->getTarget()], ); } } diff --git a/src/Select/Loader/Morphed/MorphedHasOneLoader.php b/src/Select/Loader/Morphed/MorphedHasOneLoader.php index 25e657e0..217f62c7 100644 --- a/src/Select/Loader/Morphed/MorphedHasOneLoader.php +++ b/src/Select/Loader/Morphed/MorphedHasOneLoader.php @@ -21,7 +21,7 @@ public function configureQuery(SelectQuery $query, array $outerKeys = []): Selec return $this->setWhere( parent::configureQuery($query, $outerKeys), $this->isJoined() ? 'onWhere' : 'where', - [$this->localKey(Relation::MORPH_KEY) => $this->parent->getTarget()] + [$this->localKey(Relation::MORPH_KEY) => $this->parent->getTarget()], ); } } diff --git a/src/Select/Loader/ParentLoader.php b/src/Select/Loader/ParentLoader.php index d3a41f53..b73c3230 100644 --- a/src/Select/Loader/ParentLoader.php +++ b/src/Select/Loader/ParentLoader.php @@ -40,7 +40,7 @@ public function __construct( SourceProviderInterface $sourceProvider, FactoryInterface $factory, string $role, - string $target + string $target, ) { $schemaArray = [ Relation::INNER_KEY => $ormSchema->define($role, SchemaInterface::PRIMARY_KEY), @@ -51,11 +51,6 @@ public function __construct( parent::__construct($ormSchema, $sourceProvider, $factory, $role, $target, $schemaArray); } - protected function generateSublassLoaders(): iterable - { - return []; - } - public function configureQuery(SelectQuery $query, array $outerKeys = []): SelectQuery { if ($this->options['using'] !== null) { @@ -68,6 +63,11 @@ public function configureQuery(SelectQuery $query, array $outerKeys = []): Selec return parent::configureQuery($query); } + protected function generateSublassLoaders(): iterable + { + return []; + } + protected function getJoinMethod(): string { return 'INNER'; @@ -78,9 +78,9 @@ protected function initNode(): AbstractNode return new ParentMergeNode( $this->target, $this->columnNames(), - (array)$this->define(SchemaInterface::PRIMARY_KEY), - (array)$this->schema[Relation::OUTER_KEY], - (array)$this->schema[Relation::INNER_KEY] + (array) $this->define(SchemaInterface::PRIMARY_KEY), + (array) $this->schema[Relation::OUTER_KEY], + (array) $this->schema[Relation::INNER_KEY], ); } } diff --git a/src/Select/Loader/PivotLoader.php b/src/Select/Loader/PivotLoader.php index b4d660d1..3e32685e 100644 --- a/src/Select/Loader/PivotLoader.php +++ b/src/Select/Loader/PivotLoader.php @@ -44,7 +44,7 @@ public function configureQuery(SelectQuery $query, array $outerKeys = []): Selec $this->setWhere( $query, $this->isJoined() ? 'onWhere' : 'where', - $this->options['where'] ?? $this->schema[Relation::THROUGH_WHERE] ?? [] + $this->options['where'] ?? $this->schema[Relation::THROUGH_WHERE] ?? [], ); return parent::configureQuery($query, $outerKeys); @@ -54,9 +54,9 @@ protected function initNode(): AbstractNode { return new ArrayNode( $this->columnNames(), - (array)$this->define(SchemaInterface::PRIMARY_KEY), - (array)$this->schema[Relation::THROUGH_INNER_KEY], - (array)$this->schema[Relation::INNER_KEY] + (array) $this->define(SchemaInterface::PRIMARY_KEY), + (array) $this->schema[Relation::THROUGH_INNER_KEY], + (array) $this->schema[Relation::INNER_KEY], ); } } diff --git a/src/Select/Loader/SubQueryLoader.php b/src/Select/Loader/SubQueryLoader.php index 556fa23f..1933f246 100644 --- a/src/Select/Loader/SubQueryLoader.php +++ b/src/Select/Loader/SubQueryLoader.php @@ -24,7 +24,6 @@ final class SubQueryLoader extends JoinableLoader 'using' => null, 'as' => null, ]; - private JoinableLoader $loader; public function __construct( @@ -32,7 +31,7 @@ public function __construct( SourceProviderInterface $sourceProvider, FactoryInterface $factory, JoinableLoader $loader, - array $options + array $options, ) { parent::__construct($ormSchema, $sourceProvider, $factory, $loader->name, $loader->getTarget(), $loader->schema); @@ -52,16 +51,16 @@ public function configureQuery(SelectQuery $query, array $outerKeys = []): Selec $queryColumns = $query->getColumns(); $body = $this->loader->source->getDatabase()->select()->from( - sprintf('%s AS %s', $this->loader->source->getTable(), $lAlias) + \sprintf('%s AS %s', $this->loader->source->getTable(), $lAlias), )->columns($queryColumns); $body = $this->loader->configureQuery($body); - $bodyColumns = array_slice($body->getColumns(), count($queryColumns)); + $bodyColumns = \array_slice($body->getColumns(), \count($queryColumns)); $body = $body->columns($bodyColumns); $aliases = []; // Move columns to parent query foreach ($bodyColumns as $column) { - preg_match('/^([^\\s]+)\\.([^\\s]+) AS ([^\\s]+)$/i', $column, $matches); + \preg_match('/^([^\\s]+)\\.([^\\s]+) AS ([^\\s]+)$/i', $column, $matches); [, $table, $column, $as] = $matches; $queryColumns[] = "$alias.$as AS $as"; if ($table === $lAlias) { @@ -70,10 +69,10 @@ public function configureQuery(SelectQuery $query, array $outerKeys = []): Selec } $query = $query->columns($queryColumns); - $parentKeys = (array)$this->schema[Relation::INNER_KEY]; + $parentKeys = (array) $this->schema[Relation::INNER_KEY]; $parentPrefix = $this->parent->getAlias() . '.'; $on = []; - foreach ((array)$this->schema[Relation::OUTER_KEY] as $i => $key) { + foreach ((array) $this->schema[Relation::OUTER_KEY] as $i => $key) { $field = $alias . '.' . $aliases[$this->fieldAlias($key)]; $on[$field] = $parentPrefix . $this->parent->fieldAlias($parentKeys[$i]); } diff --git a/src/Select/Loader/SubclassLoader.php b/src/Select/Loader/SubclassLoader.php index cbf1cd63..1d4c2d78 100644 --- a/src/Select/Loader/SubclassLoader.php +++ b/src/Select/Loader/SubclassLoader.php @@ -41,7 +41,7 @@ public function __construct( SourceProviderInterface $sourceProvider, FactoryInterface $factory, string $role, - string $target + string $target, ) { $schemaArray = [ Relation::INNER_KEY => $ormSchema->define($target, SchemaInterface::PARENT_KEY) @@ -74,9 +74,9 @@ protected function initNode(): AbstractNode return new SubclassMergeNode( $this->target, $this->columnNames(), - (array)$this->define(SchemaInterface::PRIMARY_KEY), - (array)$this->schema[Relation::OUTER_KEY], - (array)$this->schema[Relation::INNER_KEY] + (array) $this->define(SchemaInterface::PRIMARY_KEY), + (array) $this->schema[Relation::OUTER_KEY], + (array) $this->schema[Relation::INNER_KEY], ); } diff --git a/src/Select/QueryBuilder.php b/src/Select/QueryBuilder.php index 63006b74..c6793425 100644 --- a/src/Select/QueryBuilder.php +++ b/src/Select/QueryBuilder.php @@ -4,7 +4,6 @@ namespace Cycle\ORM\Select; -use Closure; use Cycle\ORM\Exception\BuilderException; use JetBrains\PhpStorm\ExpectedValues; use Cycle\Database\Driver\Compiler; @@ -48,28 +47,8 @@ final class QueryBuilder public function __construct( private SelectQuery $query, /** @internal */ - private AbstractLoader $loader - ) { - } - - /** - * Forward call to underlying target. - * - * @return mixed|SelectQuery - */ - public function __call(string $func, array $args) - { - $result = \call_user_func_array( - $this->targetFunc($func), - $this->isJoin($func) ? $args : $this->proxyArgs($args) - ); - - if ($result === $this->query) { - return $this; - } - - return $result; - } + private AbstractLoader $loader, + ) {} /** * Get currently associated query. Immutable. @@ -92,7 +71,7 @@ public function getLoader(): AbstractLoader */ public function withForward( #[ExpectedValues(values: ['where', 'onWhere'])] - string $forward = null + ?string $forward = null, ): self { $builder = clone $this; $builder->forward = $forward; @@ -168,6 +147,25 @@ public function with(string $relation, array $options = []): self return $this; } + /** + * Forward call to underlying target. + * + * @return mixed|SelectQuery + */ + public function __call(string $func, array $args) + { + $result = \call_user_func_array( + $this->targetFunc($func), + $this->isJoin($func) ? $args : $this->proxyArgs($args), + ); + + if ($result === $this->query) { + return $this; + } + + return $result; + } + /** * Find loader associated with given entity/relation alias. * @@ -175,7 +173,7 @@ public function with(string $relation, array $options = []): self */ private function findLoader(string $name, bool $autoload = true): ?LoaderInterface { - if (strpos($name, '(')) { + if (\strpos($name, '(')) { // expressions are not allowed return null; } @@ -195,15 +193,15 @@ private function findLoader(string $name, bool $autoload = true): ?LoaderInterfa private function targetFunc(string $call): callable { if ($this->forward != null) { - switch (strtolower($call)) { + switch (\strtolower($call)) { case 'where': $call = $this->forward; break; case 'orwhere': - $call = 'or' . ucfirst($this->forward); + $call = 'or' . \ucfirst($this->forward); break; case 'andwhere': - $call = 'and' . ucfirst($this->forward); + $call = 'and' . \ucfirst($this->forward); break; } } @@ -229,7 +227,7 @@ private function proxyArgs(array $args): array $args[0] = $this->walkRecursive($args[0], [$this, 'wrap']); } - if ($args[0] instanceof Closure) { + if ($args[0] instanceof \Closure) { $args[0] = function ($q) use ($args): void { $args[0]($this->withQuery($q)); }; @@ -249,7 +247,7 @@ private function wrap(int|string &$identifier, &$value): void $identifier = $this->resolve($identifier); } - if ($value instanceof Closure) { + if ($value instanceof \Closure) { $value = function ($q) use ($value): void { $value($this->withQuery($q)); }; diff --git a/src/Select/QueryScope.php b/src/Select/QueryScope.php index 86967c4d..e882ec75 100644 --- a/src/Select/QueryScope.php +++ b/src/Select/QueryScope.php @@ -11,9 +11,8 @@ final class QueryScope implements ScopeInterface { public function __construct( private array $where, - private array $orderBy = [] - ) { - } + private array $orderBy = [], + ) {} public function apply(QueryBuilder $query): void { diff --git a/src/Select/Repository.php b/src/Select/Repository.php index 06aa5810..ef6a3157 100644 --- a/src/Select/Repository.php +++ b/src/Select/Repository.php @@ -24,16 +24,7 @@ class Repository implements RepositoryInterface public function __construct( /** @readonly */ protected Select $select, - ) { - } - - /** - * Repositories are always immutable by default. - */ - public function __clone() - { - $this->select = clone $this->select; - } + ) {} public function findByPK($id): ?object { @@ -67,4 +58,12 @@ public function forUpdate(): static return $repository; } + + /** + * Repositories are always immutable by default. + */ + public function __clone() + { + $this->select = clone $this->select; + } } diff --git a/src/Select/RootLoader.php b/src/Select/RootLoader.php index e2c760a7..e0dddb42 100644 --- a/src/Select/RootLoader.php +++ b/src/Select/RootLoader.php @@ -29,7 +29,6 @@ final class RootLoader extends AbstractLoader use ColumnsTrait; use ScopeTrait; - /** @var array */ protected array $options = [ 'load' => true, 'scope' => true, @@ -49,7 +48,7 @@ public function __construct( ) { parent::__construct($ormSchema, $sourceProvider, $factory, $target); $this->query = $this->source->getDatabase()->select()->from( - sprintf('%s AS %s', $this->source->getTable(), $this->getAlias()) + \sprintf('%s AS %s', $this->source->getTable(), $this->getAlias()), ); $this->columns = $this->normalizeColumns($this->define(SchemaInterface::COLUMNS)); @@ -60,15 +59,6 @@ public function __construct( } } - /** - * Clone the underlying query. - */ - public function __clone() - { - $this->query = clone $this->query; - parent::__clone(); - } - public function getAlias(): string { return $this->target; @@ -100,7 +90,7 @@ public function getPK(): array|string */ public function getPrimaryFields(): array { - return (array)$this->define(SchemaInterface::PRIMARY_KEY); + return (array) $this->define(SchemaInterface::PRIMARY_KEY); } /** @@ -143,15 +133,24 @@ public function isLoaded(): bool return true; } + /** + * Clone the underlying query. + */ + public function __clone() + { + $this->query = clone $this->query; + parent::__clone(); + } + protected function configureQuery(SelectQuery $query): SelectQuery { return parent::configureQuery( - $this->mountColumns($query, true, '', true) + $this->mountColumns($query, true, '', true), ); } protected function initNode(): RootNode { - return new RootNode($this->columnNames(), (array)$this->define(SchemaInterface::PRIMARY_KEY)); + return new RootNode($this->columnNames(), (array) $this->define(SchemaInterface::PRIMARY_KEY)); } } diff --git a/src/Select/Source.php b/src/Select/Source.php index b45a0d99..a3cc99db 100644 --- a/src/Select/Source.php +++ b/src/Select/Source.php @@ -12,9 +12,8 @@ final class Source implements SourceInterface public function __construct( private DatabaseInterface $database, - private string $table - ) { - } + private string $table, + ) {} public function getDatabase(): DatabaseInterface { diff --git a/src/Select/Traits/ChainTrait.php b/src/Select/Traits/ChainTrait.php index 585cb338..df753acf 100644 --- a/src/Select/Traits/ChainTrait.php +++ b/src/Select/Traits/ChainTrait.php @@ -25,7 +25,7 @@ abstract public function loadRelation( */ protected function isChain(string $relation): bool { - return str_contains($relation, '.'); + return \str_contains($relation, '.'); } /** @@ -39,18 +39,18 @@ protected function isChain(string $relation): bool */ protected function loadChain(string $chain, array $options, bool $join, bool $load): LoaderInterface { - $position = strpos($chain, '.'); + $position = \strpos($chain, '.'); // chain of relations provided (relation.nestedRelation) - $child = $this->loadRelation(substr($chain, 0, $position), [], $join, $load); + $child = $this->loadRelation(\substr($chain, 0, $position), [], $join, $load); if (!$child instanceof AbstractLoader) { throw new LoaderException( - sprintf('Loader `%s` does not support chain relation loading.', $child::class) + \sprintf('Loader `%s` does not support chain relation loading.', $child::class), ); } // load nested relation through chain (chainOptions prior to user options) - return $child->loadRelation(substr($chain, $position + 1), $options, $join, $load); + return $child->loadRelation(\substr($chain, $position + 1), $options, $join, $load); } } diff --git a/src/Select/Traits/ColumnsTrait.php b/src/Select/Traits/ColumnsTrait.php index 3bbcfa56..9ca5ab54 100644 --- a/src/Select/Traits/ColumnsTrait.php +++ b/src/Select/Traits/ColumnsTrait.php @@ -46,7 +46,7 @@ protected function mountColumns( SelectQuery $query, bool $minify = false, string $prefix = '', - bool $overwrite = false + bool $overwrite = false, ): SelectQuery { $alias = $this->getAlias(); $columns = $overwrite ? [] : $query->getColumns(); diff --git a/src/Select/Traits/JoinOneTableTrait.php b/src/Select/Traits/JoinOneTableTrait.php index ba5469b1..20d2f1b8 100644 --- a/src/Select/Traits/JoinOneTableTrait.php +++ b/src/Select/Traits/JoinOneTableTrait.php @@ -27,17 +27,17 @@ private function configureJoinedQuery(SelectQuery $query): void { $localPrefix = $this->getAlias() . '.'; $parentPrefix = $this->parent->getAlias() . '.'; - $parentKeys = (array)$this->schema[Relation::INNER_KEY]; + $parentKeys = (array) $this->schema[Relation::INNER_KEY]; $on = []; - foreach ((array)$this->schema[Relation::OUTER_KEY] as $i => $key) { + foreach ((array) $this->schema[Relation::OUTER_KEY] as $i => $key) { $field = $localPrefix . $this->fieldAlias($key); $on[$field] = $parentPrefix . $this->parent->fieldAlias($parentKeys[$i]); } $query->join( $this->getJoinMethod(), - $this->getJoinTable() + $this->getJoinTable(), )->on($on); } @@ -46,19 +46,19 @@ private function configureSeparatedQuery(SelectQuery $query, array $outerKeys): $localPrefix = $this->getAlias() . '.'; $fields = []; - foreach ((array)$this->schema[Relation::OUTER_KEY] as $key) { + foreach ((array) $this->schema[Relation::OUTER_KEY] as $key) { $fields[] = $localPrefix . $this->fieldAlias($key); } if (\count($fields) === 1) { - $query->andWhere($fields[0], 'IN', new Parameter(array_column($outerKeys, key($outerKeys[0])))); + $query->andWhere($fields[0], 'IN', new Parameter(\array_column($outerKeys, \key($outerKeys[0])))); } else { $query->andWhere( - static function (SelectQuery $select) use ($outerKeys, $fields) { + static function (SelectQuery $select) use ($outerKeys, $fields): void { foreach ($outerKeys as $set) { - $select->orWhere(array_combine($fields, array_values($set))); + $select->orWhere(\array_combine($fields, \array_values($set))); } - } + }, ); } } diff --git a/src/Select/Traits/ScopeTrait.php b/src/Select/Traits/ScopeTrait.php index b7a64e35..15d4e289 100644 --- a/src/Select/Traits/ScopeTrait.php +++ b/src/Select/Traits/ScopeTrait.php @@ -20,7 +20,7 @@ trait ScopeTrait /** * Associate scope with the selector. */ - public function setScope(ScopeInterface $scope = null): self + public function setScope(?ScopeInterface $scope = null): self { $this->scope = $scope; diff --git a/src/Select/Traits/WhereTrait.php b/src/Select/Traits/WhereTrait.php index d700750e..feb87230 100644 --- a/src/Select/Traits/WhereTrait.php +++ b/src/Select/Traits/WhereTrait.php @@ -4,7 +4,6 @@ namespace Cycle\ORM\Select\Traits; -use Closure; use Cycle\ORM\Select\QueryBuilder; use Cycle\Database\Query\SelectQuery; @@ -17,12 +16,12 @@ trait WhereTrait { /** * @param string $target Query target section (accepts: where, having, onWhere, on) - * @param array|Closure $where Where conditions in a form or short array form. + * @param array|\Closure $where Where conditions in a form or short array form. */ private function setWhere( SelectQuery $query, string $target, - array|Closure $where = null + array|\Closure|null $where = null, ): SelectQuery { if ($where === []) { // no conditions, nothing to do diff --git a/src/Service/Implementation/EntityFactory.php b/src/Service/Implementation/EntityFactory.php index 4943a30d..620daf83 100644 --- a/src/Service/Implementation/EntityFactory.php +++ b/src/Service/Implementation/EntityFactory.php @@ -26,14 +26,13 @@ public function __construct( private MapperProviderInterface $mapperProvider, private RelationProviderInterface $relationProvider, private IndexProviderInterface $indexProvider, - ) { - } + ) {} public function make( string $role, array $data = [], int $status = Node::NEW, - bool $typecast = false + bool $typecast = false, ): object { $role = $data[LoaderInterface::ROLE_KEY] ?? $role; unset($data[LoaderInterface::ROLE_KEY]); @@ -91,7 +90,7 @@ public function resolveRole(object|string $entity): string $class = $entity::class; if (!$this->schema->defines($class)) { - $parentClass = get_parent_class($entity); + $parentClass = \get_parent_class($entity); if ($parentClass === false || !$entity instanceof EntityProxyInterface diff --git a/src/Service/Implementation/EntityProvider.php b/src/Service/Implementation/EntityProvider.php index c395a960..b80dffc0 100644 --- a/src/Service/Implementation/EntityProvider.php +++ b/src/Service/Implementation/EntityProvider.php @@ -16,8 +16,7 @@ final class EntityProvider implements EntityProviderInterface public function __construct( private HeapInterface $heap, private RepositoryProviderInterface $repositoryProvider, - ) { - } + ) {} public function get(string $role, array $scope, bool $load = true): ?object { diff --git a/src/Service/Implementation/IndexProvider.php b/src/Service/Implementation/IndexProvider.php index 3d32dffd..a3341233 100644 --- a/src/Service/Implementation/IndexProvider.php +++ b/src/Service/Implementation/IndexProvider.php @@ -7,8 +7,6 @@ use Cycle\ORM\Service\IndexProviderInterface; use Cycle\ORM\SchemaInterface; -use const SORT_REGULAR; - /** * @internal */ @@ -18,8 +16,7 @@ final class IndexProvider implements IndexProviderInterface public function __construct( private SchemaInterface $schema, - ) { - } + ) {} public function getIndexes(string $entity): array { @@ -30,6 +27,6 @@ public function getIndexes(string $entity): array $pk = $this->schema->define($entity, SchemaInterface::PRIMARY_KEY); $keys = $this->schema->define($entity, SchemaInterface::FIND_BY_KEYS) ?? []; - return $this->indexes[$entity] = \array_unique(\array_merge([$pk], $keys), SORT_REGULAR); + return $this->indexes[$entity] = \array_unique(\array_merge([$pk], $keys), \SORT_REGULAR); } } diff --git a/src/Service/Implementation/MapperProvider.php b/src/Service/Implementation/MapperProvider.php index 22dbf17e..699e9c70 100644 --- a/src/Service/Implementation/MapperProvider.php +++ b/src/Service/Implementation/MapperProvider.php @@ -20,9 +20,8 @@ final class MapperProvider implements MapperProviderInterface public function __construct( private ?ORMInterface $orm, - private FactoryInterface $factory - ) { - } + private FactoryInterface $factory, + ) {} public function getMapper(string $entity): MapperInterface { diff --git a/src/Service/Implementation/RelationProvider.php b/src/Service/Implementation/RelationProvider.php index eb56e0cc..ae5213a2 100644 --- a/src/Service/Implementation/RelationProvider.php +++ b/src/Service/Implementation/RelationProvider.php @@ -19,8 +19,7 @@ final class RelationProvider implements RelationProviderInterface public function __construct( private ?ORMInterface $orm, - ) { - } + ) {} /** * Get relation map associated with the given class. diff --git a/src/Service/Implementation/RepositoryProvider.php b/src/Service/Implementation/RepositoryProvider.php index 847f5fc8..90ebec26 100644 --- a/src/Service/Implementation/RepositoryProvider.php +++ b/src/Service/Implementation/RepositoryProvider.php @@ -25,9 +25,8 @@ public function __construct( private ?ORMInterface $orm, private SourceProviderInterface $sourceProvider, private SchemaInterface $schema, - private FactoryInterface $factory - ) { - } + private FactoryInterface $factory, + ) {} public function getRepository(string $entity): RepositoryInterface { diff --git a/src/Service/Implementation/SourceProvider.php b/src/Service/Implementation/SourceProvider.php index 470ff248..f56742e2 100644 --- a/src/Service/Implementation/SourceProvider.php +++ b/src/Service/Implementation/SourceProvider.php @@ -20,8 +20,7 @@ final class SourceProvider implements SourceProviderInterface public function __construct( private FactoryInterface $factory, private SchemaInterface $schema, - ) { - } + ) {} /** * @param non-empty-string $entity diff --git a/src/Service/Implementation/TypecastProvider.php b/src/Service/Implementation/TypecastProvider.php index 03543c64..e11a4e26 100644 --- a/src/Service/Implementation/TypecastProvider.php +++ b/src/Service/Implementation/TypecastProvider.php @@ -22,8 +22,7 @@ public function __construct( private FactoryInterface $factory, private SchemaInterface $schema, private SourceProviderInterface $sourceProvider, - ) { - } + ) {} public function getTypecast(string $role): ?TypecastInterface { @@ -32,7 +31,7 @@ public function getTypecast(string $role): ?TypecastInterface : ($this->typecasts[$role] = $this->factory->typecast( $this->schema, $this->sourceProvider->getSource($role)->getDatabase(), - $role + $role, )); } } diff --git a/src/Transaction.php b/src/Transaction.php index 2041fd5a..827c0809 100644 --- a/src/Transaction.php +++ b/src/Transaction.php @@ -22,9 +22,8 @@ final class Transaction implements TransactionInterface public function __construct( private ORMInterface $orm, - private ?RunnerInterface $runner = null - ) { - } + private ?RunnerInterface $runner = null, + ) {} public function persist(object $entity, int $mode = self::MODE_CASCADE): self { diff --git a/src/Transaction/CommandGenerator.php b/src/Transaction/CommandGenerator.php index 8cd00421..bb6ce7a0 100644 --- a/src/Transaction/CommandGenerator.php +++ b/src/Transaction/CommandGenerator.php @@ -32,7 +32,7 @@ public function generateStoreCommand(ORMInterface $orm, Tuple $tuple): ?CommandI return match (\count($commands)) { 0 => null, 1 => \current($commands), - default => $this->buildStoreSequence($schema, $commands, $tuple, $entityCommand) + default => $this->buildStoreSequence($schema, $commands, $tuple, $entityCommand), }; } @@ -50,7 +50,7 @@ protected function storeParents(ORMInterface $orm, Tuple $tuple, bool $isNew): a $schema = $orm->getSchema(); $parents = $commands = []; $parent = $schema->define($tuple->node->getRole(), SchemaInterface::PARENT); - while (is_string($parent)) { + while (\is_string($parent)) { \array_unshift($parents, $parent); $parent = $schema->define($parent, SchemaInterface::PARENT); } @@ -83,7 +83,7 @@ protected function generateParentStoreCommand( ORMInterface $orm, Tuple $tuple, string $parentRole, - bool $isNew + bool $isNew, ): ?CommandInterface { $parentMapper = $orm->getMapper($parentRole); return $isNew @@ -98,7 +98,7 @@ private function buildStoreSequence( SchemaInterface $schema, array $commands, Tuple $tuple, - ?CommandInterface $primaryCommand = null + ?CommandInterface $primaryCommand = null, ): CommandInterface { $parent = null; $result = []; @@ -113,15 +113,15 @@ private function buildStoreSequence( $command = WrappedStoreCommand::wrapStoreCommand($command); // Transact PK from previous parent to current - $parentKey = (array)($schema->define($role, SchemaInterface::PARENT_KEY) + $parentKey = (array) ($schema->define($role, SchemaInterface::PARENT_KEY) ?? $schema->define($parent, SchemaInterface::PRIMARY_KEY)); - $primaryKey = (array)$schema->define($role, SchemaInterface::PRIMARY_KEY); + $primaryKey = (array) $schema->define($role, SchemaInterface::PRIMARY_KEY); $result[] = $command->withBeforeExecution( static function (StoreCommandInterface $command) use ($tuple, $parentKey, $primaryKey): void { foreach ($primaryKey as $i => $pk) { $command->registerAppendix($pk, $tuple->state->getValue($parentKey[$i])); } - } + }, ); $parent = $role; } diff --git a/src/Transaction/Pool.php b/src/Transaction/Pool.php index 2d04dbe2..3f93d07f 100644 --- a/src/Transaction/Pool.php +++ b/src/Transaction/Pool.php @@ -10,7 +10,6 @@ use Cycle\ORM\ORMInterface; use Cycle\ORM\Reference\ReferenceInterface; use JetBrains\PhpStorm\ExpectedValues; -use Traversable; /** * @internal @@ -41,7 +40,7 @@ final class Pool implements \Countable private bool $iterating = false; public function __construct( - private ORMInterface $orm + private ORMInterface $orm, ) { $this->storage = new TupleStorage(); $this->all = new TupleStorage(); @@ -61,7 +60,7 @@ public function attach( ?State $state = null, ?int $status = null, bool $highPriority = false, - bool $persist = false + bool $persist = false, ): Tuple { // Find existing $tuple = $this->offsetGet($entity); @@ -84,39 +83,13 @@ public function attach( return $this->smartAttachTuple($tuple, $highPriority, $persist); } - private function smartAttachTuple(Tuple $tuple, bool $highPriority = false, bool $snap = false): Tuple - { - if ($tuple->status === Tuple::STATUS_PROCESSED) { - $this->all->attach($tuple); - return $tuple; - } - if ($tuple->status === Tuple::STATUS_PREPARING && $this->all->contains($tuple->entity)) { - return $this->all->getTuple($tuple->entity); - } - $this->all->attach($tuple); - - if ($this->iterating || $snap) { - $this->snap($tuple); - } - - if (isset($tuple->node) && $tuple->task === Tuple::TASK_DELETE) { - $tuple->state->setStatus(Node::SCHEDULED_DELETE); - } - if (($this->priorityAutoAttach || $highPriority) && $tuple->status === Tuple::STATUS_PREPARING) { - $this->priorityStorage->attach($tuple); - } else { - $this->storage->attach($tuple); - } - return $tuple; - } - public function attachStore( object $entity, bool $cascade, ?Node $node = null, ?State $state = null, bool $highPriority = false, - bool $persist = false + bool $persist = false, ): Tuple { return $this->attach($entity, Tuple::TASK_STORE, $cascade, $node, $state, null, $highPriority, $persist); } @@ -125,7 +98,7 @@ public function attachDelete( object $entity, bool $cascade, ?Node $node = null, - ?State $state = null + ?State $state = null, ): Tuple { return $this->attach($entity, Tuple::TASK_DELETE, $cascade, $node, $state); } @@ -138,9 +111,9 @@ public function offsetGet(object $entity): ?Tuple /** * Smart iterator * - * @return Traversable + * @return \Traversable */ - public function openIterator(): Traversable + public function openIterator(): \Traversable { if ($this->iterating) { throw new \RuntimeException('Iterator is already open.'); @@ -284,6 +257,32 @@ public function closeIterator(): void unset($this->priorityStorage, $this->unprocessed); } + private function smartAttachTuple(Tuple $tuple, bool $highPriority = false, bool $snap = false): Tuple + { + if ($tuple->status === Tuple::STATUS_PROCESSED) { + $this->all->attach($tuple); + return $tuple; + } + if ($tuple->status === Tuple::STATUS_PREPARING && $this->all->contains($tuple->entity)) { + return $this->all->getTuple($tuple->entity); + } + $this->all->attach($tuple); + + if ($this->iterating || $snap) { + $this->snap($tuple); + } + + if (isset($tuple->node) && $tuple->task === Tuple::TASK_DELETE) { + $tuple->state->setStatus(Node::SCHEDULED_DELETE); + } + if (($this->priorityAutoAttach || $highPriority) && $tuple->status === Tuple::STATUS_PREPARING) { + $this->priorityStorage->attach($tuple); + } else { + $this->storage->attach($tuple); + } + return $tuple; + } + /** * Make snapshot: create Node, State if not exists. Also attach Mapper */ diff --git a/src/Transaction/Runner.php b/src/Transaction/Runner.php index 2083f15e..46b909c4 100644 --- a/src/Transaction/Runner.php +++ b/src/Transaction/Runner.php @@ -10,7 +10,6 @@ use Cycle\ORM\Command\RollbackMethodInterface; use Cycle\ORM\Command\StoreCommandInterface; use Cycle\ORM\Exception\RunnerException; -use Traversable; final class Runner implements RunnerInterface { @@ -27,13 +26,39 @@ final class Runner implements RunnerInterface private int $countExecuted = 0; private function __construct( - private int $mode - ) { + private int $mode, + ) {} + + /** + * Create Runner in the 'inner transaction' mode. + * In this case the Runner will open new transaction for each used driver connection + * and will close they on finish. + */ + public static function innerTransaction(): self + { + return new self(self::MODE_OPEN_TRANSACTION); + } + + /** + * Create Runner in the 'outer transaction' mode. + * In this case the Runner won't begin transactions, you should do it previously manually. + * This mode also means the Runner WON'T commit or rollback opened transactions on success or fail. + * But commands that implement CompleteMethodInterface or RollbackMethodInterface will be called. + * + * @param bool $strict Check transaction statuses before commands running. + * When strict mode is {@see true} and a transaction of any used driver didn't be opened + * the Runner will throw an Exception and stop Unit of Work. + * When strict mode is {@see false} the Runner won't begin/commit/rollback transactions + * and will ignore any transaction statuses. + */ + public static function outerTransaction(bool $strict = true): self + { + return new self($strict ? self::MODE_CONTINUE_TRANSACTION : self::MODE_IGNORE_TRANSACTION); } public function run(CommandInterface $command): void { - if ($command instanceof Traversable) { + if ($command instanceof \Traversable) { foreach ($command as $cmd) { $this->run($cmd); } @@ -110,33 +135,6 @@ public function rollback(): void $this->drivers = $this->executed = []; } - /** - * Create Runner in the 'inner transaction' mode. - * In this case the Runner will open new transaction for each used driver connection - * and will close they on finish. - */ - public static function innerTransaction(): self - { - return new self(self::MODE_OPEN_TRANSACTION); - } - - /** - * Create Runner in the 'outer transaction' mode. - * In this case the Runner won't begin transactions, you should do it previously manually. - * This mode also means the Runner WON'T commit or rollback opened transactions on success or fail. - * But commands that implement CompleteMethodInterface or RollbackMethodInterface will be called. - * - * @param bool $strict Check transaction statuses before commands running. - * When strict mode is {@see true} and a transaction of any used driver didn't be opened - * the Runner will throw an Exception and stop Unit of Work. - * When strict mode is {@see false} the Runner won't begin/commit/rollback transactions - * and will ignore any transaction statuses. - */ - public static function outerTransaction(bool $strict = true): self - { - return new self($strict ? self::MODE_CONTINUE_TRANSACTION : self::MODE_IGNORE_TRANSACTION); - } - private function prepareTransaction(DriverInterface $driver): void { if ($this->mode === self::MODE_IGNORE_TRANSACTION) { @@ -147,7 +145,7 @@ private function prepareTransaction(DriverInterface $driver): void if ($driver->getTransactionLevel() === 0) { throw new RunnerException(\sprintf( 'The `%s` driver connection has no opened transaction.', - $driver->getType() + $driver->getType(), )); } return; diff --git a/src/Transaction/StateInterface.php b/src/Transaction/StateInterface.php index 22242948..749053c9 100644 --- a/src/Transaction/StateInterface.php +++ b/src/Transaction/StateInterface.php @@ -20,10 +20,8 @@ public function isSuccess(): bool; /** * The reason of failed transaction. - * - * @return Throwable|null */ - public function getLastError(): ?Throwable; + public function getLastError(): ?\Throwable; /** * Try to rerun transaction if previous run has been failed. diff --git a/src/Transaction/Tuple.php b/src/Transaction/Tuple.php index a96b0686..a60bad87 100644 --- a/src/Transaction/Tuple.php +++ b/src/Transaction/Tuple.php @@ -17,7 +17,6 @@ final class Tuple public const TASK_STORE = 0; public const TASK_DELETE = 1; public const TASK_FORCE_DELETE = 2; - public const STATUS_PREPARING = 0; public const STATUS_WAITING = 1; public const STATUS_WAITED = 2; @@ -30,6 +29,7 @@ final class Tuple public Node $node; public State $state; public MapperInterface $mapper; + /** * `Null` in case when Entity persisted not deferred. Else cloned State object. */ @@ -51,6 +51,5 @@ public function __construct( self::STATUS_UNPROCESSED, ])] public int $status, - ) { - } + ) {} } diff --git a/src/Transaction/TupleStorage.php b/src/Transaction/TupleStorage.php index f1ba1308..0d182949 100644 --- a/src/Transaction/TupleStorage.php +++ b/src/Transaction/TupleStorage.php @@ -4,7 +4,6 @@ namespace Cycle\ORM\Transaction; -use Countable; use IteratorAggregate; /** @@ -12,7 +11,7 @@ * * @implements IteratorAggregate */ -final class TupleStorage implements IteratorAggregate, Countable +final class TupleStorage implements \IteratorAggregate, \Countable { /** @var array */ private array $storage = []; @@ -26,7 +25,7 @@ public function getIterator(): \Traversable { $iterator = $this->storage; // When the generator is destroyed, the reference to the iterator is removed from the collection. - $cleaner = new class () { + $cleaner = new class { public array $iterators; public function __destruct() diff --git a/src/Transaction/UnitOfWork.php b/src/Transaction/UnitOfWork.php index 2582392e..1a04d922 100644 --- a/src/Transaction/UnitOfWork.php +++ b/src/Transaction/UnitOfWork.php @@ -22,7 +22,6 @@ final class UnitOfWork implements StateInterface private const RELATIONS_NOT_RESOLVED = 0; private const RELATIONS_RESOLVED = 1; private const RELATIONS_DEFERRED = 2; - private const STAGE_PREPARING = 0; private const STAGE_PROCESS = 1; private const STAGE_FINISHED = 2; @@ -34,7 +33,7 @@ final class UnitOfWork implements StateInterface public function __construct( private ORMInterface $orm, - private ?RunnerInterface $runner = null + private ?RunnerInterface $runner = null, ) { $this->pool = new Pool($orm); $this->commandGenerator = $orm->getCommandGenerator(); @@ -83,7 +82,7 @@ public function run(): StateInterface { $this->stage = match ($this->stage) { self::STAGE_FINISHED => throw new SuccessTransactionRetryException( - 'A successful transaction cannot be re-run.' + 'A successful transaction cannot be re-run.', ), self::STAGE_PROCESS => throw new TransactionException('Can\'t run started transaction.'), default => self::STAGE_PROCESS, @@ -177,7 +176,7 @@ private function syncHeap(): void $syncData = \array_udiff_assoc( $tuple->state->getData(), $tuple->persist->getData(), - [Node::class, 'compare'] + [Node::class, 'compare'], ); } else { $syncData = $node->syncState($relationProvider->getRelationMap($role), $tuple->state); @@ -344,7 +343,7 @@ private function resolveSelfWithEmbedded(Tuple $tuple, RelationMap $map, bool $h $relation->queue( $this->pool, $tuple, - $command instanceof Sequence ? $command->getPrimaryCommand() : $command + $command instanceof Sequence ? $command->getPrimaryCommand() : $command, ); } $this->runCommand($command); @@ -361,8 +360,8 @@ private function resolveRelations(Tuple $tuple): void $result = $tuple->task === Tuple::TASK_STORE ? $this->resolveMasterRelations($tuple, $map) : $this->resolveSlaveRelations($tuple, $map); - $isDependenciesResolved = (bool)($result & self::RELATIONS_RESOLVED); - $deferred = (bool)($result & self::RELATIONS_DEFERRED); + $isDependenciesResolved = (bool) ($result & self::RELATIONS_RESOLVED); + $deferred = (bool) ($result & self::RELATIONS_DEFERRED); // Self if ($deferred && $tuple->status < Tuple::STATUS_PROPOSED) { From 1dad933462466f9c02b1c7381d8e002397a670f3 Mon Sep 17 00:00:00 2001 From: roxblnfk Date: Tue, 10 Dec 2024 15:03:37 +0400 Subject: [PATCH 4/6] Reuse common CI; add PHP 8.4 --- .github/workflows/ci-mssql.yml | 88 +++------------------------- .github/workflows/ci-mysql.yml | 101 +++------------------------------ .github/workflows/ci-pgsql.yml | 99 +++----------------------------- .github/workflows/main.yml | 2 + tests/bootstrap.php | 6 +- tests/docker-compose.yml | 6 +- 6 files changed, 35 insertions(+), 267 deletions(-) diff --git a/.github/workflows/ci-mssql.yml b/.github/workflows/ci-mssql.yml index 462e1304..2f5f2eaa 100644 --- a/.github/workflows/ci-mssql.yml +++ b/.github/workflows/ci-mssql.yml @@ -1,86 +1,16 @@ -on: +--- + +on: # yamllint disable-line rule:truthy push: branches: - - '2.*' + - '*.*' + - '*.*.*' pull_request: null -name: ci-mssql +name: MSSQL jobs: - tests: - name: PHP ${{ matrix.php }}-mssql-${{ matrix.mssql }} - - env: - key: cache - - runs-on: ubuntu-latest - - strategy: - fail-fast: false - matrix: - include: - - php: '8.0' - extensions: pdo, pdo_sqlsrv - mssql: 'server:2017-latest' - - php: '8.0' - extensions: pdo, pdo_sqlsrv - mssql: 'server:2019-CU25-ubuntu-20.04' - - php: '8.1' - extensions: pdo, pdo_sqlsrv - mssql: 'server:2019-CU25-ubuntu-20.04' - - php: '8.2' - extensions: pdo, pdo_sqlsrv - mssql: 'server:2019-CU25-ubuntu-20.04' - - php: '8.3' - extensions: pdo, pdo_sqlsrv - mssql: 'server:2019-CU25-ubuntu-20.04' - - services: - mssql: - image: mcr.microsoft.com/mssql/${{ matrix.mssql }} - env: - SA_PASSWORD: SSpaSS__1 - ACCEPT_EULA: Y - MSSQL_PID: Developer - ports: - - 11433:1433 - options: --name=mssql --health-cmd="/opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P 'SSpaSS__1' -Q 'SELECT 1'" --health-interval=10s --health-timeout=5s --health-retries=3 - - steps: - - name: Checkout - uses: actions/checkout@v2.3.4 - - - name: Install PHP with extensions - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php }} - extensions: ${{ matrix.extensions }} - ini-values: date.timezone='UTC' - tools: composer:v2, pecl - - - name: Determine composer cache directory on Linux - run: echo "COMPOSER_CACHE_DIR=$(composer config cache-dir)" >> $GITHUB_ENV - - - name: Cache dependencies installed with composer - uses: actions/cache@v2 - with: - path: ${{ env.COMPOSER_CACHE_DIR }} - key: php${{ matrix.php }}-composer-${{ hashFiles('**/composer.json') }} - restore-keys: | - php${{ matrix.php }}-composer- - - - name: Update composer - run: composer self-update - - - name: Install dependencies with composer - if: matrix.php != '8.4' - run: composer update --prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi - - - name: Install dependencies with composer php 8.4 - if: matrix.php == '8.4' - run: composer update --ignore-platform-reqs --prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi + phpunit: + uses: cycle/gh-actions/.github/workflows/db-mssql.yml@master - - name: Run tests with phpunit without coverage - env: - DB: sqlserver - run: vendor/bin/phpunit --group driver-sqlserver --colors=always +... diff --git a/.github/workflows/ci-mysql.yml b/.github/workflows/ci-mysql.yml index b88e39ac..c0ccde1d 100644 --- a/.github/workflows/ci-mysql.yml +++ b/.github/workflows/ci-mysql.yml @@ -1,99 +1,16 @@ -on: +--- + +on: # yamllint disable-line rule:truthy push: branches: - - '2.*' + - '*.*' + - '*.*.*' pull_request: null -name: ci-mysql +name: MySQL jobs: - tests: - name: PHP ${{ matrix.php-version }}-mysql-${{ matrix.mysql-version }} - env: - extensions: curl, intl, pdo, pdo_mysql - key: cache-v1 - - runs-on: ${{ matrix.os }} - - strategy: - fail-fast: false - matrix: - os: - - ubuntu-latest - - php-version: - - "8.0" - - "8.1" - - "8.2" - - "8.3" - - mysql-version: - - "5.7" - - "8.0" - - services: - mysql: - image: mysql:${{ matrix.mysql-version }} - env: - MYSQL_ROOT_PASSWORD: root - MYSQL_DATABASE: spiral - MYSQL_AUTHENTICATION_PLUGIN: mysql_native_password - ports: - - 13306:3306 - options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 - - steps: - - name: Show databases for root user - run: mysql --protocol=tcp -h localhost -P 13306 -u root -proot -e "ALTER DATABASE spiral CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" - - - name: Checkout - uses: actions/checkout@v2 - - - name: Setup cache environment - id: cache-env - uses: shivammathur/cache-extensions@v1 - with: - php-version: ${{ matrix.php-version }} - extensions: ${{ env.extensions }} - key: ${{ env.key }} - - - name: Cache extensions - uses: actions/cache@v2 - with: - path: ${{ steps.cache-env.outputs.dir }} - key: ${{ steps.cache-env.outputs.key }} - restore-keys: ${{ steps.cache-env.outputs.key }} - - - name: Install PHP with extensions - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php-version }} - extensions: ${{ env.extensions }} - ini-values: date.timezone='UTC' - coverage: pcov - - - name: Determine composer cache directory - if: matrix.os == 'ubuntu-latest' - run: echo "COMPOSER_CACHE_DIR=$(composer config cache-dir)" >> $GITHUB_ENV - - - name: Cache dependencies installed with composer - uses: actions/cache@v2 - with: - path: ${{ env.COMPOSER_CACHE_DIR }} - key: php${{ matrix.php-version }}-composer-${{ matrix.dependencies }}-${{ hashFiles('**/composer.json') }} - restore-keys: | - php${{ matrix.php-version }}-composer-${{ matrix.dependencies }}- - - - name: Install dependencies with composer - if: matrix.php-version != '8.4' - run: composer update --prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi - - - name: Install dependencies with composer php 8.4 - if: matrix.php-version == '8.4' - run: composer update --ignore-platform-reqs --prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi + phpunit: + uses: cycle/gh-actions/.github/workflows/db-mysql.yml@master - - name: Run mysql tests with phpunit - env: - DB: mysql - MYSQL: ${{ matrix.mysql-version }} - run: vendor/bin/phpunit --group driver-mysql --colors=always +... diff --git a/.github/workflows/ci-pgsql.yml b/.github/workflows/ci-pgsql.yml index 456fe83f..2b3f8e71 100644 --- a/.github/workflows/ci-pgsql.yml +++ b/.github/workflows/ci-pgsql.yml @@ -1,97 +1,16 @@ -on: +--- + +on: # yamllint disable-line rule:truthy push: branches: - - '2.*' + - '*.*' + - '*.*.*' pull_request: null -name: ci-pgsql +name: Postgres jobs: - tests: - name: PHP ${{ matrix.php-version }}-pgsql-${{ matrix.pgsql-version }} - env: - extensions: curl, intl, pdo, pdo_pgsql - key: cache-v1 - - runs-on: ${{ matrix.os }} - - strategy: - fail-fast: false - matrix: - os: - - ubuntu-latest - php-version: - - "8.0" - - "8.1" - - "8.2" - - "8.3" - - pgsql-version: - - "10" - - "11" - - "12" - - "13" - - services: - postgres: - image: postgres:${{ matrix.pgsql-version }} - env: - POSTGRES_USER: postgres - POSTGRES_PASSWORD: postgres - POSTGRES_DB: spiral - ports: - - 15432:5432 - options: --name=postgres --health-cmd="pg_isready" --health-interval=10s --health-timeout=5s --health-retries=3 - - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Setup cache environment - id: cache-env - uses: shivammathur/cache-extensions@v1 - with: - php-version: ${{ matrix.php-version }} - extensions: ${{ env.extensions }} - key: ${{ env.key }} - - - name: Cache extensions - uses: actions/cache@v2 - with: - path: ${{ steps.cache-env.outputs.dir }} - key: ${{ steps.cache-env.outputs.key }} - restore-keys: ${{ steps.cache-env.outputs.key }} - - - name: Install PHP with extensions - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php-version }} - extensions: ${{ env.extensions }} - ini-values: date.timezone='UTC' - coverage: pcov - - - name: Determine composer cache directory - if: matrix.os == 'ubuntu-latest' - run: echo "COMPOSER_CACHE_DIR=$(composer config cache-dir)" >> $GITHUB_ENV - - - name: Cache dependencies installed with composer - uses: actions/cache@v2 - with: - path: ${{ env.COMPOSER_CACHE_DIR }} - key: php${{ matrix.php-version }}-composer-${{ matrix.dependencies }}-${{ hashFiles('**/composer.json') }} - restore-keys: | - php${{ matrix.php-version }}-composer-${{ matrix.dependencies }}- - - - name: Install dependencies with composer - if: matrix.php-version != '8.4' - run: composer update --prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi - - - name: Install dependencies with composer php 8.4 - if: matrix.php-version == '8.4' - run: composer update --ignore-platform-reqs --prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi + phpunit: + uses: cycle/gh-actions/.github/workflows/db-pgsql.yml@master - - name: Run pgsql tests with phpunit - env: - DB: postgres - POSTGRES: ${{ matrix.pgsql-version }} - run: vendor/bin/phpunit --group driver-postgres --colors=always +... diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 5ed5e346..f9a673d5 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -22,6 +22,7 @@ jobs: - "8.1" - "8.2" - "8.3" + - "8.4" steps: - name: Checkout uses: actions/checkout@v2 @@ -81,6 +82,7 @@ jobs: - "8.1" - "8.2" - "8.3" + - "8.4" steps: - name: Checkout uses: actions/checkout@v2 diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 34996a9e..82810de5 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -24,7 +24,7 @@ port: 13306, charset: 'utf8mb4', user: 'root', - password: 'root', + password: 'YourStrong!Passw0rd', ), queryCache: true, options: [ @@ -37,7 +37,7 @@ host: '127.0.0.1', port: 15432, user: 'postgres', - password: 'postgres', + password: 'YourStrong!Passw0rd', ), schema: 'public', queryCache: true, @@ -49,7 +49,7 @@ connection: new Config\SQLServer\DsnConnectionConfig( 'sqlsrv:Server=127.0.0.1,11433;Database=tempdb;TrustServerCertificate=true', user: 'SA', - password: 'SSpaSS__1' + password: 'YourStrong!Passw0rd' ), queryCache: true, options: [ diff --git a/tests/docker-compose.yml b/tests/docker-compose.yml index 444b5be5..3dccd689 100644 --- a/tests/docker-compose.yml +++ b/tests/docker-compose.yml @@ -6,7 +6,7 @@ services: ports: - "11433:1433" environment: - SA_PASSWORD: "SSpaSS__1" + SA_PASSWORD: "YourStrong!Passw0rd" ACCEPT_EULA: "Y" cycle-mysql_latest: @@ -20,7 +20,7 @@ services: - "13306:3306" environment: MYSQL_DATABASE: "spiral" - MYSQL_ROOT_PASSWORD: "root" + MYSQL_ROOT_PASSWORD: "YourStrong!Passw0rd" MYSQL_ROOT_HOST: "%" cycle-postgres: @@ -31,4 +31,4 @@ services: environment: POSTGRES_DB: "spiral" POSTGRES_USER: "postgres" - POSTGRES_PASSWORD: "postgres" + POSTGRES_PASSWORD: "YourStrong!Passw0rd" From ccf28faa0115071fcf5aebb6a8e3ac1add68a3a0 Mon Sep 17 00:00:00 2001 From: roxblnfk Date: Tue, 10 Dec 2024 15:10:52 +0400 Subject: [PATCH 5/6] Expand the range of `illuminate/collections` versions --- .gitignore | 3 ++- composer.json | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index b7032e0d..f8b0475a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ -/.idea/ +/.* +!/.github/ /runtime/ /vendor/ .env diff --git a/composer.json b/composer.json index ea206d85..4d97909f 100644 --- a/composer.json +++ b/composer.json @@ -46,7 +46,7 @@ }, "require-dev": { "doctrine/collections": "^1.6 || ^2.0", - "illuminate/collections": "^8.0", + "illuminate/collections": "9 - 11", "loophp/collection": "^6.0 || ^7.0", "mockery/mockery": "^1.1", "phpunit/phpunit": "^9.5", From a6f46a3e9a61653192ee50b7a09243ee81dc3e98 Mon Sep 17 00:00:00 2001 From: roxblnfk Date: Thu, 12 Dec 2024 13:03:56 +0400 Subject: [PATCH 6/6] Apply code style to tests files --- .php-cs-fixer.dist.php | 3 +- src/Select/RootLoader.php | 1 - tests/ORM/Fixtures/Comment.php | 3 - tests/ORM/Fixtures/CompositePK.php | 3 - tests/ORM/Fixtures/CompositePKChild.php | 2 - tests/ORM/Fixtures/CompositePKNested.php | 2 - tests/ORM/Fixtures/CompositePKPivot.php | 3 - tests/ORM/Fixtures/CustomCollection.php | 4 +- tests/ORM/Fixtures/CyclicRef/Comment.php | 1 - .../Fixtures/CyclicRef/TimestampedMapper.php | 5 +- tests/ORM/Fixtures/CyclicRef/User.php | 1 - tests/ORM/Fixtures/CyclicRef2/Document.php | 4 - tests/ORM/Fixtures/CyclicRef2/Preference.php | 2 - tests/ORM/Fixtures/DifferentSource.php | 12 - tests/ORM/Fixtures/Enum/TypeIntEnum.php | 2 +- tests/ORM/Fixtures/Enum/TypeStringEnum.php | 2 +- tests/ORM/Fixtures/Favorite.php | 4 +- tests/ORM/Fixtures/Group.php | 1 - tests/ORM/Fixtures/Image.php | 1 - tests/ORM/Fixtures/ImagedInterface.php | 4 +- tests/ORM/Fixtures/OptimisticLockMapper.php | 2 +- tests/ORM/Fixtures/Post.php | 1 - tests/ORM/Fixtures/Tag.php | 2 - tests/ORM/Fixtures/TestInsertCommand.php | 4 +- .../TestInsertCommandWithReturning.php | 4 +- tests/ORM/Fixtures/TestLogger.php | 1 - tests/ORM/Fixtures/TimestampedMapper.php | 5 +- tests/ORM/Fixtures/TransactionTestMapper.php | 6 +- tests/ORM/Fixtures/User.php | 2 - tests/ORM/Fixtures/UserCredentials.php | 1 - tests/ORM/Fixtures/UserPersistRepository.php | 8 +- tests/ORM/Fixtures/UserRepository.php | 5 - tests/ORM/Fixtures/UserSnapshotMapper.php | 2 +- tests/ORM/Fixtures/UserWithUUIDPrimaryKey.php | 2 +- tests/ORM/Fixtures/Uuid.php | 45 +-- tests/ORM/Fixtures/UuidPrimaryKey.php | 8 +- .../ORM/Functional/Driver/Common/BaseTest.php | 141 ++++---- .../BenchmarkClasslessDoubleLinkedTest.php | 100 +++--- .../Benchmark/BenchmarkDoubleLinkedTest.php | 102 +++--- .../ClasslessCyclicReferencesTest.php | 266 +++++++-------- .../Classless/ClasslessHasManyPromiseTest.php | 136 ++++---- .../Classless/ClasslessHasOneCyclicTest.php | 88 ++--- .../ClasslessInverseRelationTest.php | 158 ++++----- .../Driver/Common/Classless/StdMapperTest.php | 64 ++-- .../EntityManager/EntityManagerTest.php | 64 ++-- .../Driver/Common/Enum/EnumTest.php | 80 ++--- .../Functional/Driver/Common/FactoryTest.php | 42 +-- .../Driver/Common/GeneratedColumnTest.php | 91 +++-- .../Common/Inheritance/Fixture/EBook.php | 1 + .../Common/Inheritance/Fixture/Employee.php | 2 - .../Common/Inheritance/Fixture/Engineer.php | 1 - .../Common/Inheritance/Fixture/HtmlPage.php | 4 +- .../Common/Inheritance/Fixture/Manager.php | 1 - .../Fixture/ManagerWithCredentials.php | 1 - .../Inheritance/Fixture/MarkdownPage.php | 4 +- .../Inheritance/Fixture/Programator.php | 1 - .../Inheritance/Fixture/RbacItemAbstract.php | 2 +- .../Inheritance/Fixture/RbacPermission.php | 4 +- .../Common/Inheritance/Fixture/RbacRole.php | 4 +- .../Inheritance/JTI/CompositePKTest.php | 229 ++++++------- .../Common/Inheritance/JTI/JtiBaseTest.php | 2 +- .../JTI/Relation/EmbeddedRelationsTest.php | 77 +++-- .../JTI/Relation/HierarchyInRelationTest.php | 312 +++++++++--------- .../JTI/Relation/ParentClassRelationsTest.php | 118 +++---- .../Inheritance/JTI/SimpleCasesTest.php | 128 +++---- .../Inheritance/JTI/SingleTableTest.php | 115 +++---- .../Common/Inheritance/STI/ManyToManyTest.php | 47 ++- .../Common/Inheritance/STI/SimpleTest.php | 41 +-- .../Common/Inheritance/STI/StiBaseTest.php | 2 +- .../Driver/Common/InstantiatorTest.php | 42 +-- .../Common/Integration/Case1/CaseTest.php | 73 ++-- .../Integration/Case1/Entity/Comment.php | 26 +- .../Common/Integration/Case1/Entity/Post.php | 27 +- .../Common/Integration/Case1/Entity/Tag.php | 9 +- .../Common/Integration/Case1/Entity/User.php | 16 +- .../Common/Integration/Case2/CaseTest.php | 64 ++-- .../Case2/Entity/MarkAspectResult.php | 4 +- .../Case2/Entity/MarkCriterionResult.php | 1 - .../Case2/Entity/MarkSubcriterionResult.php | 1 - .../Case2/Entity/StudentProgress.php | 3 +- .../Common/Integration/Case3/CaseTest.php | 20 +- .../Integration/Case3/Entity/Currency.php | 5 +- .../Common/Integration/Case318/CaseTest.php | 18 +- .../Integration/Case318/Entity/UserGroup.php | 1 - .../Common/Integration/Case318/Typecast.php | 4 +- .../Common/Integration/Case321/CaseTest.php | 18 +- .../Common/Integration/Case346/CaseTest.php | 20 +- .../Integration/Case346/Entity/Post.php | 14 +- .../Integration/Case346/Entity/User.php | 11 +- .../Common/Integration/Case383/CaseTest.php | 42 +-- .../Integration/Case383/Entity/Comment.php | 14 +- .../Integration/Case383/Entity/Post.php | 17 +- .../Common/Integration/Case383/Entity/Tag.php | 7 +- .../Integration/Case383/Entity/User.php | 12 +- .../Common/Integration/Case398/CaseTest.php | 18 +- .../Case398/Entity/FilterProduct.php | 3 +- .../Integration/Case398/Entity/Product.php | 3 +- .../Common/Integration/Case4/CaseTest.php | 30 +- .../Common/Integration/Case4/Entity/Node.php | 2 - .../Common/Integration/Case408/CaseTest.php | 20 +- .../Case408/Entity/TargetGroup.php | 1 - .../Integration/Case408/Type/IntegerTrait.php | 3 +- .../Integration/Case408/Type/StringTrait.php | 3 +- .../Case408/Type/ValueObjectInterface.php | 4 +- .../Common/Integration/Case416/CaseTest.php | 20 +- .../Integration/Case416/Entity/Account.php | 4 +- .../Integration/Case416/Entity/Identity.php | 11 +- .../Integration/Case416/Entity/Profile.php | 4 +- .../Integration/Case416/Entity/UserName.php | 4 +- .../Common/Integration/Case427/CaseTest.php | 48 +-- .../Integration/Case427/Entity/Buyer.php | 3 +- .../Integration/Case427/UuidTypecast.php | 2 +- .../Common/Integration/Case5/CaseTest.php | 36 +- .../Common/Integration/Case5/Entity/Badge.php | 3 +- .../Integration/CaseTemplate/CaseTest.php | 20 +- .../CaseTemplate/Entity/Comment.php | 14 +- .../Integration/CaseTemplate/Entity/Post.php | 17 +- .../Integration/CaseTemplate/Entity/Tag.php | 7 +- .../Integration/CaseTemplate/Entity/User.php | 12 +- .../Common/Integration/Issue322/CaseTest.php | 20 +- .../Integration/Issue322/Entity/Comment.php | 14 +- .../Integration/Issue322/Entity/Post.php | 16 +- .../Integration/Issue322/Entity/Tag.php | 7 +- .../Integration/Issue322/Entity/User.php | 12 +- .../Common/Integration/Issue380/CaseTest.php | 44 +-- .../Integration/Issue380/Entity/User.php | 2 - .../Issue380/Entity/User/Alias.php | 2 - .../Issue380/Entity/User/Email.php | 2 - .../Issue380/Entity/User/Phone.php | 2 - .../Common/Integration/Issue422/CaseTest.php | 20 +- .../Integration/Issue422/Entity/Billing.php | 1 - .../Issue422/Entity/SomeEmbedded.php | 1 - .../Integration/Issue482/AbstractTestCase.php | 36 +- .../Common/Mapper/AutoTimestampsTest.php | 78 ++--- .../Driver/Common/Mapper/BaseMapperTest.php | 4 +- .../ClasslessMapper/ClasslessMapperTest.php | 82 ++--- .../Driver/Common/Mapper/MapperTest.php | 186 +++++------ .../ProxyEntityMapper/EntityHydrationTest.php | 108 +++--- .../EntityWithRelationCreationTest.php | 39 ++- .../EntityWithRelationHydrationTest.php | 289 ++++++++-------- .../Hydrator/ClassPropertiesExtractorTest.php | 14 +- .../Hydrator/PropertyMapTest.php | 40 +-- .../Driver/Common/Mapper/SoftDeletesTest.php | 62 ++-- .../Driver/Common/Mapper/UUIDTest.php | 154 ++++----- .../Driver/Common/ORM/MemoryTest.php | 20 +- .../Functional/Driver/Common/ORM/ORMTest.php | 46 +-- .../BelongsTo/BelongsToCompositeKeyTest.php | 192 +++++------ .../BelongsToProxyMapperRenamedFieldsTest.php | 6 +- .../BelongsTo/BelongsToProxyMapperTest.php | 168 +++++----- .../BelongsToRelationRenamedFieldsTest.php | 6 +- .../BelongsTo/BelongsToRelationTest.php | 116 +++---- .../BelongsToRelationWithNestedUuidTest.php | 42 +-- .../BelongsTo/BelongsToWithHasOneTest.php | 256 +++++++------- .../Common/Relation/BidirectionTest.php | 164 ++++----- .../Common/Relation/CyclicReferencesTest.php | 274 +++++++-------- .../Driver/Common/Relation/DeepCyclicTest.php | 92 +++--- .../Common/Relation/DoubleLinkedTest.php | 96 +++--- .../Driver/Common/Relation/Eager2Test.php | 74 ++--- .../Driver/Common/Relation/EagerTest.php | 64 ++-- .../Relation/Embedded/DeepEmbeddedTest.php | 218 ++++++------ .../Embedded/EmbeddedCompositeKeyTest.php | 98 +++--- .../Relation/Embedded/EmbeddedLoaderTest.php | 188 +++++------ .../Embedded/EmbeddedRelationTest.php | 114 +++---- .../Relation/ExistingNestedRelationTest.php | 66 ++-- .../Cyclic/CyclicHasManyReferencesTest.php | 188 +++++------ ...icHasManyReferencesWithCompositePKTest.php | 48 +-- .../HasMany/HasManyCollectionsTest.php | 102 +++--- .../HasMany/HasManyCompositeKeyTest.php | 163 +++++---- .../Relation/HasMany/HasManyLoadingTest.php | 138 ++++---- .../HasMany/HasManyNestedConditionTest.php | 234 ++++++------- .../HasMany/HasManyProxyMapperTest.php | 142 ++++---- .../Relation/HasMany/HasManyRelationTest.php | 140 ++++---- .../Relation/HasMany/HasManyScopeTest.php | 82 ++--- .../Relation/HasMany/HasManySourceTest.php | 144 ++++---- .../HasOne/HasOneCompositeKeyTest.php | 236 ++++++------- .../Relation/HasOne/HasOneCyclicTest.php | 90 ++--- .../Relation/HasOne/HasOneProxyMapperTest.php | 208 ++++++------ .../Relation/HasOne/HasOneRelationTest.php | 218 ++++++------ .../Common/Relation/InverseRelationTest.php | 162 ++++----- .../Driver/Common/Relation/LinkedTreeTest.php | 154 ++++----- .../Cyclic/CyclicManyToManyTest.php | 272 +++++++-------- .../Cyclic/CyclicManyToManyTypedTest.php | 40 +-- .../CyclingManyToManyWithTimestampsTest.php | 86 ++--- .../ManyToMany/ManyToManyBelongsToTest.php | 144 ++++---- .../ManyToMany/ManyToManyCompositeKeyTest.php | 307 ++++++++--------- .../ManyToMany/ManyToManyDeepenedTest.php | 136 ++++---- .../ManyToMany/ManyToManyLoadingTest.php | 238 ++++++------- .../ManyToMany/ManyToManyLoophpPivotTest.php | 30 +- .../ManyToManyNonPivotedCollectionTest.php | 116 +++---- .../ManyToManyPromiseEagerLoadTest.php | 294 ++++++++--------- .../ManyToMany/ManyToManyPromiseTest.php | 208 ++++++------ .../ManyToMany/ManyToManyRelationTest.php | 112 +++---- .../ManyToMany/ManyToManyScopeTest.php | 124 +++---- .../ManyToMany/ManyToManyScopedPivotTest.php | 132 ++++---- .../ManyToMany/ManyToManyScopedTest.php | 124 +++---- .../Morphed/BelongsToMorphedRelationTest.php | 112 +++---- .../Morphed/MorphedHasManyPromiseTest.php | 246 +++++++------- .../Morphed/MorphedHasManyRelationTest.php | 242 +++++++------- .../Morphed/MorphedHasManyScopeTest.php | 128 +++---- .../Morphed/MorphedHasOnePromiseTest.php | 112 +++---- .../Morphed/MorphedHasOneRelationTest.php | 116 +++---- .../Common/Relation/NestedEagerTest.php | 186 +++++------ .../RefersToProxyMapperRenamedFieldTest.php | 6 +- .../RefersTo/RefersToProxyMapperTest.php | 164 ++++----- .../RefersToRelationCompositeKeyTest.php | 78 +++-- .../RefersToRelationMiniRowsetTest.php | 96 +++--- .../RefersTo/RefersToRelationTest.php | 46 +-- .../Relation/RelationWithColumnAliasTest.php | 150 ++++----- .../Driver/Common/RenamedPKTest.php | 4 +- .../Schema/Column/ColumnAliasesTest.php | 64 ++-- .../Driver/Common/Schema/Column/UUIDTest.php | 58 ++-- .../Driver/Common/Schema/CommonTest.php | 124 +++---- .../Driver/Common/Schema/CompositePKTest.php | 2 +- .../Driver/Common/Schema/FollowupTest.php | 78 ++--- .../Common/Schema/TableRendererTest.php | 25 +- .../Common/Select/CustomRepositoryTest.php | 66 ++-- .../Driver/Common/Select/JsonMethodsTest.php | 98 +++--- .../Driver/Common/Select/PaginateTest.php | 32 +- .../Common/Select/PersistRepositoryTest.php | 36 +- .../Driver/Common/Select/QueryBuilderTest.php | 158 ++++----- .../Driver/Common/Select/RepositoryTest.php | 64 ++-- .../Functional/Driver/Common/SelectorTest.php | 80 ++--- .../Common/Transaction/OptimisticLockTest.php | 50 +-- .../Driver/Common/Transaction/RunnerTest.php | 10 +- .../Common/Transaction/UnitOfWorkTest.php | 50 +-- .../Driver/Common/TransactionTest.php | 64 ++-- .../Driver/Common/Typecast/DatetimeTest.php | 85 +++-- .../Driver/Common/Typecast/Fixture/Book.php | 12 +- .../Typecast/Fixture/BookNestedStates.php | 8 +- .../Common/Typecast/Fixture/BookStates.php | 8 +- .../Typecast/Fixture/InvalidTypecaster.php | 4 +- .../Common/Typecast/Fixture/JsonTypecast.php | 2 +- .../Common/Typecast/Fixture/Typecaster.php | 2 +- .../Driver/Common/Typecast/Fixture/User.php | 4 +- .../Common/Typecast/Fixture/Wrapper.php | 7 +- .../Driver/Common/Typecast/JsonTest.php | 133 ++++---- .../Common/Typecast/ObjectsCompareTest.php | 70 ++-- .../Driver/Common/Typecast/SchemaTest.php | 18 +- .../Common/Typecast/TypecastEnumTest.php | 94 +++--- .../Driver/Common/Typecast/TypecastTest.php | 208 ++++++------ .../Typecast/TypecastWithLinkedDataTest.php | 120 +++---- .../Driver/Common/Typecast/UUIDTest.php | 76 ++--- .../Driver/Postgres/GeneratedColumnTest.php | 2 +- .../Driver/SQLServer/GeneratedColumnTest.php | 2 +- tests/ORM/Traits/TableTrait.php | 16 +- .../Collection/ArrayCollectionFactoryTest.php | 1 + tests/ORM/Unit/Collection/BaseTest.php | 28 +- .../DoctrineCollectionFactoryTest.php | 9 +- .../IlluminateCollectionFactoryTest.php | 6 +- .../LoophpCollectionFactoryTest.php | 10 +- tests/ORM/Unit/Command/DeleteCommandTest.php | 2 +- tests/ORM/Unit/Command/Helper/TestInsert.php | 11 +- tests/ORM/Unit/Command/InsertCommandTest.php | 34 +- tests/ORM/Unit/Command/UpdateCommandTest.php | 32 +- tests/ORM/Unit/Heap/HeapCompositeKeysTest.php | 79 ++--- tests/ORM/Unit/Heap/HeapTest.php | 2 +- tests/ORM/Unit/Heap/NodeComparisonTest.php | 40 +-- tests/ORM/Unit/Heap/NullHeapTest.php | 2 +- .../Mapper/Proxy/ProxyEntityFactoryTest.php | 38 +-- tests/ORM/Unit/OrmTest.php | 4 +- .../ORM/Unit/Parser/CompositeTypecastTest.php | 9 +- tests/ORM/Unit/Parser/TypecastTest.php | 23 +- tests/ORM/Unit/Select/Traits/ColumnsTrait.php | 2 +- tests/ORM/Unit/Transaction/PoolTest.php | 3 +- .../ORM/Unit/Transaction/TupleStorageTest.php | 24 +- tests/ORM/Util/DontGenerateAttribute.php | 8 +- tests/ORM/Util/SimpleFactory.php | 6 +- tests/ORM/Util/TableRenderer.php | 29 +- tests/bootstrap.php | 6 +- tests/generate-case.php | 14 +- tests/generate.php | 8 +- 271 files changed, 7692 insertions(+), 8048 deletions(-) diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index 328c5b0d..45745a12 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -6,7 +6,8 @@ return \Spiral\CodeStyle\Builder::create() ->include(__DIR__ . '/src') + ->include(__DIR__ . '/tests') ->include(__FILE__) ->cache('./runtime/php-cs-fixer.cache') - ->allowRisky() + ->allowRisky(false) ->build(); diff --git a/src/Select/RootLoader.php b/src/Select/RootLoader.php index e0dddb42..687e2c33 100644 --- a/src/Select/RootLoader.php +++ b/src/Select/RootLoader.php @@ -33,7 +33,6 @@ final class RootLoader extends AbstractLoader 'load' => true, 'scope' => true, ]; - private SelectQuery $query; /** diff --git a/tests/ORM/Fixtures/Comment.php b/tests/ORM/Fixtures/Comment.php index 1fc83e45..4454cf23 100644 --- a/tests/ORM/Fixtures/Comment.php +++ b/tests/ORM/Fixtures/Comment.php @@ -11,7 +11,6 @@ class Comment { public $id; - public $message; /** @var User */ @@ -21,9 +20,7 @@ class Comment public $favoredBy; public $parent; - public $level; - public UserWithUUIDPrimaryKey $userWithUuid; public function __construct() diff --git a/tests/ORM/Fixtures/CompositePK.php b/tests/ORM/Fixtures/CompositePK.php index ee1dade4..0ac9b4c2 100644 --- a/tests/ORM/Fixtures/CompositePK.php +++ b/tests/ORM/Fixtures/CompositePK.php @@ -14,14 +14,11 @@ class CompositePK public $key2; public $key3; public $key4; - public $child_entity; - public $child_key1; public $child_key2; public $child_key3; public $child_key4; - public $children; public $pivoted; diff --git a/tests/ORM/Fixtures/CompositePKChild.php b/tests/ORM/Fixtures/CompositePKChild.php index a7a95637..d119ba4f 100644 --- a/tests/ORM/Fixtures/CompositePKChild.php +++ b/tests/ORM/Fixtures/CompositePKChild.php @@ -13,12 +13,10 @@ class CompositePKChild public $key2; public $key3; public $key4; - public $parent_key1; public $parent_key2; public $parent_key3; public $parent_key4; - public $parent; public $nested; public $pivoted; diff --git a/tests/ORM/Fixtures/CompositePKNested.php b/tests/ORM/Fixtures/CompositePKNested.php index c5d2c54c..1362049e 100644 --- a/tests/ORM/Fixtures/CompositePKNested.php +++ b/tests/ORM/Fixtures/CompositePKNested.php @@ -11,11 +11,9 @@ class CompositePKNested public $key2; public $key3; public $key4; - public $parent_key1; public $parent_key2; public $parent_key3; public $parent_key4; - public $parent; } diff --git a/tests/ORM/Fixtures/CompositePKPivot.php b/tests/ORM/Fixtures/CompositePKPivot.php index 0e9adc92..f2a419ac 100644 --- a/tests/ORM/Fixtures/CompositePKPivot.php +++ b/tests/ORM/Fixtures/CompositePKPivot.php @@ -11,16 +11,13 @@ class CompositePKPivot public $key2; public $key3; public $key4; - public $parent_key1; public $parent_key2; public $parent_key3; public $parent_key4; - public $child_key1; public $child_key2; public $child_key3; public $child_key4; - public $as; } diff --git a/tests/ORM/Fixtures/CustomCollection.php b/tests/ORM/Fixtures/CustomCollection.php index cf7dc3b7..6ecee889 100644 --- a/tests/ORM/Fixtures/CustomCollection.php +++ b/tests/ORM/Fixtures/CustomCollection.php @@ -7,6 +7,4 @@ use Doctrine\Common\Collections\ArrayCollection; -final class CustomCollection extends ArrayCollection -{ -} +final class CustomCollection extends ArrayCollection {} diff --git a/tests/ORM/Fixtures/CyclicRef/Comment.php b/tests/ORM/Fixtures/CyclicRef/Comment.php index 0b91120b..5d4eb74e 100644 --- a/tests/ORM/Fixtures/CyclicRef/Comment.php +++ b/tests/ORM/Fixtures/CyclicRef/Comment.php @@ -9,7 +9,6 @@ class Comment { public $id; public $post_id; - public $message; /** @var User */ diff --git a/tests/ORM/Fixtures/CyclicRef/TimestampedMapper.php b/tests/ORM/Fixtures/CyclicRef/TimestampedMapper.php index 07f7862e..4c91b3ce 100644 --- a/tests/ORM/Fixtures/CyclicRef/TimestampedMapper.php +++ b/tests/ORM/Fixtures/CyclicRef/TimestampedMapper.php @@ -11,7 +11,6 @@ use Cycle\ORM\Heap\Node; use Cycle\ORM\Heap\State; use Cycle\ORM\Mapper\Mapper; -use DateTimeImmutable; class TimestampedMapper extends Mapper { @@ -20,7 +19,7 @@ public function queueCreate($entity, Node $node, State $state): CommandInterface /** @var Insert $cmd */ $cmd = parent::queueCreate($entity, $node, $state); - $dt = new DateTimeImmutable(); + $dt = new \DateTimeImmutable(); $state->register('created_at', $dt); $state->register('updated_at', $dt); @@ -32,7 +31,7 @@ public function queueUpdate($entity, Node $node, State $state): CommandInterface /** @var Update $cmd */ $cmd = parent::queueUpdate($entity, $node, $state); - $cmd->registerAppendix('updated_at', new DateTimeImmutable()); + $cmd->registerAppendix('updated_at', new \DateTimeImmutable()); return $cmd; } diff --git a/tests/ORM/Fixtures/CyclicRef/User.php b/tests/ORM/Fixtures/CyclicRef/User.php index b89b8756..b5e08883 100644 --- a/tests/ORM/Fixtures/CyclicRef/User.php +++ b/tests/ORM/Fixtures/CyclicRef/User.php @@ -9,7 +9,6 @@ class User { public $id; public $email; - public $created_at; public $updated_at; } diff --git a/tests/ORM/Fixtures/CyclicRef2/Document.php b/tests/ORM/Fixtures/CyclicRef2/Document.php index a7ccb1a3..a91bf6fc 100644 --- a/tests/ORM/Fixtures/CyclicRef2/Document.php +++ b/tests/ORM/Fixtures/CyclicRef2/Document.php @@ -9,14 +9,10 @@ class Document { public $tenant_id; public $id; - public $tenant; - public $preference_id; public $preference; - public $body; - public $created_at; public $updated_at; } diff --git a/tests/ORM/Fixtures/CyclicRef2/Preference.php b/tests/ORM/Fixtures/CyclicRef2/Preference.php index 15dd801b..9c2a8cdb 100644 --- a/tests/ORM/Fixtures/CyclicRef2/Preference.php +++ b/tests/ORM/Fixtures/CyclicRef2/Preference.php @@ -10,10 +10,8 @@ class Preference public $tenant; public $tenant_id; public $id; - public $flag; public $option; - public $created_at; public $updated_at; } diff --git a/tests/ORM/Fixtures/DifferentSource.php b/tests/ORM/Fixtures/DifferentSource.php index f831f3f9..73f50f0c 100644 --- a/tests/ORM/Fixtures/DifferentSource.php +++ b/tests/ORM/Fixtures/DifferentSource.php @@ -11,33 +11,21 @@ class DifferentSource implements SourceInterface { - /** - * @inheritDoc - */ public function getDatabase(): DatabaseInterface { throw new \RuntimeException('Not implemented.'); } - /** - * @inheritDoc - */ public function getTable(): string { throw new \RuntimeException('Not implemented.'); } - /** - * @inheritDoc - */ public function withScope(?ScopeInterface $scope): SourceInterface { return $this; } - /** - * @inheritDoc - */ public function getScope(): ?ScopeInterface { return null; diff --git a/tests/ORM/Fixtures/Enum/TypeIntEnum.php b/tests/ORM/Fixtures/Enum/TypeIntEnum.php index af904967..da105529 100644 --- a/tests/ORM/Fixtures/Enum/TypeIntEnum.php +++ b/tests/ORM/Fixtures/Enum/TypeIntEnum.php @@ -12,6 +12,6 @@ enum TypeIntEnum: int public static function make(int|string $value): ?self { - return self::tryFrom((int)$value); + return self::tryFrom((int) $value); } } diff --git a/tests/ORM/Fixtures/Enum/TypeStringEnum.php b/tests/ORM/Fixtures/Enum/TypeStringEnum.php index 151b99ab..0b21b312 100644 --- a/tests/ORM/Fixtures/Enum/TypeStringEnum.php +++ b/tests/ORM/Fixtures/Enum/TypeStringEnum.php @@ -12,6 +12,6 @@ enum TypeStringEnum: string public static function make(int|string $value): ?self { - return self::tryFrom((string)$value); + return self::tryFrom((string) $value); } } diff --git a/tests/ORM/Fixtures/Favorite.php b/tests/ORM/Fixtures/Favorite.php index 441d6990..eeed4d46 100644 --- a/tests/ORM/Fixtures/Favorite.php +++ b/tests/ORM/Fixtures/Favorite.php @@ -5,6 +5,4 @@ namespace Cycle\ORM\Tests\Fixtures; -class Favorite -{ -} +class Favorite {} diff --git a/tests/ORM/Fixtures/Group.php b/tests/ORM/Fixtures/Group.php index 29dd8e81..c7ae8cff 100644 --- a/tests/ORM/Fixtures/Group.php +++ b/tests/ORM/Fixtures/Group.php @@ -10,7 +10,6 @@ class Group { public $id; - public $name; /** diff --git a/tests/ORM/Fixtures/Image.php b/tests/ORM/Fixtures/Image.php index 0a747069..fc168bca 100644 --- a/tests/ORM/Fixtures/Image.php +++ b/tests/ORM/Fixtures/Image.php @@ -9,6 +9,5 @@ class Image { public $id; public $parent; - public $url; } diff --git a/tests/ORM/Fixtures/ImagedInterface.php b/tests/ORM/Fixtures/ImagedInterface.php index b5e4517c..e557b85f 100644 --- a/tests/ORM/Fixtures/ImagedInterface.php +++ b/tests/ORM/Fixtures/ImagedInterface.php @@ -5,6 +5,4 @@ namespace Cycle\ORM\Tests\Fixtures; -interface ImagedInterface -{ -} +interface ImagedInterface {} diff --git a/tests/ORM/Fixtures/OptimisticLockMapper.php b/tests/ORM/Fixtures/OptimisticLockMapper.php index 37556d68..17a22938 100644 --- a/tests/ORM/Fixtures/OptimisticLockMapper.php +++ b/tests/ORM/Fixtures/OptimisticLockMapper.php @@ -52,7 +52,7 @@ protected function lock(Node $node, State $state, Update|Delete $command): Wrapp if ($command->getAffectedRows() === 0) { throw new \RuntimeException(sprintf( 'The `%s` record is locked.', - $node->getRole() + $node->getRole(), )); } }); diff --git a/tests/ORM/Fixtures/Post.php b/tests/ORM/Fixtures/Post.php index dcf4d1cd..72079b12 100644 --- a/tests/ORM/Fixtures/Post.php +++ b/tests/ORM/Fixtures/Post.php @@ -20,6 +20,5 @@ class Post implements ImagedInterface public $comments; public ?Post $parent = null; - public UserWithUUIDPrimaryKey $userWithUuidPK; } diff --git a/tests/ORM/Fixtures/Tag.php b/tests/ORM/Fixtures/Tag.php index 9febcf71..6e52b59a 100644 --- a/tests/ORM/Fixtures/Tag.php +++ b/tests/ORM/Fixtures/Tag.php @@ -10,9 +10,7 @@ class Tag { public $id; - public $name; - public $users; public function __construct() diff --git a/tests/ORM/Fixtures/TestInsertCommand.php b/tests/ORM/Fixtures/TestInsertCommand.php index b96aa735..0617d089 100644 --- a/tests/ORM/Fixtures/TestInsertCommand.php +++ b/tests/ORM/Fixtures/TestInsertCommand.php @@ -6,6 +6,4 @@ use Cycle\Database\Query\InsertQuery; -class TestInsertCommand extends InsertQuery -{ -} +class TestInsertCommand extends InsertQuery {} diff --git a/tests/ORM/Fixtures/TestInsertCommandWithReturning.php b/tests/ORM/Fixtures/TestInsertCommandWithReturning.php index 2907512f..386c290c 100644 --- a/tests/ORM/Fixtures/TestInsertCommandWithReturning.php +++ b/tests/ORM/Fixtures/TestInsertCommandWithReturning.php @@ -6,6 +6,4 @@ use Cycle\Database\Query\InsertQuery; -abstract class TestInsertCommandWithReturning extends InsertQuery implements \Cycle\Database\Query\ReturningInterface -{ -} +abstract class TestInsertCommandWithReturning extends InsertQuery implements \Cycle\Database\Query\ReturningInterface {} diff --git a/tests/ORM/Fixtures/TestLogger.php b/tests/ORM/Fixtures/TestLogger.php index 8b2251cd..009e900f 100644 --- a/tests/ORM/Fixtures/TestLogger.php +++ b/tests/ORM/Fixtures/TestLogger.php @@ -14,7 +14,6 @@ class TestLogger implements LoggerInterface use LoggerTrait; private $display; - private $countWrites; private $countReads; diff --git a/tests/ORM/Fixtures/TimestampedMapper.php b/tests/ORM/Fixtures/TimestampedMapper.php index 709ad120..86bb270f 100644 --- a/tests/ORM/Fixtures/TimestampedMapper.php +++ b/tests/ORM/Fixtures/TimestampedMapper.php @@ -10,7 +10,6 @@ use Cycle\ORM\Heap\Node; use Cycle\ORM\Heap\State; use Cycle\ORM\Mapper\Mapper; -use DateTimeImmutable; class TimestampedMapper extends Mapper { @@ -18,7 +17,7 @@ public function queueCreate($entity, Node $node, State $state): CommandInterface { $cmd = parent::queueCreate($entity, $node, $state); - $dt = new DateTimeImmutable(); + $dt = new \DateTimeImmutable(); $state->register('created_at', $dt); $state->register('updated_at', $dt); @@ -30,7 +29,7 @@ public function queueUpdate($entity, Node $node, State $state): CommandInterface /** @var Update $cmd */ $cmd = parent::queueUpdate($entity, $node, $state); - $cmd->registerAppendix('updated_at', new DateTimeImmutable()); + $cmd->registerAppendix('updated_at', new \DateTimeImmutable()); return $cmd; } diff --git a/tests/ORM/Fixtures/TransactionTestMapper.php b/tests/ORM/Fixtures/TransactionTestMapper.php index 2e3d27a0..ad81807d 100644 --- a/tests/ORM/Fixtures/TransactionTestMapper.php +++ b/tests/ORM/Fixtures/TransactionTestMapper.php @@ -15,10 +15,8 @@ class TransactionTestMapper extends Mapper public function queueDelete($entity, Node $node, State $state): CommandInterface { if ($entity->id == '3') { - return new class ($this->source->getDatabase()) implements CommandInterface { - public function __construct(private DatabaseInterface $database) - { - } + return new class($this->source->getDatabase()) implements CommandInterface { + public function __construct(private DatabaseInterface $database) {} public function isReady(): bool { diff --git a/tests/ORM/Fixtures/User.php b/tests/ORM/Fixtures/User.php index 2abd4e9a..d1c0ffbe 100644 --- a/tests/ORM/Fixtures/User.php +++ b/tests/ORM/Fixtures/User.php @@ -70,9 +70,7 @@ class User implements ImagedInterface public $credentials; public array $settings; - public ?array $settingsNullable = null; - public ?JsonSerializableClass $jsonSerializable = null; public function __construct() diff --git a/tests/ORM/Fixtures/UserCredentials.php b/tests/ORM/Fixtures/UserCredentials.php index cb673e2b..719060df 100644 --- a/tests/ORM/Fixtures/UserCredentials.php +++ b/tests/ORM/Fixtures/UserCredentials.php @@ -9,7 +9,6 @@ class UserCredentials { public $username; public $password; - public $unmapped_public_property; private $unmapped_private_property; } diff --git a/tests/ORM/Fixtures/UserPersistRepository.php b/tests/ORM/Fixtures/UserPersistRepository.php index b210536a..2f124798 100644 --- a/tests/ORM/Fixtures/UserPersistRepository.php +++ b/tests/ORM/Fixtures/UserPersistRepository.php @@ -15,10 +15,6 @@ class UserPersistRepository extends Repository /** @var Transaction */ private $transaction; - /** - * @param Select $select - * @param ORMInterface $orm - */ public function __construct(Select $select, ORMInterface $orm) { parent::__construct($select); @@ -26,8 +22,6 @@ public function __construct(Select $select, ORMInterface $orm) } /** - * @param User $user - * @param bool $cascade * * @throws \Throwable */ @@ -35,7 +29,7 @@ public function save(User $user, bool $cascade = true): void { $this->transaction->persist( $user, - $cascade ? Transaction::MODE_CASCADE : Transaction::MODE_ENTITY_ONLY + $cascade ? Transaction::MODE_CASCADE : Transaction::MODE_ENTITY_ONLY, ); $this->transaction->run(); // transaction is clean after run diff --git a/tests/ORM/Fixtures/UserRepository.php b/tests/ORM/Fixtures/UserRepository.php index d0c7f8a0..ed65b42c 100644 --- a/tests/ORM/Fixtures/UserRepository.php +++ b/tests/ORM/Fixtures/UserRepository.php @@ -9,11 +9,6 @@ class UserRepository extends Repository { - /** - * @param string $email - * - * @return User|null - */ public function findByEmail(string $email): ?User { return $this->findOne(compact('email')); diff --git a/tests/ORM/Fixtures/UserSnapshotMapper.php b/tests/ORM/Fixtures/UserSnapshotMapper.php index cc09c239..65ddcca2 100644 --- a/tests/ORM/Fixtures/UserSnapshotMapper.php +++ b/tests/ORM/Fixtures/UserSnapshotMapper.php @@ -50,7 +50,7 @@ protected function snap(State $origin, string $action): StoreCommandInterface $this->source->getDatabase(), 'user_snapshots', $state, - null + null, )->withBeforeExecution(static function (StoreCommandInterface $command) use ($origin, $state): void { $state->register('user_id', $origin->getData()['id']); }); diff --git a/tests/ORM/Fixtures/UserWithUUIDPrimaryKey.php b/tests/ORM/Fixtures/UserWithUUIDPrimaryKey.php index 882cc11e..2c93a208 100644 --- a/tests/ORM/Fixtures/UserWithUUIDPrimaryKey.php +++ b/tests/ORM/Fixtures/UserWithUUIDPrimaryKey.php @@ -7,10 +7,10 @@ class UserWithUUIDPrimaryKey implements ImagedInterface { + public array $comments = []; private $uuid; private $email; private $balance; - public array $comments = []; public function __construct(UuidPrimaryKey $uuid, string $email, float $balance) { diff --git a/tests/ORM/Fixtures/Uuid.php b/tests/ORM/Fixtures/Uuid.php index 4db9f980..38dff45e 100644 --- a/tests/ORM/Fixtures/Uuid.php +++ b/tests/ORM/Fixtures/Uuid.php @@ -14,34 +14,9 @@ class Uuid implements ValueInterface /** @var UuidBody */ private $uuid; - /** - * @return string - */ - public function rawValue(): string - { - return $this->uuid->getBytes(); - } - - /** - * @return int - */ - public function rawType(): int - { - return \PDO::PARAM_LOB; - } - - /** - * @return string - */ - public function toString() - { - return $this->uuid->toString(); - } - /** * @throws \Exception * - * @return Uuid */ public static function create(): self { @@ -53,9 +28,7 @@ public static function create(): self /** * @param string $value - * @param DatabaseInterface $db * - * @return Uuid */ public static function parse($value, DatabaseInterface $db): self { @@ -69,4 +42,22 @@ public static function parse($value, DatabaseInterface $db): self return $uuid; } + + public function rawValue(): string + { + return $this->uuid->getBytes(); + } + + public function rawType(): int + { + return \PDO::PARAM_LOB; + } + + /** + * @return string + */ + public function toString() + { + return $this->uuid->toString(); + } } diff --git a/tests/ORM/Fixtures/UuidPrimaryKey.php b/tests/ORM/Fixtures/UuidPrimaryKey.php index 9a599a77..3d6c26a2 100644 --- a/tests/ORM/Fixtures/UuidPrimaryKey.php +++ b/tests/ORM/Fixtures/UuidPrimaryKey.php @@ -16,9 +16,9 @@ public function __construct(string $id) $this->id = $id; } - public function __toString(): string + public static function typecast($value, DatabaseInterface $database) { - return $this->id; + return new self($value); } public function getId(): string @@ -26,8 +26,8 @@ public function getId(): string return $this->id; } - public static function typecast($value, DatabaseInterface $database) + public function __toString(): string { - return new self($value); + return $this->id; } } diff --git a/tests/ORM/Functional/Driver/Common/BaseTest.php b/tests/ORM/Functional/Driver/Common/BaseTest.php index 90e853a2..ff2ac274 100644 --- a/tests/ORM/Functional/Driver/Common/BaseTest.php +++ b/tests/ORM/Functional/Driver/Common/BaseTest.php @@ -37,7 +37,6 @@ abstract class BaseTest extends TestCase // cross test driver cache public static $driverCache = []; - protected static $lastORM; /** @var Driver */ @@ -58,60 +57,6 @@ abstract class BaseTest extends TestCase /** @var int */ protected $numReads; - /** - * Init all we need. - */ - public function setUp(): void - { - parent::setUp(); - - $this->getDriver()->rollbackTransaction(); - - $this->dbal = new DatabaseManager(new DatabaseConfig()); - $this->dbal->addDatabase( - new Database( - 'default', - '', - $this->getDriver() - ) - ); - - $this->logger = new TestLogger(); - $this->getDriver()->setLogger($this->logger); - - if (self::$config['debug']) { - $this->logger->display(); - } - - $this->orm = new ORM( - (new Factory( - $this->dbal, - RelationConfig::getDefault(), - null, - new DoctrineCollectionFactory() - ))->withCollectionFactory('array', new ArrayCollectionFactory()), - new Schema([]), - $this->getCommandGenerator(), - ); - } - - /** - * Cleanup. - */ - public function tearDown(): void - { - $this->assertClearState($this->orm); - - $this->disableProfiling(); - $this->dropDatabase($this->dbal->database('default')); - $this->orm = null; - $this->dbal = null; - - if (\function_exists('gc_collect_cycles')) { - gc_collect_cycles(); - } - } - public function withSchema(SchemaInterface $schema): ORMInterface { $this->orm = $this->orm->with(schema: $schema); @@ -140,9 +85,6 @@ public function captureWriteQueries(): void $this->numWrites = $this->logger->countWriteQueries(); } - /** - * @param int $numWrites - */ public function assertNumWrites(int $numWrites): void { $queries = $this->logger->countWriteQueries() - $this->numWrites; @@ -151,7 +93,7 @@ public function assertNumWrites(int $numWrites): void $this->assertSame( $numWrites, $queries, - "Number of write SQL queries do not match, expected {$numWrites} got {$queries}." + "Number of write SQL queries do not match, expected {$numWrites} got {$queries}.", ); } } @@ -164,9 +106,6 @@ public function captureReadQueries(): void $this->numReads = $this->logger->countReadQueries(); } - /** - * @param int $numReads - */ public function assertNumReads(int $numReads): void { $queries = $this->logger->countReadQueries() - $this->numReads; @@ -175,23 +114,71 @@ public function assertNumReads(int $numReads): void $this->assertSame( $numReads, $queries, - "Number of read SQL queries do not match, expected {$numReads} got {$queries}." + "Number of read SQL queries do not match, expected {$numReads} got {$queries}.", ); } } /** - * @return Database + * Init all we need. */ - protected function getDatabase(): Database + public function setUp(): void { - return $this->dbal->database('default'); + parent::setUp(); + + $this->getDriver()->rollbackTransaction(); + + $this->dbal = new DatabaseManager(new DatabaseConfig()); + $this->dbal->addDatabase( + new Database( + 'default', + '', + $this->getDriver(), + ), + ); + + $this->logger = new TestLogger(); + $this->getDriver()->setLogger($this->logger); + + if (self::$config['debug']) { + $this->logger->display(); + } + + $this->orm = new ORM( + (new Factory( + $this->dbal, + RelationConfig::getDefault(), + null, + new DoctrineCollectionFactory(), + ))->withCollectionFactory('array', new ArrayCollectionFactory()), + new Schema([]), + $this->getCommandGenerator(), + ); } /** - * @param Database|null $database + * Cleanup. */ - protected function dropDatabase(Database $database = null): void + public function tearDown(): void + { + $this->assertClearState($this->orm); + + $this->disableProfiling(); + $this->dropDatabase($this->dbal->database('default')); + $this->orm = null; + $this->dbal = null; + + if (\function_exists('gc_collect_cycles')) { + gc_collect_cycles(); + } + } + + protected function getDatabase(): Database + { + return $this->dbal->database('default'); + } + + protected function dropDatabase(?Database $database = null): void { if ($database === null) { return; @@ -219,7 +206,7 @@ protected function dropDatabase(Database $database = null): void */ protected function enableProfiling(): void { - if (null !== $this->logger) { + if ($this->logger !== null) { $this->logger->display(); } } @@ -229,7 +216,7 @@ protected function enableProfiling(): void */ protected function disableProfiling(): void { - if (null !== $this->logger) { + if ($this->logger !== null) { $this->logger->hide(); } } @@ -277,7 +264,7 @@ protected function assertClearState(ORM $orm): void $node->getRole(), $orm->getMapper($entity)->extract($entity), $node->getData(), - $rel->getValue($node) + $rel->getValue($node), ); // all the states must be closed @@ -292,14 +279,14 @@ protected function assertEntitySynced( string $eName, array $entity, array $stateData, - array $relations + array $relations, ): void { foreach ($entity as $name => $eValue) { if (array_key_exists($name, $stateData)) { $this->assertEquals( $eValue, $stateData[$name], - "Entity and State are not in sync `{$eName}`.`{$name}`" + "Entity and State are not in sync `{$eName}`.`{$name}`", ); continue; @@ -315,7 +302,7 @@ protected function assertEntitySynced( $parentChain = []; do { $parentChain[] = $parent; - $relationSchema = (array)$this->orm->getSchema()->define($parent, SchemaInterface::RELATIONS); + $relationSchema = (array) $this->orm->getSchema()->define($parent, SchemaInterface::RELATIONS); if (array_key_exists($name, $relationSchema)) { $relation = $relationSchema[$name]; break; @@ -371,18 +358,18 @@ protected function assertEntitySynced( $this->assertEquals( $rValue->getScope(), $eValue->getScope(), - "Entity and State are not in sync `{$eName}`.`{$name}` (Reference scope)" + "Entity and State are not in sync `{$eName}`.`{$name}` (Reference scope)", ); $this->assertEquals( $rValue->getRole(), $eValue->getRole(), - "Entity and State are not in sync `{$eName}`.`{$name}` (Reference role)" + "Entity and State are not in sync `{$eName}`.`{$name}` (Reference role)", ); } else { $this->assertEquals( $rValue, $eValue, - "Entity and State are not in sync `{$eName}`.`{$name}`" + "Entity and State are not in sync `{$eName}`.`{$name}`", ); } } diff --git a/tests/ORM/Functional/Driver/Common/Benchmark/BenchmarkClasslessDoubleLinkedTest.php b/tests/ORM/Functional/Driver/Common/Benchmark/BenchmarkClasslessDoubleLinkedTest.php index ac6e6ab8..d74216c2 100644 --- a/tests/ORM/Functional/Driver/Common/Benchmark/BenchmarkClasslessDoubleLinkedTest.php +++ b/tests/ORM/Functional/Driver/Common/Benchmark/BenchmarkClasslessDoubleLinkedTest.php @@ -18,56 +18,6 @@ abstract class BenchmarkClasslessDoubleLinkedTest extends BaseTest { use TableTrait; - public function setUp(): void - { - if (!BaseTest::$config['benchmark']) { - $this->markTestSkipped(); - return; - } - - parent::setUp(); - - $this->makeTable('cyclic', [ - 'id' => 'primary', - 'name' => 'string', - 'parent_id' => 'integer,nullable', - ]); - - $this->orm = $this->withSchema(new Schema([ - 'cyclic' => [ - Schema::MAPPER => StdMapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'cyclic', - Schema::PRIMARY_KEY => 'id', - Schema::FIND_BY_KEYS => ['parent_id'], - Schema::COLUMNS => ['id', 'parent_id', 'name'], - Schema::SCHEMA => [], - Schema::RELATIONS => [ - 'cyclic' => [ - Relation::TYPE => Relation::HAS_ONE, - Relation::TARGET => 'cyclic', - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::NULLABLE => true, - Relation::INNER_KEY => 'id', - Relation::OUTER_KEY => 'parent_id', - ], - ], - 'other' => [ - Relation::TYPE => Relation::REFERS_TO, - Relation::TARGET => 'cyclic', - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::NULLABLE => true, - Relation::INNER_KEY => 'parent_id', - Relation::OUTER_KEY => 'id', - ], - ], - ], - ], - ])); - } - public function testMemoryUsage(): void { $this->orm = $this->orm->withHeap(new Heap()); @@ -120,4 +70,54 @@ public function testMemoryUsageDouble(): void $tr->run(); } + + public function setUp(): void + { + if (!BaseTest::$config['benchmark']) { + $this->markTestSkipped(); + return; + } + + parent::setUp(); + + $this->makeTable('cyclic', [ + 'id' => 'primary', + 'name' => 'string', + 'parent_id' => 'integer,nullable', + ]); + + $this->orm = $this->withSchema(new Schema([ + 'cyclic' => [ + Schema::MAPPER => StdMapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'cyclic', + Schema::PRIMARY_KEY => 'id', + Schema::FIND_BY_KEYS => ['parent_id'], + Schema::COLUMNS => ['id', 'parent_id', 'name'], + Schema::SCHEMA => [], + Schema::RELATIONS => [ + 'cyclic' => [ + Relation::TYPE => Relation::HAS_ONE, + Relation::TARGET => 'cyclic', + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::NULLABLE => true, + Relation::INNER_KEY => 'id', + Relation::OUTER_KEY => 'parent_id', + ], + ], + 'other' => [ + Relation::TYPE => Relation::REFERS_TO, + Relation::TARGET => 'cyclic', + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::NULLABLE => true, + Relation::INNER_KEY => 'parent_id', + Relation::OUTER_KEY => 'id', + ], + ], + ], + ], + ])); + } } diff --git a/tests/ORM/Functional/Driver/Common/Benchmark/BenchmarkDoubleLinkedTest.php b/tests/ORM/Functional/Driver/Common/Benchmark/BenchmarkDoubleLinkedTest.php index 24219864..85f959a1 100644 --- a/tests/ORM/Functional/Driver/Common/Benchmark/BenchmarkDoubleLinkedTest.php +++ b/tests/ORM/Functional/Driver/Common/Benchmark/BenchmarkDoubleLinkedTest.php @@ -19,57 +19,6 @@ abstract class BenchmarkDoubleLinkedTest extends BaseTest { use TableTrait; - public function setUp(): void - { - if (!BaseTest::$config['benchmark']) { - $this->markTestSkipped(); - return; - } - - parent::setUp(); - - $this->makeTable('cyclic', [ - 'id' => 'primary', - 'name' => 'string', - 'parent_id' => 'integer,nullable', - ]); - - $this->orm = $this->withSchema(new Schema([ - Cyclic::class => [ - Schema::ROLE => 'cyclic', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'cyclic', - Schema::PRIMARY_KEY => 'id', - Schema::FIND_BY_KEYS => ['parent_id'], - Schema::COLUMNS => ['id', 'parent_id', 'name'], - Schema::SCHEMA => [], - Schema::RELATIONS => [ - 'cyclic' => [ - Relation::TYPE => Relation::HAS_ONE, - Relation::TARGET => Cyclic::class, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::NULLABLE => true, - Relation::INNER_KEY => 'id', - Relation::OUTER_KEY => 'parent_id', - ], - ], - 'other' => [ - Relation::TYPE => Relation::REFERS_TO, - Relation::TARGET => Cyclic::class, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::NULLABLE => true, - Relation::INNER_KEY => 'parent_id', - Relation::OUTER_KEY => 'id', - ], - ], - ], - ], - ])); - } - public function testClean(): void { $this->orm = $this->orm->withHeap(new Heap()); @@ -137,4 +86,55 @@ public function testMemoryUsageDouble(): void $tr->run(); } + + public function setUp(): void + { + if (!BaseTest::$config['benchmark']) { + $this->markTestSkipped(); + return; + } + + parent::setUp(); + + $this->makeTable('cyclic', [ + 'id' => 'primary', + 'name' => 'string', + 'parent_id' => 'integer,nullable', + ]); + + $this->orm = $this->withSchema(new Schema([ + Cyclic::class => [ + Schema::ROLE => 'cyclic', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'cyclic', + Schema::PRIMARY_KEY => 'id', + Schema::FIND_BY_KEYS => ['parent_id'], + Schema::COLUMNS => ['id', 'parent_id', 'name'], + Schema::SCHEMA => [], + Schema::RELATIONS => [ + 'cyclic' => [ + Relation::TYPE => Relation::HAS_ONE, + Relation::TARGET => Cyclic::class, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::NULLABLE => true, + Relation::INNER_KEY => 'id', + Relation::OUTER_KEY => 'parent_id', + ], + ], + 'other' => [ + Relation::TYPE => Relation::REFERS_TO, + Relation::TARGET => Cyclic::class, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::NULLABLE => true, + Relation::INNER_KEY => 'parent_id', + Relation::OUTER_KEY => 'id', + ], + ], + ], + ], + ])); + } } diff --git a/tests/ORM/Functional/Driver/Common/Classless/ClasslessCyclicReferencesTest.php b/tests/ORM/Functional/Driver/Common/Classless/ClasslessCyclicReferencesTest.php index 4146d3a7..d4c24d33 100644 --- a/tests/ORM/Functional/Driver/Common/Classless/ClasslessCyclicReferencesTest.php +++ b/tests/ORM/Functional/Driver/Common/Classless/ClasslessCyclicReferencesTest.php @@ -17,133 +17,6 @@ abstract class ClasslessCyclicReferencesTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('user', [ - 'id' => 'primary', - 'email' => 'string', - 'balance' => 'float', - 'comment_id' => 'integer,nullable', - ]); - - $this->makeTable('comment', [ - 'id' => 'primary', - 'user_id' => 'integer', - 'message' => 'string', - ], [ - 'user_id' => ['table' => 'user', 'column' => 'id'], - ]); - - $this->makeTable('favorites', [ - 'id' => 'primary', - 'user_id' => 'integer', - 'comment_id' => 'integer', - ]); - - $this->makeFK('comment', 'user_id', 'user', 'id'); - $this->makeFK( - 'favorites', - 'user_id', - 'user', - 'id', - ForeignKeyInterface::NO_ACTION, - ForeignKeyInterface::NO_ACTION - ); - $this->makeFK( - 'favorites', - 'comment_id', - 'comment', - 'id', - ForeignKeyInterface::NO_ACTION, - ForeignKeyInterface::NO_ACTION - ); - $this->orm = $this->withSchema(new Schema([ - 'user' => [ - Schema::MAPPER => StdMapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'user', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'email', 'balance', 'comment_id'], - Schema::SCHEMA => [], - Schema::RELATIONS => [ - 'lastComment' => [ - Relation::TYPE => Relation::REFERS_TO, - Relation::TARGET => 'comment', - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::INNER_KEY => 'comment_id', - Relation::OUTER_KEY => 'id', - Relation::NULLABLE => true, - ], - ], - 'comments' => [ - Relation::TYPE => Relation::HAS_MANY, - Relation::TARGET => 'comment', - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::INNER_KEY => 'id', - Relation::OUTER_KEY => 'user_id', - ], - ], - 'favorites' => [ - Relation::TYPE => Relation::MANY_TO_MANY, - Relation::TARGET => 'comment', - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::THROUGH_ENTITY => 'favorite', - Relation::INNER_KEY => 'id', - Relation::OUTER_KEY => 'id', - Relation::THROUGH_INNER_KEY => 'user_id', - Relation::THROUGH_OUTER_KEY => 'comment_id', - ], - ], - ], - ], - 'comment' => [ - Schema::MAPPER => StdMapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'comment', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'user_id', 'message'], - Schema::SCHEMA => [], - Schema::RELATIONS => [ - 'user' => [ - Relation::TYPE => Relation::BELONGS_TO, - Relation::TARGET => 'user', - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::INNER_KEY => 'user_id', - Relation::OUTER_KEY => 'id', - ], - ], - 'favoredBy' => [ - Relation::TYPE => Relation::MANY_TO_MANY, - Relation::TARGET => 'user', - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::THROUGH_ENTITY => 'favorite', - Relation::INNER_KEY => 'id', - Relation::OUTER_KEY => 'id', - Relation::THROUGH_INNER_KEY => 'comment_id', - Relation::THROUGH_OUTER_KEY => 'user_id', - ], - ], - ], - ], - 'favorite' => [ - Schema::MAPPER => StdMapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'favorites', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'user_id', 'comment_id'], - Schema::SCHEMA => [], - Schema::RELATIONS => [], - ], - ])); - } - public function testCreate(): void { $u = $this->orm->make('user'); @@ -232,12 +105,12 @@ public function testCreateMultipleLinkedTrees(): void $this->assertEquals($u->favorites[0]->user->id, $u1->favorites[0]->user->id); $fav = [ - (string)$u1->favorites[0]->favoredBy[0]->id, - (string)$u1->favorites[0]->favoredBy[1]->id, + (string) $u1->favorites[0]->favoredBy[0]->id, + (string) $u1->favorites[0]->favoredBy[1]->id, ]; - $this->assertContains((string)$u->id, $fav); - $this->assertContains((string)$u2->id, $fav); + $this->assertContains((string) $u->id, $fav); + $this->assertContains((string) $u2->id, $fav); $this->orm = $this->orm->withHeap(new Heap()); @@ -248,8 +121,8 @@ public function testCreateMultipleLinkedTrees(): void ->load('favorites') ->wherePK($u2->id)->fetchOne(); - $this->assertEquals((string)$u1->id, $u2->id); - $this->assertEquals((string)$u1->favorites[0]->id, $u2->favorites[0]->id); + $this->assertEquals((string) $u1->id, $u2->id); + $this->assertEquals((string) $u1->favorites[0]->id, $u2->favorites[0]->id); } public function testCreateMultipleLinkedTreesExchange(): void @@ -290,4 +163,131 @@ public function testCreateMultipleLinkedTreesExchange(): void $this->save($u, $u2); $this->assertNumWrites(0); } + + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('user', [ + 'id' => 'primary', + 'email' => 'string', + 'balance' => 'float', + 'comment_id' => 'integer,nullable', + ]); + + $this->makeTable('comment', [ + 'id' => 'primary', + 'user_id' => 'integer', + 'message' => 'string', + ], [ + 'user_id' => ['table' => 'user', 'column' => 'id'], + ]); + + $this->makeTable('favorites', [ + 'id' => 'primary', + 'user_id' => 'integer', + 'comment_id' => 'integer', + ]); + + $this->makeFK('comment', 'user_id', 'user', 'id'); + $this->makeFK( + 'favorites', + 'user_id', + 'user', + 'id', + ForeignKeyInterface::NO_ACTION, + ForeignKeyInterface::NO_ACTION, + ); + $this->makeFK( + 'favorites', + 'comment_id', + 'comment', + 'id', + ForeignKeyInterface::NO_ACTION, + ForeignKeyInterface::NO_ACTION, + ); + $this->orm = $this->withSchema(new Schema([ + 'user' => [ + Schema::MAPPER => StdMapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'user', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'email', 'balance', 'comment_id'], + Schema::SCHEMA => [], + Schema::RELATIONS => [ + 'lastComment' => [ + Relation::TYPE => Relation::REFERS_TO, + Relation::TARGET => 'comment', + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::INNER_KEY => 'comment_id', + Relation::OUTER_KEY => 'id', + Relation::NULLABLE => true, + ], + ], + 'comments' => [ + Relation::TYPE => Relation::HAS_MANY, + Relation::TARGET => 'comment', + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::INNER_KEY => 'id', + Relation::OUTER_KEY => 'user_id', + ], + ], + 'favorites' => [ + Relation::TYPE => Relation::MANY_TO_MANY, + Relation::TARGET => 'comment', + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::THROUGH_ENTITY => 'favorite', + Relation::INNER_KEY => 'id', + Relation::OUTER_KEY => 'id', + Relation::THROUGH_INNER_KEY => 'user_id', + Relation::THROUGH_OUTER_KEY => 'comment_id', + ], + ], + ], + ], + 'comment' => [ + Schema::MAPPER => StdMapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'comment', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'user_id', 'message'], + Schema::SCHEMA => [], + Schema::RELATIONS => [ + 'user' => [ + Relation::TYPE => Relation::BELONGS_TO, + Relation::TARGET => 'user', + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::INNER_KEY => 'user_id', + Relation::OUTER_KEY => 'id', + ], + ], + 'favoredBy' => [ + Relation::TYPE => Relation::MANY_TO_MANY, + Relation::TARGET => 'user', + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::THROUGH_ENTITY => 'favorite', + Relation::INNER_KEY => 'id', + Relation::OUTER_KEY => 'id', + Relation::THROUGH_INNER_KEY => 'comment_id', + Relation::THROUGH_OUTER_KEY => 'user_id', + ], + ], + ], + ], + 'favorite' => [ + Schema::MAPPER => StdMapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'favorites', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'user_id', 'comment_id'], + Schema::SCHEMA => [], + Schema::RELATIONS => [], + ], + ])); + } } diff --git a/tests/ORM/Functional/Driver/Common/Classless/ClasslessHasManyPromiseTest.php b/tests/ORM/Functional/Driver/Common/Classless/ClasslessHasManyPromiseTest.php index ffb00359..cb327caa 100644 --- a/tests/ORM/Functional/Driver/Common/Classless/ClasslessHasManyPromiseTest.php +++ b/tests/ORM/Functional/Driver/Common/Classless/ClasslessHasManyPromiseTest.php @@ -20,74 +20,6 @@ abstract class ClasslessHasManyPromiseTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('user', [ - 'id' => 'primary', - 'email' => 'string', - 'balance' => 'float', - ]); - - $this->getDatabase()->table('user')->insertMultiple( - ['email', 'balance'], - [ - ['hello@world.com', 100], - ['another@world.com', 200], - ] - ); - - $this->makeTable('comment', [ - 'id' => 'primary', - 'user_id' => 'integer', - 'message' => 'string', - ]); - - $this->makeFK('comment', 'user_id', 'user', 'id'); - - $this->getDatabase()->table('comment')->insertMultiple( - ['user_id', 'message'], - [ - [1, 'msg 1'], - [1, 'msg 2'], - [1, 'msg 3'], - ] - ); - - $this->orm = $this->withSchema(new Schema([ - 'user' => [ - Schema::MAPPER => StdMapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'user', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'email', 'balance'], - Schema::SCHEMA => [], - Schema::RELATIONS => [ - 'comments' => [ - Relation::TYPE => Relation::HAS_MANY, - Relation::TARGET => 'comment', - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::INNER_KEY => 'id', - Relation::OUTER_KEY => 'user_id', - ], - ], - ], - ], - 'comment' => [ - Schema::MAPPER => StdMapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'comment', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'user_id', 'message'], - Schema::SCHEMA => [], - Schema::RELATIONS => [], - Schema::SCOPE => SortByIDScope::class, - ], - ])); - } - public function testInitRelation(): void { $u = $this->orm->make('user'); @@ -319,4 +251,72 @@ public function testSliceAndSaveToAnotherParent(): void $this->assertEquals('new b', $b->comments[0]->message); } + + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('user', [ + 'id' => 'primary', + 'email' => 'string', + 'balance' => 'float', + ]); + + $this->getDatabase()->table('user')->insertMultiple( + ['email', 'balance'], + [ + ['hello@world.com', 100], + ['another@world.com', 200], + ], + ); + + $this->makeTable('comment', [ + 'id' => 'primary', + 'user_id' => 'integer', + 'message' => 'string', + ]); + + $this->makeFK('comment', 'user_id', 'user', 'id'); + + $this->getDatabase()->table('comment')->insertMultiple( + ['user_id', 'message'], + [ + [1, 'msg 1'], + [1, 'msg 2'], + [1, 'msg 3'], + ], + ); + + $this->orm = $this->withSchema(new Schema([ + 'user' => [ + Schema::MAPPER => StdMapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'user', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'email', 'balance'], + Schema::SCHEMA => [], + Schema::RELATIONS => [ + 'comments' => [ + Relation::TYPE => Relation::HAS_MANY, + Relation::TARGET => 'comment', + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::INNER_KEY => 'id', + Relation::OUTER_KEY => 'user_id', + ], + ], + ], + ], + 'comment' => [ + Schema::MAPPER => StdMapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'comment', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'user_id', 'message'], + Schema::SCHEMA => [], + Schema::RELATIONS => [], + Schema::SCOPE => SortByIDScope::class, + ], + ])); + } } diff --git a/tests/ORM/Functional/Driver/Common/Classless/ClasslessHasOneCyclicTest.php b/tests/ORM/Functional/Driver/Common/Classless/ClasslessHasOneCyclicTest.php index df598591..75c4a922 100644 --- a/tests/ORM/Functional/Driver/Common/Classless/ClasslessHasOneCyclicTest.php +++ b/tests/ORM/Functional/Driver/Common/Classless/ClasslessHasOneCyclicTest.php @@ -17,50 +17,6 @@ abstract class ClasslessHasOneCyclicTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('cyclic', [ - 'id' => 'primary', - 'name' => 'string', - 'parent_id' => 'integer,nullable', - ]); - - $this->getDatabase()->table('cyclic')->insertMultiple( - ['parent_id', 'name'], - [ - [null, 'first'], - [1, 'second'], - [3, 'self-reference'], - ] - ); - - $this->orm = $this->withSchema(new Schema([ - 'cyclic' => [ - Schema::MAPPER => StdMapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'cyclic', - Schema::PRIMARY_KEY => 'id', - Schema::FIND_BY_KEYS => ['parent_id'], - Schema::COLUMNS => ['id', 'parent_id', 'name'], - Schema::SCHEMA => [], - Schema::RELATIONS => [ - 'cyclic' => [ - Relation::TYPE => Relation::HAS_ONE, - Relation::TARGET => 'cyclic', - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::NULLABLE => true, - Relation::INNER_KEY => 'id', - Relation::OUTER_KEY => 'parent_id', - ], - ], - ], - ], - ])); - } - public function testFetchCyclic(): void { $selector = new Select($this->orm, 'cyclic'); @@ -147,4 +103,48 @@ public function testCreateCyclic(): void $this->assertEquals('new', $c->name); $this->assertSame($c, $c->cyclic); } + + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('cyclic', [ + 'id' => 'primary', + 'name' => 'string', + 'parent_id' => 'integer,nullable', + ]); + + $this->getDatabase()->table('cyclic')->insertMultiple( + ['parent_id', 'name'], + [ + [null, 'first'], + [1, 'second'], + [3, 'self-reference'], + ], + ); + + $this->orm = $this->withSchema(new Schema([ + 'cyclic' => [ + Schema::MAPPER => StdMapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'cyclic', + Schema::PRIMARY_KEY => 'id', + Schema::FIND_BY_KEYS => ['parent_id'], + Schema::COLUMNS => ['id', 'parent_id', 'name'], + Schema::SCHEMA => [], + Schema::RELATIONS => [ + 'cyclic' => [ + Relation::TYPE => Relation::HAS_ONE, + Relation::TARGET => 'cyclic', + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::NULLABLE => true, + Relation::INNER_KEY => 'id', + Relation::OUTER_KEY => 'parent_id', + ], + ], + ], + ], + ])); + } } diff --git a/tests/ORM/Functional/Driver/Common/Classless/ClasslessInverseRelationTest.php b/tests/ORM/Functional/Driver/Common/Classless/ClasslessInverseRelationTest.php index cf2a9938..6e73964e 100644 --- a/tests/ORM/Functional/Driver/Common/Classless/ClasslessInverseRelationTest.php +++ b/tests/ORM/Functional/Driver/Common/Classless/ClasslessInverseRelationTest.php @@ -17,85 +17,6 @@ abstract class ClasslessInverseRelationTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('user', [ - 'id' => 'primary', - 'email' => 'string', - 'balance' => 'float', - ]); - - $this->getDatabase()->table('user')->insertMultiple( - ['email', 'balance'], - [ - ['hello@world.com', 100], - ['another@world.com', 200], - ] - ); - - $this->makeTable('profile', [ - 'id' => 'primary', - 'user_id' => 'integer', - 'image' => 'string', - ]); - - $this->makeFK('profile', 'user_id', 'user', 'id'); - - $this->getDatabase()->table('profile')->insertMultiple( - ['user_id', 'image'], - [ - [1, 'image.png'], - [2, 'second.png'], - [2, 'third.png'], - ] - ); - - $this->orm = $this->withSchema(new Schema([ - 'user' => [ - Schema::MAPPER => StdMapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'user', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'email', 'balance'], - Schema::SCHEMA => [], - Schema::RELATIONS => [ - 'profile' => [ - Relation::TYPE => Relation::HAS_ONE, - Relation::TARGET => 'profile', - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::INNER_KEY => 'id', - Relation::OUTER_KEY => 'user_id', - ], - ], - ], - Schema::SCOPE => SortByIDScope::class, - ], - 'profile' => [ - Schema::MAPPER => StdMapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'profile', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'user_id', 'image'], - Schema::SCHEMA => [], - Schema::RELATIONS => [ - 'user' => [ - Relation::TYPE => Relation::BELONGS_TO, - Relation::TARGET => 'user', - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::INNER_KEY => 'user_id', - Relation::OUTER_KEY => 'id', - ], - ], - ], - Schema::SCOPE => SortByIDScope::class, - ], - ])); - } - public function testFetchRelation(): void { $selector = new Select($this->orm, 'user'); @@ -173,4 +94,83 @@ public function testCyclicThoughtInverse(): void $this->orm = $this->orm->withHeap(new Heap()); } + + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('user', [ + 'id' => 'primary', + 'email' => 'string', + 'balance' => 'float', + ]); + + $this->getDatabase()->table('user')->insertMultiple( + ['email', 'balance'], + [ + ['hello@world.com', 100], + ['another@world.com', 200], + ], + ); + + $this->makeTable('profile', [ + 'id' => 'primary', + 'user_id' => 'integer', + 'image' => 'string', + ]); + + $this->makeFK('profile', 'user_id', 'user', 'id'); + + $this->getDatabase()->table('profile')->insertMultiple( + ['user_id', 'image'], + [ + [1, 'image.png'], + [2, 'second.png'], + [2, 'third.png'], + ], + ); + + $this->orm = $this->withSchema(new Schema([ + 'user' => [ + Schema::MAPPER => StdMapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'user', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'email', 'balance'], + Schema::SCHEMA => [], + Schema::RELATIONS => [ + 'profile' => [ + Relation::TYPE => Relation::HAS_ONE, + Relation::TARGET => 'profile', + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::INNER_KEY => 'id', + Relation::OUTER_KEY => 'user_id', + ], + ], + ], + Schema::SCOPE => SortByIDScope::class, + ], + 'profile' => [ + Schema::MAPPER => StdMapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'profile', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'user_id', 'image'], + Schema::SCHEMA => [], + Schema::RELATIONS => [ + 'user' => [ + Relation::TYPE => Relation::BELONGS_TO, + Relation::TARGET => 'user', + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::INNER_KEY => 'user_id', + Relation::OUTER_KEY => 'id', + ], + ], + ], + Schema::SCOPE => SortByIDScope::class, + ], + ])); + } } diff --git a/tests/ORM/Functional/Driver/Common/Classless/StdMapperTest.php b/tests/ORM/Functional/Driver/Common/Classless/StdMapperTest.php index f15f912a..a8bf4a6e 100644 --- a/tests/ORM/Functional/Driver/Common/Classless/StdMapperTest.php +++ b/tests/ORM/Functional/Driver/Common/Classless/StdMapperTest.php @@ -17,37 +17,6 @@ abstract class StdMapperTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('user', [ - 'id' => 'primary', - 'email' => 'string', - 'balance' => 'float', - ]); - - $this->getDatabase()->table('user')->insertMultiple( - ['email', 'balance'], - [ - ['hello@world.com', 100], - ['another@world.com', 200], - ] - ); - - $this->orm = $this->withSchema(new Schema([ - 'user' => [ - Schema::MAPPER => StdMapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'user', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'email', 'balance'], - Schema::SCHEMA => [], - Schema::RELATIONS => [], - ], - ])); - } - public function testFetchData(): void { $selector = new Select($this->orm, 'user'); @@ -145,7 +114,7 @@ public function testHeap(): void 'email' => 'hello@world.com', 'balance' => 100.0, ], - $this->orm->getHeap()->get($result)->getData() + $this->orm->getHeap()->get($result)->getData(), ); } @@ -235,4 +204,35 @@ public function testRepositoryFindOneWithWhere(): void $this->assertEquals('another@world.com', $result->email); $this->assertEquals(200.0, $result->balance); } + + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('user', [ + 'id' => 'primary', + 'email' => 'string', + 'balance' => 'float', + ]); + + $this->getDatabase()->table('user')->insertMultiple( + ['email', 'balance'], + [ + ['hello@world.com', 100], + ['another@world.com', 200], + ], + ); + + $this->orm = $this->withSchema(new Schema([ + 'user' => [ + Schema::MAPPER => StdMapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'user', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'email', 'balance'], + Schema::SCHEMA => [], + Schema::RELATIONS => [], + ], + ])); + } } diff --git a/tests/ORM/Functional/Driver/Common/EntityManager/EntityManagerTest.php b/tests/ORM/Functional/Driver/Common/EntityManager/EntityManagerTest.php index 63cdbbbc..c1b0c998 100644 --- a/tests/ORM/Functional/Driver/Common/EntityManager/EntityManagerTest.php +++ b/tests/ORM/Functional/Driver/Common/EntityManager/EntityManagerTest.php @@ -18,38 +18,6 @@ abstract class EntityManagerTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('post', [ - 'id' => 'primary', - 'title' => 'string', - 'content' => 'string', - ]); - - $this->getDatabase()->table('post')->insertMultiple( - ['title', 'content'], - [ - ['foo', 'foofoo'], - ['bar', 'barbar'], - ] - ); - - $this->orm = $this->withSchema(new Schema([ - Post::class => [ - SchemaInterface::ROLE => 'post', - SchemaInterface::MAPPER => Mapper::class, - SchemaInterface::DATABASE => 'default', - SchemaInterface::TABLE => 'post', - SchemaInterface::PRIMARY_KEY => 'id', - SchemaInterface::COLUMNS => ['id', 'title', 'content'], - SchemaInterface::SCHEMA => [], - SchemaInterface::RELATIONS => [], - ], - ])); - } - public function testClean(): void { $em = new EntityManager($this->orm); @@ -261,5 +229,37 @@ public function testRunError(): void $this->assertInstanceOf(ConstrainException::class, $result->getLastError()); } + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('post', [ + 'id' => 'primary', + 'title' => 'string', + 'content' => 'string', + ]); + + $this->getDatabase()->table('post')->insertMultiple( + ['title', 'content'], + [ + ['foo', 'foofoo'], + ['bar', 'barbar'], + ], + ); + + $this->orm = $this->withSchema(new Schema([ + Post::class => [ + SchemaInterface::ROLE => 'post', + SchemaInterface::MAPPER => Mapper::class, + SchemaInterface::DATABASE => 'default', + SchemaInterface::TABLE => 'post', + SchemaInterface::PRIMARY_KEY => 'id', + SchemaInterface::COLUMNS => ['id', 'title', 'content'], + SchemaInterface::SCHEMA => [], + SchemaInterface::RELATIONS => [], + ], + ])); + } + // todo test parallel transactions running } diff --git a/tests/ORM/Functional/Driver/Common/Enum/EnumTest.php b/tests/ORM/Functional/Driver/Common/Enum/EnumTest.php index 51822e5f..188eec74 100644 --- a/tests/ORM/Functional/Driver/Common/Enum/EnumTest.php +++ b/tests/ORM/Functional/Driver/Common/Enum/EnumTest.php @@ -23,44 +23,6 @@ abstract class EnumTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('user', [ - 'id' => 'primary', - 'balance' => 'int', - 'type_str' => 'string', - 'type_int' => 'int', - ]); - - $this->getDatabase()->table('user')->insertMultiple( - ['balance', 'type_str', 'type_int'], - [ - [56, TypeStringEnum::Guest->value, TypeIntEnum::Guest->value], - [42, TypeStringEnum::User->value, TypeIntEnum::User->value], - [69, TypeStringEnum::Admin->value, TypeIntEnum::Admin->value], - ] - ); - - $this->orm = $this->withSchema(new Schema([ - User::class => [ - SchemaInterface::ROLE => 'user', - SchemaInterface::MAPPER => Mapper::class, - SchemaInterface::DATABASE => 'default', - SchemaInterface::TABLE => 'user', - SchemaInterface::PRIMARY_KEY => 'id', - SchemaInterface::COLUMNS => ['id', 'balance', 'type_str', 'type_int'], - SchemaInterface::TYPECAST => [ - 'type_str' => \Closure::fromCallable([TypeStringEnum::class, 'make']), - 'type_int' => \Closure::fromCallable([TypeIntEnum::class, 'make']), - ], - SchemaInterface::SCHEMA => [], - SchemaInterface::RELATIONS => [], - ], - ])); - } - public function testFetchRawData(): void { $selector = new Select($this->orm, User::class); @@ -86,7 +48,7 @@ public function testFetchRawData(): void 'type_int' => 2, ], ], - $selector->fetchData(typecast: false) + $selector->fetchData(typecast: false), ); } @@ -115,7 +77,7 @@ public function testFetchData(): void 'type_int' => TypeIntEnum::Admin, ], ], - $selector->fetchData() + $selector->fetchData(), ); } @@ -138,4 +100,42 @@ public function testStoreData(): void $this->markTestSkipped("Can't save a Enum value because it is not supported yet."); } } + + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('user', [ + 'id' => 'primary', + 'balance' => 'int', + 'type_str' => 'string', + 'type_int' => 'int', + ]); + + $this->getDatabase()->table('user')->insertMultiple( + ['balance', 'type_str', 'type_int'], + [ + [56, TypeStringEnum::Guest->value, TypeIntEnum::Guest->value], + [42, TypeStringEnum::User->value, TypeIntEnum::User->value], + [69, TypeStringEnum::Admin->value, TypeIntEnum::Admin->value], + ], + ); + + $this->orm = $this->withSchema(new Schema([ + User::class => [ + SchemaInterface::ROLE => 'user', + SchemaInterface::MAPPER => Mapper::class, + SchemaInterface::DATABASE => 'default', + SchemaInterface::TABLE => 'user', + SchemaInterface::PRIMARY_KEY => 'id', + SchemaInterface::COLUMNS => ['id', 'balance', 'type_str', 'type_int'], + SchemaInterface::TYPECAST => [ + 'type_str' => \Closure::fromCallable([TypeStringEnum::class, 'make']), + 'type_int' => \Closure::fromCallable([TypeIntEnum::class, 'make']), + ], + SchemaInterface::SCHEMA => [], + SchemaInterface::RELATIONS => [], + ], + ])); + } } diff --git a/tests/ORM/Functional/Driver/Common/FactoryTest.php b/tests/ORM/Functional/Driver/Common/FactoryTest.php index 0631ad5a..39e7f86e 100644 --- a/tests/ORM/Functional/Driver/Common/FactoryTest.php +++ b/tests/ORM/Functional/Driver/Common/FactoryTest.php @@ -23,25 +23,6 @@ abstract class FactoryTest extends BaseTest */ private $factory; - public function setUp(): void - { - parent::setUp(); - - $this->orm = $this->withSchema(new Schema([ - User::class => [ - Schema::ROLE => 'user', - Schema::DATABASE => 'default', - Schema::TABLE => 'user', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'email', 'balance'], - Schema::SCHEMA => [], - Schema::RELATIONS => [], - ], - ])); - - $this->factory = new Factory($this->dbal); - } - public function testShouldMakeDefaultMapper(): void { $mapper = $this->factory->mapper($this->orm, 'user'); @@ -77,7 +58,7 @@ public function testShouldMakeDefaultRepository(): void $this->orm, $this->orm->getSchema(), 'user', - new Select($this->orm, 'user') + new Select($this->orm, 'user'), ); $this->assertInstanceOf(Repository::class, $result); @@ -93,7 +74,7 @@ public function testShouldChangeDefaultRepositoryClass(): void $this->orm, $this->orm->getSchema(), 'user', - new Select($this->orm, 'user') + new Select($this->orm, 'user'), ); $this->assertInstanceOf(UserRepository::class, $result); @@ -138,4 +119,23 @@ public function testShouldThrowExceptionIfDefaultSourceClassNotImplementSourceIn $this->factory->source($this->orm->getSchema(), 'user'); } + + public function setUp(): void + { + parent::setUp(); + + $this->orm = $this->withSchema(new Schema([ + User::class => [ + Schema::ROLE => 'user', + Schema::DATABASE => 'default', + Schema::TABLE => 'user', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'email', 'balance'], + Schema::SCHEMA => [], + Schema::RELATIONS => [], + ], + ])); + + $this->factory = new Factory($this->dbal); + } } diff --git a/tests/ORM/Functional/Driver/Common/GeneratedColumnTest.php b/tests/ORM/Functional/Driver/Common/GeneratedColumnTest.php index 8f877897..f4de012b 100644 --- a/tests/ORM/Functional/Driver/Common/GeneratedColumnTest.php +++ b/tests/ORM/Functional/Driver/Common/GeneratedColumnTest.php @@ -16,7 +16,6 @@ use Cycle\ORM\Tests\Traits\TableTrait; use Cycle\ORM\Tests\Util\DontGenerateAttribute; use Cycle\ORM\Transaction; -use DateTimeImmutable; use Ramsey\Uuid\Uuid; #[DontGenerateAttribute] @@ -24,6 +23,49 @@ abstract class GeneratedColumnTest extends BaseTest { use TableTrait; + public function testPersist(): void + { + $u = new User(); + $u->id = Uuid::uuid4()->toString(); + + $this->save($u); + + $this->assertNotNull($u->balance); + + $this->orm->getHeap()->clean(); + + $s = (new Select($this->orm, User::class))->wherePK($u->id)->fetchOne(); + + $this->assertSame($u->balance, $s->balance); + } + + public function testPersistMultipleSerial(): void + { + $d1 = new Document(); + + $d2 = new Document(); + $d2->body = 213; + $d2->created_at = $d2->updated_at = new \DateTimeImmutable('2020-01-01'); + + $d3 = new Document(); + $d3->created_at = $d3->updated_at = new \DateTimeImmutable('2020-01-01'); + + + $this->save($d1, $d2, $d3); + + $this->assertEquals(1, $d1->id); + $this->assertEquals(1, $d1->body); + $this->assertNotSame('2020-01-01', $d1->created_at->format('Y-m-d')); + $this->assertEquals(2, $d2->id); + $this->assertEquals(213, $d2->body); + $this->assertSame('2020-01-01', $d2->created_at->format('Y-m-d')); + $this->assertEquals(3, $d3->id); + $this->assertEquals(2, $d3->body); + $this->assertSame('2020-01-01', $d3->created_at->format('Y-m-d')); + } + + abstract public function createTables(): void; + public function setUp(): void { parent::setUp(); @@ -67,57 +109,16 @@ public function setUp(): void ])); } - public function testPersist(): void - { - $u = new User(); - $u->id = Uuid::uuid4()->toString(); - - $this->save($u); - - $this->assertNotNull($u->balance); - - $this->orm->getHeap()->clean(); - - $s = (new Select($this->orm, User::class))->wherePK($u->id)->fetchOne(); - - $this->assertSame($u->balance, $s->balance); - } - - public function testPersistMultipleSerial(): void - { - $d1 = new Document(); - - $d2 = new Document(); - $d2->body = 213; - $d2->created_at = $d2->updated_at = new DateTimeImmutable('2020-01-01'); - - $d3 = new Document(); - $d3->created_at = $d3->updated_at = new DateTimeImmutable('2020-01-01'); - - - $this->save($d1, $d2, $d3); - - $this->assertEquals(1, $d1->id); - $this->assertEquals(1, $d1->body); - $this->assertNotSame('2020-01-01', $d1->created_at->format('Y-m-d')); - $this->assertEquals(2, $d2->id); - $this->assertEquals(213, $d2->body); - $this->assertSame('2020-01-01', $d2->created_at->format('Y-m-d')); - $this->assertEquals(3, $d3->id); - $this->assertEquals(2, $d3->body); - $this->assertSame('2020-01-01', $d3->created_at->format('Y-m-d')); - } - protected function getCommandGenerator(): ?Transaction\CommandGeneratorInterface { - return new class () extends Transaction\CommandGenerator { + return new class extends Transaction\CommandGenerator { protected function storeEntity(ORMInterface $orm, Transaction\Tuple $tuple, bool $isNew): ?CommandInterface { /** @var CommandInterface|null $command */ $command = parent::storeEntity($orm, $tuple, $isNew); if ($command !== null && $tuple->entity instanceof Document && empty($tuple->entity->updated_at)) { - $now = new DateTimeImmutable(); + $now = new \DateTimeImmutable(); $tuple->state->register('updated_at', $now); $tuple->entity->updated_at = $now; } @@ -126,6 +127,4 @@ protected function storeEntity(ORMInterface $orm, Transaction\Tuple $tuple, bool } }; } - - abstract public function createTables(): void; } diff --git a/tests/ORM/Functional/Driver/Common/Inheritance/Fixture/EBook.php b/tests/ORM/Functional/Driver/Common/Inheritance/Fixture/EBook.php index 06032c9c..5676b3ed 100644 --- a/tests/ORM/Functional/Driver/Common/Inheritance/Fixture/EBook.php +++ b/tests/ORM/Functional/Driver/Common/Inheritance/Fixture/EBook.php @@ -8,6 +8,7 @@ class EBook extends Book { public string $url; public ?int $block_id = null; + /** @var Page[] */ public array $pages = []; } diff --git a/tests/ORM/Functional/Driver/Common/Inheritance/Fixture/Employee.php b/tests/ORM/Functional/Driver/Common/Inheritance/Fixture/Employee.php index 3b57b7ef..d5c2b006 100644 --- a/tests/ORM/Functional/Driver/Common/Inheritance/Fixture/Employee.php +++ b/tests/ORM/Functional/Driver/Common/Inheritance/Fixture/Employee.php @@ -9,10 +9,8 @@ class Employee extends Human { public ?int $employee_id = null; - public ?string $name = null; public ?string $email = null; public ?int $age = 0; - public null|Book|ReferenceInterface $book = null; } diff --git a/tests/ORM/Functional/Driver/Common/Inheritance/Fixture/Engineer.php b/tests/ORM/Functional/Driver/Common/Inheritance/Fixture/Engineer.php index 0f58fa25..064de875 100644 --- a/tests/ORM/Functional/Driver/Common/Inheritance/Fixture/Engineer.php +++ b/tests/ORM/Functional/Driver/Common/Inheritance/Fixture/Engineer.php @@ -9,7 +9,6 @@ class Engineer extends Employee { public ?int $role_id = null; - public int $level = 0; public ?string $rank = null; public null|Book|ReferenceInterface $tech_book = null; diff --git a/tests/ORM/Functional/Driver/Common/Inheritance/Fixture/HtmlPage.php b/tests/ORM/Functional/Driver/Common/Inheritance/Fixture/HtmlPage.php index a4835519..ed74870c 100644 --- a/tests/ORM/Functional/Driver/Common/Inheritance/Fixture/HtmlPage.php +++ b/tests/ORM/Functional/Driver/Common/Inheritance/Fixture/HtmlPage.php @@ -4,6 +4,4 @@ namespace Cycle\ORM\Tests\Functional\Driver\Common\Inheritance\Fixture; -class HtmlPage extends Page -{ -} +class HtmlPage extends Page {} diff --git a/tests/ORM/Functional/Driver/Common/Inheritance/Fixture/Manager.php b/tests/ORM/Functional/Driver/Common/Inheritance/Fixture/Manager.php index ef0c529f..ca83da21 100644 --- a/tests/ORM/Functional/Driver/Common/Inheritance/Fixture/Manager.php +++ b/tests/ORM/Functional/Driver/Common/Inheritance/Fixture/Manager.php @@ -7,7 +7,6 @@ class Manager extends Employee { public ?int $role_id = null; - public ?int $level = null; public string $rank = 'none'; } diff --git a/tests/ORM/Functional/Driver/Common/Inheritance/Fixture/ManagerWithCredentials.php b/tests/ORM/Functional/Driver/Common/Inheritance/Fixture/ManagerWithCredentials.php index eed86239..0b4b9f44 100644 --- a/tests/ORM/Functional/Driver/Common/Inheritance/Fixture/ManagerWithCredentials.php +++ b/tests/ORM/Functional/Driver/Common/Inheritance/Fixture/ManagerWithCredentials.php @@ -9,7 +9,6 @@ class ManagerWithCredentials extends Employee { public ?int $role_id = null; - public ?int $level = null; public string $rank = 'none'; public ?UserCredentials $credentials = null; diff --git a/tests/ORM/Functional/Driver/Common/Inheritance/Fixture/MarkdownPage.php b/tests/ORM/Functional/Driver/Common/Inheritance/Fixture/MarkdownPage.php index 825e6182..8f028ad1 100644 --- a/tests/ORM/Functional/Driver/Common/Inheritance/Fixture/MarkdownPage.php +++ b/tests/ORM/Functional/Driver/Common/Inheritance/Fixture/MarkdownPage.php @@ -4,6 +4,4 @@ namespace Cycle\ORM\Tests\Functional\Driver\Common\Inheritance\Fixture; -class MarkdownPage extends Page -{ -} +class MarkdownPage extends Page {} diff --git a/tests/ORM/Functional/Driver/Common/Inheritance/Fixture/Programator.php b/tests/ORM/Functional/Driver/Common/Inheritance/Fixture/Programator.php index dbb33b78..adfce7b2 100644 --- a/tests/ORM/Functional/Driver/Common/Inheritance/Fixture/Programator.php +++ b/tests/ORM/Functional/Driver/Common/Inheritance/Fixture/Programator.php @@ -8,6 +8,5 @@ class Programator extends Engineer { public ?int $subrole_id = null; public ?int $second_id = null; - public string $language; } diff --git a/tests/ORM/Functional/Driver/Common/Inheritance/Fixture/RbacItemAbstract.php b/tests/ORM/Functional/Driver/Common/Inheritance/Fixture/RbacItemAbstract.php index 43f17486..31b8cfeb 100644 --- a/tests/ORM/Functional/Driver/Common/Inheritance/Fixture/RbacItemAbstract.php +++ b/tests/ORM/Functional/Driver/Common/Inheritance/Fixture/RbacItemAbstract.php @@ -31,7 +31,7 @@ class RbacItemAbstract */ public $children; - public function __construct(string $name, string $description = null) + public function __construct(string $name, ?string $description = null) { $this->name = $name; $this->description = $description; diff --git a/tests/ORM/Functional/Driver/Common/Inheritance/Fixture/RbacPermission.php b/tests/ORM/Functional/Driver/Common/Inheritance/Fixture/RbacPermission.php index dc0d3993..cdfd165e 100644 --- a/tests/ORM/Functional/Driver/Common/Inheritance/Fixture/RbacPermission.php +++ b/tests/ORM/Functional/Driver/Common/Inheritance/Fixture/RbacPermission.php @@ -4,6 +4,4 @@ namespace Cycle\ORM\Tests\Functional\Driver\Common\Inheritance\Fixture; -class RbacPermission extends RbacItemAbstract -{ -} +class RbacPermission extends RbacItemAbstract {} diff --git a/tests/ORM/Functional/Driver/Common/Inheritance/Fixture/RbacRole.php b/tests/ORM/Functional/Driver/Common/Inheritance/Fixture/RbacRole.php index 5e2092fc..45f55373 100644 --- a/tests/ORM/Functional/Driver/Common/Inheritance/Fixture/RbacRole.php +++ b/tests/ORM/Functional/Driver/Common/Inheritance/Fixture/RbacRole.php @@ -4,6 +4,4 @@ namespace Cycle\ORM\Tests\Functional\Driver\Common\Inheritance\Fixture; -class RbacRole extends RbacItemAbstract -{ -} +class RbacRole extends RbacItemAbstract {} diff --git a/tests/ORM/Functional/Driver/Common/Inheritance/JTI/CompositePKTest.php b/tests/ORM/Functional/Driver/Common/Inheritance/JTI/CompositePKTest.php index 0a58c6bb..53013a50 100644 --- a/tests/ORM/Functional/Driver/Common/Inheritance/JTI/CompositePKTest.php +++ b/tests/ORM/Functional/Driver/Common/Inheritance/JTI/CompositePKTest.php @@ -16,137 +16,48 @@ abstract class CompositePKTest extends SimpleCasesTest { protected const EMPLOYEE_DEFAULT_SORTING = ['id' => 'ASC', 'employee_id' => 'ASC']; - protected const - EMPLOYEE_1 = ['id' => 1, 'employee_id' => 2, 'name' => 'John', 'age' => 38]; - protected const - EMPLOYEE_2 = ['id' => 2, 'employee_id' => 3, 'name' => 'Anton', 'age' => 35]; - protected const - EMPLOYEE_3 = ['id' => 3, 'employee_id' => 4, 'name' => 'Kentarius', 'age' => 27]; - protected const - EMPLOYEE_4 = ['id' => 4, 'employee_id' => 5, 'name' => 'Valeriy', 'age' => 32]; - protected const - ENGINEER_2 = ['_type' => 'engineer', 'id' => 2, 'role_id' => 3, 'level' => 8, 'rank' => null]; - protected const - ENGINEER_4 = ['_type' => 'engineer', 'id' => 4, 'role_id' => 5, 'level' => 10, 'rank' => null]; - protected const - MANAGER_1 = ['_type' => 'manager', 'id' => 1, 'role_id' => 2, 'level' => null, 'rank' => 'top']; - protected const - MANAGER_3 = ['_type' => 'manager', 'id' => 3, 'role_id' => 4, 'level' => null, 'rank' => 'bottom']; - protected const - ENGINEER_2_PK = ['id' => 2, 'role_id' => 3]; - protected const - EMPLOYEE_2_PK = ['id' => 2, 'employee_id' => 3]; - protected const - PROGRAMATOR_2_PK = ['second_id' => 3, 'subrole_id' => 2]; - protected const - PROGRAMATOR_2 = ['second_id' => 3, 'subrole_id' => 2, 'language' => 'php']; - protected const - PROGRAMATOR_4 = ['second_id' => 5, 'subrole_id' => 4, 'language' => 'go']; - protected const - EMPLOYEE_1_LOADED = self::EMPLOYEE_1; - protected const - EMPLOYEE_2_LOADED = self::EMPLOYEE_2; - protected const - EMPLOYEE_3_LOADED = self::EMPLOYEE_3; - protected const - EMPLOYEE_4_LOADED = self::EMPLOYEE_4; - protected const - ENGINEER_2_LOADED = self::ENGINEER_2 + self::EMPLOYEE_2_LOADED; - protected const - ENGINEER_4_LOADED = self::ENGINEER_4 + self::EMPLOYEE_4_LOADED; - protected const - PROGRAMATOR_2_LOADED = self::PROGRAMATOR_2 + self::ENGINEER_2_LOADED; - protected const - PROGRAMATOR_4_LOADED = self::PROGRAMATOR_4 + self::ENGINEER_4_LOADED; - protected const - MANAGER_1_LOADED = self::MANAGER_1 + self::EMPLOYEE_1_LOADED; - protected const - MANAGER_3_LOADED = self::MANAGER_3 + self::EMPLOYEE_3_LOADED; - protected const - EMPLOYEE_ALL_LOADED = [ - self::EMPLOYEE_1_LOADED, - self::EMPLOYEE_2_LOADED, - self::EMPLOYEE_3_LOADED, - self::EMPLOYEE_4_LOADED, - ]; - protected const - EMPLOYEE_INHERITED_LOADED = [ - self::MANAGER_1_LOADED, - self::PROGRAMATOR_2_LOADED, - self::MANAGER_3_LOADED, - self::PROGRAMATOR_4_LOADED, - ]; - protected const - ENGINEER_ALL_LOADED = [self::ENGINEER_2_LOADED, self::ENGINEER_4_LOADED]; - protected const - ENGINEER_INHERITED_LOADED = [self::PROGRAMATOR_2_LOADED, self::PROGRAMATOR_4_LOADED]; - protected const - PROGRAMATOR_ALL_LOADED = [self::PROGRAMATOR_2_LOADED, self::PROGRAMATOR_4_LOADED]; - protected const - MANAGER_ALL_LOADED = [self::MANAGER_1_LOADED, self::MANAGER_3_LOADED]; - protected const - // todo: remove when STI will support classless entities and Schema::CHILDREN's roles + protected const EMPLOYEE_1 = ['id' => 1, 'employee_id' => 2, 'name' => 'John', 'age' => 38]; + protected const EMPLOYEE_2 = ['id' => 2, 'employee_id' => 3, 'name' => 'Anton', 'age' => 35]; + protected const EMPLOYEE_3 = ['id' => 3, 'employee_id' => 4, 'name' => 'Kentarius', 'age' => 27]; + protected const EMPLOYEE_4 = ['id' => 4, 'employee_id' => 5, 'name' => 'Valeriy', 'age' => 32]; + protected const ENGINEER_2 = ['_type' => 'engineer', 'id' => 2, 'role_id' => 3, 'level' => 8, 'rank' => null]; + protected const ENGINEER_4 = ['_type' => 'engineer', 'id' => 4, 'role_id' => 5, 'level' => 10, 'rank' => null]; + protected const MANAGER_1 = ['_type' => 'manager', 'id' => 1, 'role_id' => 2, 'level' => null, 'rank' => 'top']; + protected const MANAGER_3 = ['_type' => 'manager', 'id' => 3, 'role_id' => 4, 'level' => null, 'rank' => 'bottom']; + protected const ENGINEER_2_PK = ['id' => 2, 'role_id' => 3]; + protected const EMPLOYEE_2_PK = ['id' => 2, 'employee_id' => 3]; + protected const PROGRAMATOR_2_PK = ['second_id' => 3, 'subrole_id' => 2]; + protected const PROGRAMATOR_2 = ['second_id' => 3, 'subrole_id' => 2, 'language' => 'php']; + protected const PROGRAMATOR_4 = ['second_id' => 5, 'subrole_id' => 4, 'language' => 'go']; + protected const EMPLOYEE_1_LOADED = self::EMPLOYEE_1; + protected const EMPLOYEE_2_LOADED = self::EMPLOYEE_2; + protected const EMPLOYEE_3_LOADED = self::EMPLOYEE_3; + protected const EMPLOYEE_4_LOADED = self::EMPLOYEE_4; + protected const ENGINEER_2_LOADED = self::ENGINEER_2 + self::EMPLOYEE_2_LOADED; + protected const ENGINEER_4_LOADED = self::ENGINEER_4 + self::EMPLOYEE_4_LOADED; + protected const PROGRAMATOR_2_LOADED = self::PROGRAMATOR_2 + self::ENGINEER_2_LOADED; + protected const PROGRAMATOR_4_LOADED = self::PROGRAMATOR_4 + self::ENGINEER_4_LOADED; + protected const MANAGER_1_LOADED = self::MANAGER_1 + self::EMPLOYEE_1_LOADED; + protected const MANAGER_3_LOADED = self::MANAGER_3 + self::EMPLOYEE_3_LOADED; + protected const EMPLOYEE_ALL_LOADED = [ + self::EMPLOYEE_1_LOADED, + self::EMPLOYEE_2_LOADED, + self::EMPLOYEE_3_LOADED, + self::EMPLOYEE_4_LOADED, + ]; + protected const EMPLOYEE_INHERITED_LOADED = [ + self::MANAGER_1_LOADED, + self::PROGRAMATOR_2_LOADED, + self::MANAGER_3_LOADED, + self::PROGRAMATOR_4_LOADED, + ]; + protected const ENGINEER_ALL_LOADED = [self::ENGINEER_2_LOADED, self::ENGINEER_4_LOADED]; + protected const ENGINEER_INHERITED_LOADED = [self::PROGRAMATOR_2_LOADED, self::PROGRAMATOR_4_LOADED]; + protected const PROGRAMATOR_ALL_LOADED = [self::PROGRAMATOR_2_LOADED, self::PROGRAMATOR_4_LOADED]; + protected const MANAGER_ALL_LOADED = [self::MANAGER_1_LOADED, self::MANAGER_3_LOADED]; + protected const // todo: remove when STI will support classless entities and Schema::CHILDREN's roles PROGRAMATOR_ROLE = Programator::class; - protected const - ENGINEER_ROLE = Engineer::class; - - public function setUp(): void - { - JtiBaseTest::setUp(); - - $this->makeTable('employee', [ - 'id' => 'integer', - 'employee_id' => 'integer', - 'name_column' => 'string', - 'age' => 'integer,nullable', - ], pk: ['id', 'employee_id']); - $this->makeIndex('employee', ['employee_id'], false); - - $this->makeTable('role', [ - 'id' => 'integer', - 'role_id' => 'integer', - '_type' => 'string', - 'level' => 'integer,nullable', - 'rank' => 'string,nullable', - ], fk: [ - ['from' => ['id', 'role_id'], 'table' => 'employee', 'column' => ['id', 'employee_id']], - ], pk: ['id', 'role_id']); - $this->makeIndex('role', ['role_id', 'id'], true); - - $this->makeTable('programator', [ - 'id' => 'integer', - 'subrole_id' => 'integer', - 'language' => 'string', - ], fk: [ - ['from' => ['id', 'subrole_id'], 'table' => 'role', 'column' => ['role_id', 'id']], - ], pk: ['id', 'subrole_id']); - - $this->getDatabase()->table('employee')->insertMultiple( - ['id', 'employee_id', 'name_column', 'age'], - [ - self::EMPLOYEE_1, - self::EMPLOYEE_2, - self::EMPLOYEE_3, - self::EMPLOYEE_4, - ] - ); - $this->getDatabase()->table('role')->insertMultiple( - ['_type', 'id', 'role_id', 'level', 'rank'], - [ - self::MANAGER_1, - self::ENGINEER_2, - self::MANAGER_3, - self::ENGINEER_4, - ] - ); - $this->getDatabase()->table('programator')->insertMultiple( - ['id', 'subrole_id', 'language'], - [ - self::PROGRAMATOR_2, - self::PROGRAMATOR_4, - ] - ); - } + protected const ENGINEER_ROLE = Engineer::class; public function testSelectEngineerAllDataWithInheritance(): void { @@ -248,6 +159,64 @@ public function testCreateProgramator(): void $this->assertSame('VanillaJS', $programator->language); } + public function setUp(): void + { + JtiBaseTest::setUp(); + + $this->makeTable('employee', [ + 'id' => 'integer', + 'employee_id' => 'integer', + 'name_column' => 'string', + 'age' => 'integer,nullable', + ], pk: ['id', 'employee_id']); + $this->makeIndex('employee', ['employee_id'], false); + + $this->makeTable('role', [ + 'id' => 'integer', + 'role_id' => 'integer', + '_type' => 'string', + 'level' => 'integer,nullable', + 'rank' => 'string,nullable', + ], fk: [ + ['from' => ['id', 'role_id'], 'table' => 'employee', 'column' => ['id', 'employee_id']], + ], pk: ['id', 'role_id']); + $this->makeIndex('role', ['role_id', 'id'], true); + + $this->makeTable('programator', [ + 'id' => 'integer', + 'subrole_id' => 'integer', + 'language' => 'string', + ], fk: [ + ['from' => ['id', 'subrole_id'], 'table' => 'role', 'column' => ['role_id', 'id']], + ], pk: ['id', 'subrole_id']); + + $this->getDatabase()->table('employee')->insertMultiple( + ['id', 'employee_id', 'name_column', 'age'], + [ + self::EMPLOYEE_1, + self::EMPLOYEE_2, + self::EMPLOYEE_3, + self::EMPLOYEE_4, + ], + ); + $this->getDatabase()->table('role')->insertMultiple( + ['_type', 'id', 'role_id', 'level', 'rank'], + [ + self::MANAGER_1, + self::ENGINEER_2, + self::MANAGER_3, + self::ENGINEER_4, + ], + ); + $this->getDatabase()->table('programator')->insertMultiple( + ['id', 'subrole_id', 'language'], + [ + self::PROGRAMATOR_2, + self::PROGRAMATOR_4, + ], + ); + } + protected function getSchemaArray(): array { return [ diff --git a/tests/ORM/Functional/Driver/Common/Inheritance/JTI/JtiBaseTest.php b/tests/ORM/Functional/Driver/Common/Inheritance/JTI/JtiBaseTest.php index 0a162d1d..783e940f 100644 --- a/tests/ORM/Functional/Driver/Common/Inheritance/JTI/JtiBaseTest.php +++ b/tests/ORM/Functional/Driver/Common/Inheritance/JTI/JtiBaseTest.php @@ -26,7 +26,7 @@ public function setUp(): void $this->dbal, RelationConfig::getDefault(), null, - new ArrayCollectionFactory() + new ArrayCollectionFactory(), ); $this->orm = $this->withSchema(new Schema($this->getSchemaArray()))->withFactory($factory); } diff --git a/tests/ORM/Functional/Driver/Common/Inheritance/JTI/Relation/EmbeddedRelationsTest.php b/tests/ORM/Functional/Driver/Common/Inheritance/JTI/Relation/EmbeddedRelationsTest.php index 01e01d23..ea0b9a10 100644 --- a/tests/ORM/Functional/Driver/Common/Inheritance/JTI/Relation/EmbeddedRelationsTest.php +++ b/tests/ORM/Functional/Driver/Common/Inheritance/JTI/Relation/EmbeddedRelationsTest.php @@ -18,7 +18,6 @@ abstract class EmbeddedRelationsTest extends JtiBaseTest { protected const EMPLOYEE_ROLE = 'employee'; protected const MANAGER_ROLE = 'manager_with_credentials'; - protected const EMPLOYEE_1 = ['id' => 1, 'name' => 'John', 'age' => 38]; protected const EMPLOYEE_2 = ['id' => 2, 'name' => 'Anton', 'age' => 35]; protected const EMPLOYEE_3 = ['id' => 3, 'name' => 'Kentarius', 'age' => 27]; @@ -26,43 +25,6 @@ abstract class EmbeddedRelationsTest extends JtiBaseTest protected const MANAGER_1 = ['id' => 1, 'rank' => 'top']; protected const MANAGER_3 = ['id' => 3, 'rank' => 'bottom']; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('employee', [ - 'id' => 'integer', - 'name' => 'string', - 'age' => 'integer,nullable', - ], pk: ['id']); - - $this->makeTable('manager_with_credentials', [ - 'id' => 'integer', - 'rank' => 'string', - 'creds_username' => 'string,nullable', - 'creds_password' => 'string,nullable', - ], fk: [ - 'id' => ['table' => 'employee', 'column' => 'id'], - ], pk: ['id']); - - $this->getDatabase()->table('employee')->insertMultiple( - array_keys(static::EMPLOYEE_1), - [ - self::EMPLOYEE_1, - self::EMPLOYEE_2, - self::EMPLOYEE_3, - self::EMPLOYEE_4, - ] - ); - $this->getDatabase()->table('manager_with_credentials')->insertMultiple( - array_keys(static::MANAGER_1), - [ - self::MANAGER_1, - self::MANAGER_3, - ] - ); - } - /** * Parent's relation should be initialized */ @@ -94,7 +56,7 @@ public function testInsertToEmbeddedFieldsForJtiChildEntity(): void public function testInsertToCreatingNewEmbeddedObjectForJtiChildEntity(): void { $this->markTestSkipped( - 'TODO: Must be fixed. When we create new embedded object, we should update entity\'s node in heap' + 'TODO: Must be fixed. When we create new embedded object, we should update entity\'s node in heap', ); /** @var ManagerWithCredentials $entity */ @@ -121,6 +83,43 @@ public function testInsertToCreatingNewEmbeddedObjectForJtiChildEntity(): void $this->assertSame('secret', $entity->credentials->password); } + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('employee', [ + 'id' => 'integer', + 'name' => 'string', + 'age' => 'integer,nullable', + ], pk: ['id']); + + $this->makeTable('manager_with_credentials', [ + 'id' => 'integer', + 'rank' => 'string', + 'creds_username' => 'string,nullable', + 'creds_password' => 'string,nullable', + ], fk: [ + 'id' => ['table' => 'employee', 'column' => 'id'], + ], pk: ['id']); + + $this->getDatabase()->table('employee')->insertMultiple( + array_keys(static::EMPLOYEE_1), + [ + self::EMPLOYEE_1, + self::EMPLOYEE_2, + self::EMPLOYEE_3, + self::EMPLOYEE_4, + ], + ); + $this->getDatabase()->table('manager_with_credentials')->insertMultiple( + array_keys(static::MANAGER_1), + [ + self::MANAGER_1, + self::MANAGER_3, + ], + ); + } + protected function getSchemaArray(): array { return [ diff --git a/tests/ORM/Functional/Driver/Common/Inheritance/JTI/Relation/HierarchyInRelationTest.php b/tests/ORM/Functional/Driver/Common/Inheritance/JTI/Relation/HierarchyInRelationTest.php index 96cf88ff..1cb1c3c7 100644 --- a/tests/ORM/Functional/Driver/Common/Inheritance/JTI/Relation/HierarchyInRelationTest.php +++ b/tests/ORM/Functional/Driver/Common/Inheritance/JTI/Relation/HierarchyInRelationTest.php @@ -92,6 +92,147 @@ abstract class HierarchyInRelationTest extends JtiBaseTest protected const PROGRAMATOR_ALL_LOADED = [self::PROGRAMATOR_2_LOADED, self::PROGRAMATOR_4_LOADED]; protected const MANAGER_ALL_LOADED = [self::MANAGER_1_LOADED, self::MANAGER_3_LOADED]; + /** + * Subclasses in relations should be loaded and initialized + */ + public function testLoadSubclassAndCheckParentsRelations(): void + { + /** @var Programator $entity */ + $entity = (new Select($this->orm, static::PROGRAMATOR_ROLE)) + ->load('tech_book') + ->wherePK(2)->fetchOne(); + + $this->assertInstanceof(Programator::class, $entity); + /** BOOK_3 */ + $this->assertInstanceof(Book::class, $entity->tech_book); + $this->assertSame(3, $entity->tech_book->id); + /** EBOOK_3 */ + $this->assertInstanceof(EBook::class, $entity->tech_book); + $this->assertSame(static::EBOOK_3['url'], $entity->tech_book->url); + // Check relation eager loading in the book subclass + /** @var EBook $ebook */ + $ebook = $entity->tech_book; + $this->assertCount(3, $ebook->pages); + } + + /** + * Subclass relations can't be resolved manually + */ + public function testLoadRelationOfSubclass(): void + { + $this->expectException(LoaderException::class); + $this->expectExceptionMessage('Unable to create loader: Undefined relation `human`.`book`.'); + + /** @var Programator $entity */ + (new Select($this->orm, static::HUMAN_ROLE)) + // Load subclass relation + ->load('book') + ->wherePK(2)->fetchOne(); + } + + public function testLoadBaseClassAndCheckSubclassEagerRelations(): void + { + /** @var Programator $entity */ + $entity = (new Select($this->orm, static::HUMAN_ROLE)) + ->wherePK(2)->fetchOne(); + + $this->assertInstanceof(Programator::class, $entity); + /** BOOK_4 */ + $this->assertInstanceof(Book::class, $entity->book); + $this->assertSame(4, $entity->book->id); + /** EBOOK_4 */ + $this->assertInstanceof(EBook::class, $entity->book); + $this->assertSame(static::EBOOK_4['url'], $entity->book->url); + // Check relation eager loading in the book subclass + /** @var EBook $ebook */ + $ebook = $entity->book; + $this->assertEmpty($ebook->pages); + } + + public function testInnerLoadParentClassRelation(): void + { + $this->captureReadQueries(); + + /** @var MarkdownPage $entity */ + $entity = (new Select($this->orm, static::MARKDOWN_PAGE_ROLE)) + ->load('owner', ['method' => Select::SINGLE_QUERY]) + ->wherePK(1)->fetchOne(); + + $this->assertNumReads(2); + + $this->assertInstanceof(MarkdownPage::class, $entity); + $this->assertInstanceof(Programator::class, $entity->owner); + } + + /** + * Inheritance hierarchy should be joined as sub-query + */ + public function testInnerLoadParentClassRelationNullToNull(): void + { + /** @var MarkdownPage $entity */ + $entity = (new Select($this->orm, static::MARKDOWN_PAGE_ROLE)) + ->load('ebook', ['method' => Select::SINGLE_QUERY]) + ->wherePK(5)->fetchOne(); + + $this->assertInstanceof(MarkdownPage::class, $entity); + $this->assertNull($entity->block_id); + $this->assertNull($entity->ebook); + } + + public function testLoadTwoInheritancesInSingleQuery(): void + { + $this->captureReadQueries(); + + /** @var Programator $entity */ + $entity = (new Select($this->orm, static::PROGRAMATOR_ROLE)) + ->load('book', ['method' => Select::SINGLE_QUERY]) + ->load('tech_book', ['method' => Select::SINGLE_QUERY]) + ->load('tech_book.pages', ['method' => Select::SINGLE_QUERY]) + ->wherePK(2)->fetchOne(); + + $this->assertNumReads(1); + $this->captureReadQueries(); + + $this->assertInstanceof(EBook::class, $entity->book); + $this->assertSame(4, $entity->book->id); + $this->assertInstanceof(EBook::class, $entity->tech_book); + $this->assertSame(3, $entity->tech_book->id); + $this->assertNotEmpty($entity->tech_book->pages); + + // Don't use promises + $this->assertNumReads(0); + } + + public function testPersistRelatedHierarchy(): void + { + /** @var Ebook $entity */ + $entity = $this->orm->make(EBook::class, [ + 'title' => 'awesome book', + 'url' => 'awesome-book.com', + 'block_id' => 100, + 'pages' => [], + ]); + $entity->pages = [ + $this->orm->make(Page::class, ['title' => 'page 1', 'content' => '...', 'owner_id' => 1]), + $this->orm->make(Page::class, ['title' => 'page 2', 'content' => '...', 'owner_id' => 1]), + $this->orm->make(MarkdownPage::class, ['title' => 'page 3', 'content' => '...', 'owner_id' => 2]), + ]; + + $this->captureWriteQueries(); + $this->save($entity); + $this->assertNumWrites(6); + + // Relations are not non-rewritable on sync hydration + // This behavior can be changed + $this->assertNull($entity->pages[0]->ebook); + $this->assertNull($entity->pages[1]->ebook); + $this->assertNull($entity->pages[2]->ebook); + + // $this->captureWriteQueries(); + // $this->save($entity); + // $this->assertNumWrites(0); + } + public function setUp(): void { JtiBaseTest::setUp(); @@ -170,28 +311,28 @@ public function setUp(): void $this->getDatabase()->table('book_table')->insertMultiple( \array_values(\array_diff(\array_keys(static::BOOK_1), ['id'])), - \array_map(static fn (array $value): array => \array_diff_key($value, ['id' => 1]), [ + \array_map(static fn(array $value): array => \array_diff_key($value, ['id' => 1]), [ self::BOOK_1, self::BOOK_2, self::BOOK_3, self::BOOK_4, - ]) + ]), ); $this->getDatabase()->table('ebook_table')->insertMultiple( array_keys(static::EBOOK_3), [ self::EBOOK_3, self::EBOOK_4, - ] + ], ); $this->getDatabase()->table('human_table')->insertMultiple( \array_values(\array_diff(\array_keys(static::HUMAN_1), ['id'])), - \array_map(static fn (array $value): array => \array_diff_key($value, ['id' => 1]), [ + \array_map(static fn(array $value): array => \array_diff_key($value, ['id' => 1]), [ self::HUMAN_1, self::HUMAN_2, self::HUMAN_3, self::HUMAN_4, - ]) + ]), ); $this->getDatabase()->table('employee_table')->insertMultiple( array_keys(static::EMPLOYEE_1), @@ -200,204 +341,63 @@ public function setUp(): void self::EMPLOYEE_2, self::EMPLOYEE_3, self::EMPLOYEE_4, - ] + ], ); $this->getDatabase()->table('engineer_table')->insertMultiple( array_keys(static::ENGINEER_2), [ self::ENGINEER_2, self::ENGINEER_4, - ] + ], ); $this->getDatabase()->table('programator_table')->insertMultiple( array_keys(static::PROGRAMATOR_2), [ self::PROGRAMATOR_2, self::PROGRAMATOR_4, - ] + ], ); $this->getDatabase()->table('manager_table')->insertMultiple( array_keys(static::MANAGER_1), [ self::MANAGER_1, self::MANAGER_3, - ] + ], ); $this->getDatabase()->table('page_table')->insertMultiple( \array_values(\array_diff(\array_keys(static::PAGE_1), ['id'])), - \array_map(static fn (array $value): array => \array_diff_key($value, ['id' => 1]), [ + \array_map(static fn(array $value): array => \array_diff_key($value, ['id' => 1]), [ self::PAGE_1, self::PAGE_2, self::PAGE_3, self::PAGE_4, self::PAGE_5, - ]) + ]), ); $this->getDatabase()->table('html_page_table')->insertMultiple( array_keys(static::HTML_PAGE_2), [ static::HTML_PAGE_2, - ] + ], ); $this->getDatabase()->table('markdown_page_table')->insertMultiple( array_keys(static::MARKDOWN_PAGE_1), [ static::MARKDOWN_PAGE_1, static::MARKDOWN_PAGE_5, - ] + ], ); $this->getDatabase()->table('tool_table')->insertMultiple( \array_values(\array_diff(\array_keys(static::TOOL_1), ['id'])), - \array_map(static fn (array $value): array => \array_diff_key($value, ['id' => 1]), [ + \array_map(static fn(array $value): array => \array_diff_key($value, ['id' => 1]), [ self::TOOL_1, self::TOOL_2, self::TOOL_3, self::TOOL_4, - ]) + ]), ); } - /** - * Subclasses in relations should be loaded and initialized - */ - public function testLoadSubclassAndCheckParentsRelations(): void - { - /** @var Programator $entity */ - $entity = (new Select($this->orm, static::PROGRAMATOR_ROLE)) - ->load('tech_book') - ->wherePK(2)->fetchOne(); - - $this->assertInstanceof(Programator::class, $entity); - /** BOOK_3 */ - $this->assertInstanceof(Book::class, $entity->tech_book); - $this->assertSame(3, $entity->tech_book->id); - /** EBOOK_3 */ - $this->assertInstanceof(EBook::class, $entity->tech_book); - $this->assertSame(static::EBOOK_3['url'], $entity->tech_book->url); - // Check relation eager loading in the book subclass - /** @var EBook $ebook */ - $ebook = $entity->tech_book; - $this->assertCount(3, $ebook->pages); - } - - /** - * Subclass relations can't be resolved manually - */ - public function testLoadRelationOfSubclass(): void - { - $this->expectException(LoaderException::class); - $this->expectExceptionMessage('Unable to create loader: Undefined relation `human`.`book`.'); - - /** @var Programator $entity */ - (new Select($this->orm, static::HUMAN_ROLE)) - // Load subclass relation - ->load('book') - ->wherePK(2)->fetchOne(); - } - - public function testLoadBaseClassAndCheckSubclassEagerRelations(): void - { - /** @var Programator $entity */ - $entity = (new Select($this->orm, static::HUMAN_ROLE)) - ->wherePK(2)->fetchOne(); - - $this->assertInstanceof(Programator::class, $entity); - /** BOOK_4 */ - $this->assertInstanceof(Book::class, $entity->book); - $this->assertSame(4, $entity->book->id); - /** EBOOK_4 */ - $this->assertInstanceof(EBook::class, $entity->book); - $this->assertSame(static::EBOOK_4['url'], $entity->book->url); - // Check relation eager loading in the book subclass - /** @var EBook $ebook */ - $ebook = $entity->book; - $this->assertEmpty($ebook->pages); - } - - public function testInnerLoadParentClassRelation(): void - { - $this->captureReadQueries(); - - /** @var MarkdownPage $entity */ - $entity = (new Select($this->orm, static::MARKDOWN_PAGE_ROLE)) - ->load('owner', ['method' => Select::SINGLE_QUERY]) - ->wherePK(1)->fetchOne(); - - $this->assertNumReads(2); - - $this->assertInstanceof(MarkdownPage::class, $entity); - $this->assertInstanceof(Programator::class, $entity->owner); - } - - /** - * Inheritance hierarchy should be joined as sub-query - */ - public function testInnerLoadParentClassRelationNullToNull(): void - { - /** @var MarkdownPage $entity */ - $entity = (new Select($this->orm, static::MARKDOWN_PAGE_ROLE)) - ->load('ebook', ['method' => Select::SINGLE_QUERY]) - ->wherePK(5)->fetchOne(); - - $this->assertInstanceof(MarkdownPage::class, $entity); - $this->assertNull($entity->block_id); - $this->assertNull($entity->ebook); - } - - public function testLoadTwoInheritancesInSingleQuery(): void - { - $this->captureReadQueries(); - - /** @var Programator $entity */ - $entity = (new Select($this->orm, static::PROGRAMATOR_ROLE)) - ->load('book', ['method' => Select::SINGLE_QUERY]) - ->load('tech_book', ['method' => Select::SINGLE_QUERY]) - ->load('tech_book.pages', ['method' => Select::SINGLE_QUERY]) - ->wherePK(2)->fetchOne(); - - $this->assertNumReads(1); - $this->captureReadQueries(); - - $this->assertInstanceof(EBook::class, $entity->book); - $this->assertSame(4, $entity->book->id); - $this->assertInstanceof(EBook::class, $entity->tech_book); - $this->assertSame(3, $entity->tech_book->id); - $this->assertNotEmpty($entity->tech_book->pages); - - // Don't use promises - $this->assertNumReads(0); - } - - public function testPersistRelatedHierarchy(): void - { - /** @var Ebook $entity */ - $entity = $this->orm->make(EBook::class, [ - 'title' => 'awesome book', - 'url' => 'awesome-book.com', - 'block_id' => 100, - 'pages' => [], - ]); - $entity->pages = [ - $this->orm->make(Page::class, ['title' => 'page 1', 'content' => '...', 'owner_id' => 1]), - $this->orm->make(Page::class, ['title' => 'page 2', 'content' => '...', 'owner_id' => 1]), - $this->orm->make(MarkdownPage::class, ['title' => 'page 3', 'content' => '...', 'owner_id' => 2]), - ]; - - $this->captureWriteQueries(); - $this->save($entity); - $this->assertNumWrites(6); - - // Relations are not non-rewritable on sync hydration - // This behavior can be changed - $this->assertNull($entity->pages[0]->ebook); - $this->assertNull($entity->pages[1]->ebook); - $this->assertNull($entity->pages[2]->ebook); - - // $this->captureWriteQueries(); - // $this->save($entity); - // $this->assertNumWrites(0); - } - protected function getSchemaArray(): array { return [ diff --git a/tests/ORM/Functional/Driver/Common/Inheritance/JTI/Relation/ParentClassRelationsTest.php b/tests/ORM/Functional/Driver/Common/Inheritance/JTI/Relation/ParentClassRelationsTest.php index 575b03e8..1c78405f 100644 --- a/tests/ORM/Functional/Driver/Common/Inheritance/JTI/Relation/ParentClassRelationsTest.php +++ b/tests/ORM/Functional/Driver/Common/Inheritance/JTI/Relation/ParentClassRelationsTest.php @@ -61,6 +61,59 @@ abstract class ParentClassRelationsTest extends SimpleCasesTest protected const TOOL_ROLE = 'tool'; protected const BOOK_ROLE = 'book'; + /** + * Parent's relation should be initialized + */ + public function testLoadParentRelations(): void + { + /** @var Programator $entity */ + $entity = (new Select($this->orm, static::PROGRAMATOR_ROLE)) + ->load('tech_book') + ->wherePK(2)->fetchOne(); + + $this->assertNotNull($entity->book); + $this->assertNotNull($entity->tech_book); + } + + /** + * Parent's relations should be removed or not removed with their parent + */ + public function testRemoveSubclassWithRelations(): void + { + /** @var Engineer $engineer */ + $engineer = (new Select($this->orm, static::ENGINEER_ROLE)) + ->loadSubclasses(false) + ->wherePK(2)->fetchOne(); + + $this->captureWriteQueries(); + (new Transaction($this->orm))->delete($engineer)->run(); + $this->assertNumWrites(1); + + $this->captureWriteQueries(); + (new Transaction($this->orm))->delete($engineer)->run(); + $this->assertNumWrites(0); + + $this->assertNull( + (new Select($this->orm, static::PROGRAMATOR_ROLE)) + ->wherePK(2) + ->fetchOne(), + ); + $this->assertNull( + (new Select($this->orm, static::ENGINEER_ROLE)) + ->loadSubclasses(false) + ->wherePK(2) + ->fetchOne(), + ); + /** @var Employee $employee */ + $employee = (new Select($this->orm, static::EMPLOYEE_ROLE)) + ->loadSubclasses(false) + ->wherePK(2) + ->fetchOne(); + + $this->assertNotNull($employee); + $this->assertNotNull($employee->book); + } + public function setUp(): void { JtiBaseTest::setUp(); @@ -109,7 +162,7 @@ public function setUp(): void self::TOOL_2, self::TOOL_3, self::TOOL_4, - ] + ], ); $this->getDatabase()->table('book')->insertMultiple( array_keys(static::BOOK_1), @@ -118,7 +171,7 @@ public function setUp(): void self::BOOK_2, self::BOOK_3, self::BOOK_4, - ] + ], ); $this->getDatabase()->table('employee')->insertMultiple( array_keys(static::EMPLOYEE_1), @@ -127,82 +180,29 @@ public function setUp(): void self::EMPLOYEE_2, self::EMPLOYEE_3, self::EMPLOYEE_4, - ] + ], ); $this->getDatabase()->table('engineer')->insertMultiple( array_keys(static::ENGINEER_2), [ self::ENGINEER_2, self::ENGINEER_4, - ] + ], ); $this->getDatabase()->table('programator')->insertMultiple( array_keys(static::PROGRAMATOR_2), [ self::PROGRAMATOR_2, self::PROGRAMATOR_4, - ] + ], ); $this->getDatabase()->table('manager')->insertMultiple( array_keys(static::MANAGER_1), [ self::MANAGER_1, self::MANAGER_3, - ] - ); - } - - /** - * Parent's relation should be initialized - */ - public function testLoadParentRelations(): void - { - /** @var Programator $entity */ - $entity = (new Select($this->orm, static::PROGRAMATOR_ROLE)) - ->load('tech_book') - ->wherePK(2)->fetchOne(); - - $this->assertNotNull($entity->book); - $this->assertNotNull($entity->tech_book); - } - - /** - * Parent's relations should be removed or not removed with their parent - */ - public function testRemoveSubclassWithRelations(): void - { - /** @var Engineer $engineer */ - $engineer = (new Select($this->orm, static::ENGINEER_ROLE)) - ->loadSubclasses(false) - ->wherePK(2)->fetchOne(); - - $this->captureWriteQueries(); - (new Transaction($this->orm))->delete($engineer)->run(); - $this->assertNumWrites(1); - - $this->captureWriteQueries(); - (new Transaction($this->orm))->delete($engineer)->run(); - $this->assertNumWrites(0); - - $this->assertNull( - (new Select($this->orm, static::PROGRAMATOR_ROLE)) - ->wherePK(2) - ->fetchOne() - ); - $this->assertNull( - (new Select($this->orm, static::ENGINEER_ROLE)) - ->loadSubclasses(false) - ->wherePK(2) - ->fetchOne() + ], ); - /** @var Employee $employee */ - $employee = (new Select($this->orm, static::EMPLOYEE_ROLE)) - ->loadSubclasses(false) - ->wherePK(2) - ->fetchOne(); - - $this->assertNotNull($employee); - $this->assertNotNull($employee->book); } protected function getSchemaArray(): array diff --git a/tests/ORM/Functional/Driver/Common/Inheritance/JTI/SimpleCasesTest.php b/tests/ORM/Functional/Driver/Common/Inheritance/JTI/SimpleCasesTest.php index eee69187..b5f6f063 100644 --- a/tests/ORM/Functional/Driver/Common/Inheritance/JTI/SimpleCasesTest.php +++ b/tests/ORM/Functional/Driver/Common/Inheritance/JTI/SimpleCasesTest.php @@ -60,69 +60,6 @@ abstract class SimpleCasesTest extends JtiBaseTest protected const MANAGER_ROLE = 'manager'; protected const PROGRAMATOR_ROLE = 'programator'; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('employee', [ - 'id' => 'integer', - 'name_column' => 'string', - 'age' => 'integer,nullable', - ], pk: ['id']); - $this->makeTable('engineer', [ - 'id' => 'integer', - 'level' => 'integer', - ], fk: [ - 'id' => ['table' => 'employee', 'column' => 'id'], - ], pk: ['id']); - $this->makeTable('programator', [ - 'id' => 'integer', - 'language' => 'string', - ], fk: [ - 'id' => ['table' => 'engineer', 'column' => 'id'], - ], pk: ['id']); - $this->makeTable('manager', [ - 'id' => 'integer', - 'rank' => 'string', - ], fk: [ - 'id' => ['table' => 'employee', 'column' => 'id'], - ], pk: ['id']); - - $this->getDatabase()->table('employee')->insertMultiple( - ['id', 'name_column', 'age'], - [ - self::EMPLOYEE_1, - self::EMPLOYEE_2, - self::EMPLOYEE_3, - self::EMPLOYEE_4, - ] - ); - - $this->getDatabase()->table('engineer')->insertMultiple( - ['id', 'level'], - [ - self::ENGINEER_2, - self::ENGINEER_4, - ] - ); - - $this->getDatabase()->table('programator')->insertMultiple( - ['id', 'language'], - [ - self::PROGRAMATOR_2, - self::PROGRAMATOR_4, - ] - ); - - $this->getDatabase()->table('manager')->insertMultiple( - ['id', 'rank'], - [ - self::MANAGER_1, - self::MANAGER_3, - ] - ); - } - // Select public function testSelectEmployeeHierarchyByPK(): void @@ -374,7 +311,7 @@ public function testRemoveEngineer(): void $this->assertNull( (new Select($this->orm, static::PROGRAMATOR_ROLE)) ->wherePK(static::PROGRAMATOR_2_PK) - ->fetchOne() + ->fetchOne(), ); $this->assertNull((new Select($this->orm, static::ENGINEER_ROLE)) ->loadSubclasses(false) @@ -384,6 +321,69 @@ public function testRemoveEngineer(): void ->wherePK(static::EMPLOYEE_2_PK)->fetchOne()); } + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('employee', [ + 'id' => 'integer', + 'name_column' => 'string', + 'age' => 'integer,nullable', + ], pk: ['id']); + $this->makeTable('engineer', [ + 'id' => 'integer', + 'level' => 'integer', + ], fk: [ + 'id' => ['table' => 'employee', 'column' => 'id'], + ], pk: ['id']); + $this->makeTable('programator', [ + 'id' => 'integer', + 'language' => 'string', + ], fk: [ + 'id' => ['table' => 'engineer', 'column' => 'id'], + ], pk: ['id']); + $this->makeTable('manager', [ + 'id' => 'integer', + 'rank' => 'string', + ], fk: [ + 'id' => ['table' => 'employee', 'column' => 'id'], + ], pk: ['id']); + + $this->getDatabase()->table('employee')->insertMultiple( + ['id', 'name_column', 'age'], + [ + self::EMPLOYEE_1, + self::EMPLOYEE_2, + self::EMPLOYEE_3, + self::EMPLOYEE_4, + ], + ); + + $this->getDatabase()->table('engineer')->insertMultiple( + ['id', 'level'], + [ + self::ENGINEER_2, + self::ENGINEER_4, + ], + ); + + $this->getDatabase()->table('programator')->insertMultiple( + ['id', 'language'], + [ + self::PROGRAMATOR_2, + self::PROGRAMATOR_4, + ], + ); + + $this->getDatabase()->table('manager')->insertMultiple( + ['id', 'rank'], + [ + self::MANAGER_1, + self::MANAGER_3, + ], + ); + } + protected function getSchemaArray(): array { return [ diff --git a/tests/ORM/Functional/Driver/Common/Inheritance/JTI/SingleTableTest.php b/tests/ORM/Functional/Driver/Common/Inheritance/JTI/SingleTableTest.php index 2dfc3ad2..4dab4e9a 100644 --- a/tests/ORM/Functional/Driver/Common/Inheritance/JTI/SingleTableTest.php +++ b/tests/ORM/Functional/Driver/Common/Inheritance/JTI/SingleTableTest.php @@ -57,67 +57,11 @@ abstract class SingleTableTest extends SimpleCasesTest ]; protected const PROGRAMATOR_ALL_LOADED = [self::PROGRAMATOR_2_LOADED, self::PROGRAMATOR_4_LOADED]; protected const MANAGER_ALL_LOADED = [self::MANAGER_1_LOADED, self::MANAGER_3_LOADED]; + // todo: remove when STI will support classless entities and Schema::CHILDREN's roles protected const PROGRAMATOR_ROLE = Programator::class; protected const ENGINEER_ROLE = Engineer::class; - public function setUp(): void - { - JtiBaseTest::setUp(); - - $this->makeTable('employee_table', [ - 'employee_id_column' => 'primary', - 'name_column' => 'string', - 'age' => 'integer,nullable', - ]); - - $this->makeTable('role_table', [ - 'role_id_column' => 'integer,nullable', - 'subrole_id_column' => 'integer,nullable', - 'discriminator' => 'string,nullable', - 'level' => 'integer,nullable', - 'rank' => 'string,nullable', - 'language' => 'string,nullable', - ], fk: [ - 'role_id_column' => ['table' => 'employee_table', 'column' => 'employee_id_column'], - ]); - $this->makeIndex('role_table', ['role_id_column', 'subrole_id_column'], true); - $this->makeFK( - 'role_table', - ['subrole_id_column', 'role_id_column'], - 'role_table', - ['role_id_column', 'subrole_id_column'], - 'NO ACTION', - 'NO ACTION' - ); - - $this->getDatabase()->table('employee_table')->insertMultiple( - ['name_column', 'age'], - \array_map(static fn (array $value): array => \array_diff_key($value, ['employee_id' => 1]), [ - self::EMPLOYEE_1, - self::EMPLOYEE_2, - self::EMPLOYEE_3, - self::EMPLOYEE_4, - ]) - ); - $this->getDatabase()->table('role_table')->insertMultiple( - ['discriminator', 'role_id_column', 'level', 'rank'], - [ - self::MANAGER_1, - self::ENGINEER_2, - self::MANAGER_3, - self::ENGINEER_4, - ] - ); - $this->getDatabase()->table('role_table')->insertMultiple( - ['subrole_id_column', 'language'], - [ - self::PROGRAMATOR_2, - self::PROGRAMATOR_4, - ] - ); - } - public function testFetchAllChildren(): void { /** @var Engineer[]|Manager[] $entities */ @@ -234,6 +178,63 @@ public function testCreateProgramator(): void $this->assertSame('VanillaJS', $programator->language); } + public function setUp(): void + { + JtiBaseTest::setUp(); + + $this->makeTable('employee_table', [ + 'employee_id_column' => 'primary', + 'name_column' => 'string', + 'age' => 'integer,nullable', + ]); + + $this->makeTable('role_table', [ + 'role_id_column' => 'integer,nullable', + 'subrole_id_column' => 'integer,nullable', + 'discriminator' => 'string,nullable', + 'level' => 'integer,nullable', + 'rank' => 'string,nullable', + 'language' => 'string,nullable', + ], fk: [ + 'role_id_column' => ['table' => 'employee_table', 'column' => 'employee_id_column'], + ]); + $this->makeIndex('role_table', ['role_id_column', 'subrole_id_column'], true); + $this->makeFK( + 'role_table', + ['subrole_id_column', 'role_id_column'], + 'role_table', + ['role_id_column', 'subrole_id_column'], + 'NO ACTION', + 'NO ACTION', + ); + + $this->getDatabase()->table('employee_table')->insertMultiple( + ['name_column', 'age'], + \array_map(static fn(array $value): array => \array_diff_key($value, ['employee_id' => 1]), [ + self::EMPLOYEE_1, + self::EMPLOYEE_2, + self::EMPLOYEE_3, + self::EMPLOYEE_4, + ]), + ); + $this->getDatabase()->table('role_table')->insertMultiple( + ['discriminator', 'role_id_column', 'level', 'rank'], + [ + self::MANAGER_1, + self::ENGINEER_2, + self::MANAGER_3, + self::ENGINEER_4, + ], + ); + $this->getDatabase()->table('role_table')->insertMultiple( + ['subrole_id_column', 'language'], + [ + self::PROGRAMATOR_2, + self::PROGRAMATOR_4, + ], + ); + } + protected function getSchemaArray(): array { return [ diff --git a/tests/ORM/Functional/Driver/Common/Inheritance/STI/ManyToManyTest.php b/tests/ORM/Functional/Driver/Common/Inheritance/STI/ManyToManyTest.php index 00215633..6c39245b 100644 --- a/tests/ORM/Functional/Driver/Common/Inheritance/STI/ManyToManyTest.php +++ b/tests/ORM/Functional/Driver/Common/Inheritance/STI/ManyToManyTest.php @@ -15,35 +15,12 @@ use Cycle\ORM\Tests\Functional\Driver\Common\Inheritance\Fixture\RbacItemAbstract; use Cycle\ORM\Tests\Functional\Driver\Common\Inheritance\Fixture\RbacPermission; use Cycle\ORM\Tests\Functional\Driver\Common\Inheritance\Fixture\RbacRole; -use stdClass; abstract class ManyToManyTest extends StiBaseTest { protected const PARENT_MAPPER = Mapper::class; protected const CHILD_MAPPER = StdMapper::class; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('rbac_item', [ - 'name' => 'string,primary', - 'description' => 'string,nullable', - '_type' => 'string,nullable', - ]); - - $this->makeTable('rbac_item_inheritance', [ - 'id' => 'primary', - 'parent' => 'string', - 'child' => 'string', - ]); - - $this->makeFK('rbac_item_inheritance', 'parent', 'rbac_item', 'name', 'NO ACTION', 'NO ACTION'); - $this->makeFK('rbac_item_inheritance', 'child', 'rbac_item', 'name', 'NO ACTION', 'NO ACTION'); - - $this->withSchema(new Schema($this->getSchemaArray())); - } - public function testStore(): void { $role = new RbacRole('superAdmin'); @@ -109,7 +86,7 @@ public function testMakeEntityUsingRole(): void { $this->assertInstanceOf(RbacRole::class, $this->orm->make('rbac_role')); $this->assertInstanceOf(RbacPermission::class, $this->orm->make('rbac_permission')); - $this->assertInstanceOf(stdClass::class, $this->orm->make('rbac_item_inheritance')); + $this->assertInstanceOf(\stdClass::class, $this->orm->make('rbac_item_inheritance')); } public function testMakeUndefinedChildRole(): void @@ -155,6 +132,28 @@ public function testNotTriggersRehydrate(): void $this->orm = $this->orm->withHeap(new Heap()); } + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('rbac_item', [ + 'name' => 'string,primary', + 'description' => 'string,nullable', + '_type' => 'string,nullable', + ]); + + $this->makeTable('rbac_item_inheritance', [ + 'id' => 'primary', + 'parent' => 'string', + 'child' => 'string', + ]); + + $this->makeFK('rbac_item_inheritance', 'parent', 'rbac_item', 'name', 'NO ACTION', 'NO ACTION'); + $this->makeFK('rbac_item_inheritance', 'child', 'rbac_item', 'name', 'NO ACTION', 'NO ACTION'); + + $this->withSchema(new Schema($this->getSchemaArray())); + } + protected function getSchemaArray(): array { return [ diff --git a/tests/ORM/Functional/Driver/Common/Inheritance/STI/SimpleTest.php b/tests/ORM/Functional/Driver/Common/Inheritance/STI/SimpleTest.php index 5dc398a8..d49c017f 100644 --- a/tests/ORM/Functional/Driver/Common/Inheritance/STI/SimpleTest.php +++ b/tests/ORM/Functional/Driver/Common/Inheritance/STI/SimpleTest.php @@ -52,6 +52,7 @@ abstract class SimpleTest extends StiBaseTest self::EMPLOYEE_3_LOADED, self::EMPLOYEE_4_LOADED, ]; + // Filtered on discriminator value protected const EMPLOYEES_LOADED_ALL = [self::EMPLOYEE_2_LOADED, self::EMPLOYEE_4_LOADED]; protected const MANAGERS_LOADED_ALL = [self::EMPLOYEE_1_LOADED, self::EMPLOYEE_3_LOADED]; @@ -61,26 +62,6 @@ abstract class SimpleTest extends StiBaseTest */ protected static string $discriminator = 'discriminator_value'; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('employee_table', [ - static::$discriminator => 'string,nullable', - 'id' => 'primary', - 'name' => 'string', - 'email' => 'string', - 'age' => 'int', - ]); - - $this->getDatabase()->table('employee_table')->insertMultiple( - [static::$discriminator, 'name', 'email', 'age'], - [self::EMPLOYEE_1, self::EMPLOYEE_2, self::EMPLOYEE_3, self::EMPLOYEE_4] - ); - - $this->orm = $this->withSchema(new Schema($this->getSchemaArray())); - } - // Basics public function testFetchBaseData(): void @@ -205,6 +186,26 @@ public function testMultipleDiscriminaorValueOnOneRole(): void $this->assertSame(static::MANAGER_VALUE . '_two', $loadedEntity[0]['_type']); } + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('employee_table', [ + static::$discriminator => 'string,nullable', + 'id' => 'primary', + 'name' => 'string', + 'email' => 'string', + 'age' => 'int', + ]); + + $this->getDatabase()->table('employee_table')->insertMultiple( + [static::$discriminator, 'name', 'email', 'age'], + [self::EMPLOYEE_1, self::EMPLOYEE_2, self::EMPLOYEE_3, self::EMPLOYEE_4], + ); + + $this->orm = $this->withSchema(new Schema($this->getSchemaArray())); + } + protected function getSchemaArray(): array { return [ diff --git a/tests/ORM/Functional/Driver/Common/Inheritance/STI/StiBaseTest.php b/tests/ORM/Functional/Driver/Common/Inheritance/STI/StiBaseTest.php index e2990f4a..3d215801 100644 --- a/tests/ORM/Functional/Driver/Common/Inheritance/STI/StiBaseTest.php +++ b/tests/ORM/Functional/Driver/Common/Inheritance/STI/StiBaseTest.php @@ -24,7 +24,7 @@ public function setUp(): void $this->dbal, RelationConfig::getDefault(), null, - new ArrayCollectionFactory() + new ArrayCollectionFactory(), ))->withCollectionFactory('doctrine', new DoctrineCollectionFactory()); $this->orm = $this->withSchema(new Schema($this->getSchemaArray()))->withFactory($factory); diff --git a/tests/ORM/Functional/Driver/Common/InstantiatorTest.php b/tests/ORM/Functional/Driver/Common/InstantiatorTest.php index ec043948..78e2a385 100644 --- a/tests/ORM/Functional/Driver/Common/InstantiatorTest.php +++ b/tests/ORM/Functional/Driver/Common/InstantiatorTest.php @@ -19,6 +19,27 @@ abstract class InstantiatorTest extends BaseTest { use TableTrait; + public function testInitRelation(): void + { + $u = $this->orm->make(WithConstructor::class); + $this->assertInstanceOf(ArrayCollection::class, $u->comments); + $this->assertNull($u->called); + } + + public function testConstructor(): void + { + $u = new WithConstructor('email'); + + $t = new Transaction($this->orm); + $t->persist($u); + $t->run(); + + $selector = new Select(clone $this->orm, 'user'); + $u = $selector->fetchOne(); + + $this->assertSame('email', $u->email); + } + public function setUp(): void { parent::setUp(); @@ -70,25 +91,4 @@ public function setUp(): void ], ])); } - - public function testInitRelation(): void - { - $u = $this->orm->make(WithConstructor::class); - $this->assertInstanceOf(ArrayCollection::class, $u->comments); - $this->assertNull($u->called); - } - - public function testConstructor(): void - { - $u = new WithConstructor('email'); - - $t = new Transaction($this->orm); - $t->persist($u); - $t->run(); - - $selector = new Select(clone $this->orm, 'user'); - $u = $selector->fetchOne(); - - $this->assertSame('email', $u->email); - } } diff --git a/tests/ORM/Functional/Driver/Common/Integration/Case1/CaseTest.php b/tests/ORM/Functional/Driver/Common/Integration/Case1/CaseTest.php index b397955b..e0402c11 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Case1/CaseTest.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Case1/CaseTest.php @@ -19,13 +19,48 @@ abstract class CaseTest extends BaseTest /** @var User[] */ private array $users = []; + /** @var Tag[] */ private array $tags = []; - private int $iterator = 0; + private int $iterator = 0; private ?float $startTime = null; private array $memories = []; + public function countProvider(): array + { + return [ + '1 item' => [1], + '2 items' => [2], + '10 items' => [10], + '20 items' => [20], + // '50 items' => [50], + ]; + } + + /** + * @dataProvider countProvider + */ + public function testRun(int $count): void + { + $generator = $this->generate($count); + + while ($generator->valid()) { + $this->snapMemory($generator->current()); + $generator->next(); + } + + // Reset state + $this->resetState(false); + $this->orm->getHeap()->clean(); + $this->snapMemory('Clean state'); + + // No errors + $this->assertTrue(true); + + // $this->printDebug(); + } + public function setUp(): void { $this->resetState(); @@ -87,40 +122,6 @@ public function setUp(): void $this->loadSchema(__DIR__ . '/schema.php'); } - public function countProvider(): array - { - return [ - '1 item' => [1], - '2 items' => [2], - '10 items' => [10], - '20 items' => [20], - // '50 items' => [50], - ]; - } - - /** - * @dataProvider countProvider - */ - public function testRun(int $count): void - { - $generator = $this->generate($count); - - while ($generator->valid()) { - $this->snapMemory($generator->current()); - $generator->next(); - } - - // Reset state - $this->resetState(false); - $this->orm->getHeap()->clean(); - $this->snapMemory('Clean state'); - - // No errors - $this->assertTrue(true); - - // $this->printDebug(); - } - /** * @return \Generator */ @@ -189,7 +190,7 @@ private function addPosts(int $count): void $post->setPublishedAt(new \DateTimeImmutable(date('r', random_int(strtotime('-2 years'), time())))); } // link tags - $postTags = (array)array_rand($this->tags, random_int(1, count($this->tags))); + $postTags = (array) array_rand($this->tags, random_int(1, count($this->tags))); foreach ($postTags as $tagId) { $tag = $this->tags[$tagId]; $post->addTag($tag); diff --git a/tests/ORM/Functional/Driver/Common/Integration/Case1/Entity/Comment.php b/tests/ORM/Functional/Driver/Common/Integration/Case1/Entity/Comment.php index 54036433..d58be4bb 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Case1/Entity/Comment.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Case1/Entity/Comment.php @@ -4,30 +4,30 @@ namespace Cycle\ORM\Tests\Functional\Driver\Common\Integration\Case1\Entity; -use DateTimeImmutable; - class Comment { private ?int $id = null; private bool $public = false; private string $content; - private DateTimeImmutable $created_at; - private DateTimeImmutable $updated_at; - private ?DateTimeImmutable $published_at = null; - private ?DateTimeImmutable $deleted_at = null; + private \DateTimeImmutable $created_at; + private \DateTimeImmutable $updated_at; + private ?\DateTimeImmutable $published_at = null; + private ?\DateTimeImmutable $deleted_at = null; private User $user; private ?int $user_id = null; + /** * @var Post */ private $post = null; + private ?int $post_id = null; public function __construct(string $content) { $this->content = $content; - $this->created_at = new DateTimeImmutable(); - $this->updated_at = new DateTimeImmutable(); + $this->created_at = new \DateTimeImmutable(); + $this->updated_at = new \DateTimeImmutable(); } public function getId(): ?int @@ -55,17 +55,17 @@ public function setPublic(bool $public): void $this->public = $public; } - public function getCreatedAt(): DateTimeImmutable + public function getCreatedAt(): \DateTimeImmutable { return $this->created_at; } - public function getUpdatedAt(): DateTimeImmutable + public function getUpdatedAt(): \DateTimeImmutable { return $this->updated_at; } - public function getDeletedAt(): ?DateTimeImmutable + public function getDeletedAt(): ?\DateTimeImmutable { return $this->deleted_at; } @@ -90,12 +90,12 @@ public function getPost(): ?Post return $this->post; } - public function getPublishedAt(): ?DateTimeImmutable + public function getPublishedAt(): ?\DateTimeImmutable { return $this->published_at; } - public function setPublishedAt(?DateTimeImmutable $published_at): void + public function setPublishedAt(?\DateTimeImmutable $published_at): void { $this->published_at = $published_at; } diff --git a/tests/ORM/Functional/Driver/Common/Integration/Case1/Entity/Post.php b/tests/ORM/Functional/Driver/Common/Integration/Case1/Entity/Post.php index 864e9d55..106be599 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Case1/Entity/Post.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Case1/Entity/Post.php @@ -4,8 +4,6 @@ namespace Cycle\ORM\Tests\Functional\Driver\Common\Integration\Case1\Entity; -use DateTimeImmutable; - class Post { private ?int $id = null; @@ -13,17 +11,20 @@ class Post private string $title = ''; private bool $public = false; private string $content = ''; - private DateTimeImmutable $created_at; - private DateTimeImmutable $updated_at; - private ?DateTimeImmutable $published_at = null; - private ?DateTimeImmutable $deleted_at = null; + private \DateTimeImmutable $created_at; + private \DateTimeImmutable $updated_at; + private ?\DateTimeImmutable $published_at = null; + private ?\DateTimeImmutable $deleted_at = null; private User $user; private ?int $user_id = null; + /** * @var Tag[] */ private array $tags = []; + private ?int $tag_id = null; + /** * @var Comment[] */ @@ -33,8 +34,8 @@ public function __construct(string $title = '', string $content = '') { $this->title = $title; $this->content = $content; - $this->created_at = new DateTimeImmutable(); - $this->updated_at = new DateTimeImmutable(); + $this->created_at = new \DateTimeImmutable(); + $this->updated_at = new \DateTimeImmutable(); $this->resetSlug(); } @@ -83,17 +84,17 @@ public function setPublic(bool $public): void $this->public = $public; } - public function getCreatedAt(): DateTimeImmutable + public function getCreatedAt(): \DateTimeImmutable { return $this->created_at; } - public function getUpdatedAt(): DateTimeImmutable + public function getUpdatedAt(): \DateTimeImmutable { return $this->updated_at; } - public function getDeletedAt(): ?DateTimeImmutable + public function getDeletedAt(): ?\DateTimeImmutable { return $this->deleted_at; } @@ -108,12 +109,12 @@ public function getUser(): ?User return $this->user; } - public function getPublishedAt(): ?DateTimeImmutable + public function getPublishedAt(): ?\DateTimeImmutable { return $this->published_at; } - public function setPublishedAt(?DateTimeImmutable $published_at): void + public function setPublishedAt(?\DateTimeImmutable $published_at): void { $this->published_at = $published_at; } diff --git a/tests/ORM/Functional/Driver/Common/Integration/Case1/Entity/Tag.php b/tests/ORM/Functional/Driver/Common/Integration/Case1/Entity/Tag.php index fb944f9d..b5f4f9d9 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Case1/Entity/Tag.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Case1/Entity/Tag.php @@ -4,13 +4,12 @@ namespace Cycle\ORM\Tests\Functional\Driver\Common\Integration\Case1\Entity; -use DateTimeImmutable; - class Tag { private ?int $id = null; private string $label; - private DateTimeImmutable $created_at; + private \DateTimeImmutable $created_at; + /** * @var Post[] */ @@ -19,7 +18,7 @@ class Tag public function __construct(string $label) { $this->label = $label; - $this->created_at = new DateTimeImmutable(); + $this->created_at = new \DateTimeImmutable(); } public function getId(): ?int @@ -37,7 +36,7 @@ public function setLabel(string $label): void $this->label = $label; } - public function getCreatedAt(): DateTimeImmutable + public function getCreatedAt(): \DateTimeImmutable { return $this->created_at; } diff --git a/tests/ORM/Functional/Driver/Common/Integration/Case1/Entity/User.php b/tests/ORM/Functional/Driver/Common/Integration/Case1/Entity/User.php index 549cf1cc..a4517403 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Case1/Entity/User.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Case1/Entity/User.php @@ -4,15 +4,13 @@ namespace Cycle\ORM\Tests\Functional\Driver\Common\Integration\Case1\Entity; -use DateTimeImmutable; - class User { private ?int $id = null; private string $login; private string $passwordHash; - private DateTimeImmutable $created_at; - private DateTimeImmutable $updated_at; + private \DateTimeImmutable $created_at; + private \DateTimeImmutable $updated_at; /** * @var Post[] @@ -27,14 +25,14 @@ class User public function __construct(string $login, string $password) { $this->login = $login; - $this->created_at = new DateTimeImmutable(); - $this->updated_at = new DateTimeImmutable(); + $this->created_at = new \DateTimeImmutable(); + $this->updated_at = new \DateTimeImmutable(); $this->setPassword($password); } public function getId(): ?string { - return $this->id === null ? null : (string)$this->id; + return $this->id === null ? null : (string) $this->id; } public function getLogin(): string @@ -59,12 +57,12 @@ public function setPassword(string $password): void $this->passwordHash = md5($password); } - public function getCreatedAt(): DateTimeImmutable + public function getCreatedAt(): \DateTimeImmutable { return $this->created_at; } - public function getUpdatedAt(): DateTimeImmutable + public function getUpdatedAt(): \DateTimeImmutable { return $this->updated_at; } diff --git a/tests/ORM/Functional/Driver/Common/Integration/Case2/CaseTest.php b/tests/ORM/Functional/Driver/Common/Integration/Case2/CaseTest.php index 99e75400..87d76418 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Case2/CaseTest.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Case2/CaseTest.php @@ -17,6 +17,33 @@ abstract class CaseTest extends BaseTest use IntegrationTestTrait; use TableTrait; + public function testRun(): void + { + $markCriterionResult = (new Select($this->orm, MarkCriterionResult::class)) + ->wherePK('criterion-1') + ->fetchOne(); + \assert($markCriterionResult instanceof MarkCriterionResult); + + $sub = $markCriterionResult + ->markSubcriterionResults + ->filter(static fn(MarkSubcriterionResult $item) => $item->id === 'subcriterion-1') + ->first(); + $aspect = $sub->markAspectResults->first(); + $this->assertNotFalse($aspect); + $student = $aspect->student; + $student->studentProgresses->add(new StudentProgress('new-progress-42')); + + $this->captureWriteQueries(); + $this->save($markCriterionResult, $sub, $aspect); + $this->assertNumWrites(1); + + $this->orm->getHeap()->clean(); + $studentProgress = (new Select($this->orm, StudentProgress::class)) + ->wherePK('new-progress-42') + ->fetchOne(); + $this->assertNotNull($studentProgress); + } + public function setUp(): void { // Init DB @@ -67,64 +94,37 @@ public function setUp(): void [ ['stud-1', 'Kent'], ['stud-2', 'Kant'], - ] + ], ); $this->getDatabase()->table('mark_criterion_results')->insertMultiple( ['id', 'result_objective', 'student_id'], [ ['criterion-1', '24', 'stud-1'], ['criterion-2', '42', 'stud-1'], - ] + ], ); $this->getDatabase()->table('student_progresses')->insertMultiple( ['id', 'aspects_entered_count', 'student_id'], [ ['progress-1', '52', 'stud-1'], ['progress-2', '25', 'stud-1'], - ] + ], ); $this->getDatabase()->table('mark_subcriterion_results')->insertMultiple( ['id', 'result_objective', 'mark_criterion_result_id', 'student_id'], [ ['subcriterion-1', '63', 'criterion-1', 'stud-1'], ['subcriterion-2', '36', 'criterion-1', 'stud-1'], - ] + ], ); $this->getDatabase()->table('mark_aspect_results')->insertMultiple( ['id', 'marks_requires_attention', 'student_id', 'mark_subcriterion_result_id'], [ ['aspect-1', '1', 'stud-1', 'subcriterion-1'], ['aspect-2', '0', 'stud-1', 'subcriterion-1'], - ] + ], ); $this->loadSchema(__DIR__ . '/schema.php'); } - - public function testRun(): void - { - $markCriterionResult = (new Select($this->orm, MarkCriterionResult::class)) - ->wherePK('criterion-1') - ->fetchOne(); - \assert($markCriterionResult instanceof MarkCriterionResult); - - $sub = $markCriterionResult - ->markSubcriterionResults - ->filter(static fn (MarkSubcriterionResult $item) => $item->id === 'subcriterion-1') - ->first(); - $aspect = $sub->markAspectResults->first(); - $this->assertNotFalse($aspect); - $student = $aspect->student; - $student->studentProgresses->add(new StudentProgress('new-progress-42')); - - $this->captureWriteQueries(); - $this->save($markCriterionResult, $sub, $aspect); - $this->assertNumWrites(1); - - $this->orm->getHeap()->clean(); - $studentProgress = (new Select($this->orm, StudentProgress::class)) - ->wherePK('new-progress-42') - ->fetchOne(); - $this->assertNotNull($studentProgress); - } } diff --git a/tests/ORM/Functional/Driver/Common/Integration/Case2/Entity/MarkAspectResult.php b/tests/ORM/Functional/Driver/Common/Integration/Case2/Entity/MarkAspectResult.php index a8c6eb32..eca904ff 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Case2/Entity/MarkAspectResult.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Case2/Entity/MarkAspectResult.php @@ -7,7 +7,6 @@ class MarkAspectResult { public Student $student; - public MarkSubcriterionResult $markSubcriterionResult; public bool $marksRequiresAttention = false; public ?string $student_id = null; @@ -15,6 +14,5 @@ class MarkAspectResult public function __construct( public ?string $id = null, - ) { - } + ) {} } diff --git a/tests/ORM/Functional/Driver/Common/Integration/Case2/Entity/MarkCriterionResult.php b/tests/ORM/Functional/Driver/Common/Integration/Case2/Entity/MarkCriterionResult.php index f4acecbc..f1f8e7ab 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Case2/Entity/MarkCriterionResult.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Case2/Entity/MarkCriterionResult.php @@ -11,7 +11,6 @@ class MarkCriterionResult { public ?string $id = null; public int $resultObjective = 0; - public ?Student $student; public ?string $student_id = null; diff --git a/tests/ORM/Functional/Driver/Common/Integration/Case2/Entity/MarkSubcriterionResult.php b/tests/ORM/Functional/Driver/Common/Integration/Case2/Entity/MarkSubcriterionResult.php index 88676520..befbb662 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Case2/Entity/MarkSubcriterionResult.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Case2/Entity/MarkSubcriterionResult.php @@ -10,7 +10,6 @@ class MarkSubcriterionResult { public ?string $id = null; public int $resultObjective = 0; - public Student $student; public ?string $student_id = null; diff --git a/tests/ORM/Functional/Driver/Common/Integration/Case2/Entity/StudentProgress.php b/tests/ORM/Functional/Driver/Common/Integration/Case2/Entity/StudentProgress.php index 7e2cc821..290a4ee3 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Case2/Entity/StudentProgress.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Case2/Entity/StudentProgress.php @@ -11,6 +11,5 @@ class StudentProgress public function __construct( public ?string $id = null, public int $aspectsEnteredCount = 0, - ) { - } + ) {} } diff --git a/tests/ORM/Functional/Driver/Common/Integration/Case3/CaseTest.php b/tests/ORM/Functional/Driver/Common/Integration/Case3/CaseTest.php index 76eeb5fe..049cce87 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Case3/CaseTest.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Case3/CaseTest.php @@ -15,16 +15,6 @@ abstract class CaseTest extends BaseTest use IntegrationTestTrait; use TableTrait; - public function setUp(): void - { - // Init DB - parent::setUp(); - $this->makeTables(); - $this->fillData(); - - $this->loadSchema(__DIR__ . '/schema.php'); - } - public function testSave(): void { // Get entity @@ -47,6 +37,16 @@ public function testSave(): void $this->assertSame('eur', $user->currency->code); } + public function setUp(): void + { + // Init DB + parent::setUp(); + $this->makeTables(); + $this->fillData(); + + $this->loadSchema(__DIR__ . '/schema.php'); + } + private function makeTables(): void { // Make tables diff --git a/tests/ORM/Functional/Driver/Common/Integration/Case3/Entity/Currency.php b/tests/ORM/Functional/Driver/Common/Integration/Case3/Entity/Currency.php index 1eebf5d8..a6cbb4b9 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Case3/Entity/Currency.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Case3/Entity/Currency.php @@ -8,7 +8,6 @@ class Currency { public function __construct( public string $code, - public string $name - ) { - } + public string $name, + ) {} } diff --git a/tests/ORM/Functional/Driver/Common/Integration/Case318/CaseTest.php b/tests/ORM/Functional/Driver/Common/Integration/Case318/CaseTest.php index 1368c0c1..52f1fcee 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Case318/CaseTest.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Case318/CaseTest.php @@ -17,15 +17,6 @@ abstract class CaseTest extends BaseTest use IntegrationTestTrait; use TableTrait; - public function setUp(): void - { - // Init DB - parent::setUp(); - $this->makeTables(); - - $this->loadSchema(__DIR__ . '/schema.php'); - } - public function testSelect(): void { $groupUuid = Uuid::uuid4(); @@ -51,6 +42,15 @@ public function testSelect(): void $this->assertEquals($groupUuid, $groups[0]->uuid); } + public function setUp(): void + { + // Init DB + parent::setUp(); + $this->makeTables(); + + $this->loadSchema(__DIR__ . '/schema.php'); + } + private function makeTables(): void { // Make tables diff --git a/tests/ORM/Functional/Driver/Common/Integration/Case318/Entity/UserGroup.php b/tests/ORM/Functional/Driver/Common/Integration/Case318/Entity/UserGroup.php index 302836c9..cf16f76c 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Case318/Entity/UserGroup.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Case318/Entity/UserGroup.php @@ -9,7 +9,6 @@ class UserGroup { public UuidInterface $uuid; - public UuidInterface $user_id; public UuidInterface $group_id; } diff --git a/tests/ORM/Functional/Driver/Common/Integration/Case318/Typecast.php b/tests/ORM/Functional/Driver/Common/Integration/Case318/Typecast.php index 0fa82288..478a45aa 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Case318/Typecast.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Case318/Typecast.php @@ -34,7 +34,7 @@ public function cast(array $data): array } $data[$column] = match ($rule) { 'uuid' => Uuid::fromString($data[$column]), - default => $data[$column] + default => $data[$column], }; } @@ -50,7 +50,7 @@ public function uncast(array $data): array $data[$column] = match ($rule) { 'uuid' => $data[$column] instanceof UuidInterface ? $data[$column]->toString() : $data[$column], - default => (string) $data[$column] + default => (string) $data[$column], }; } diff --git a/tests/ORM/Functional/Driver/Common/Integration/Case321/CaseTest.php b/tests/ORM/Functional/Driver/Common/Integration/Case321/CaseTest.php index 00c4c3f3..5062adc9 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Case321/CaseTest.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Case321/CaseTest.php @@ -13,15 +13,6 @@ abstract class CaseTest extends BaseTest use IntegrationTestTrait; use TableTrait; - public function setUp(): void - { - // Init DB - parent::setUp(); - $this->makeTables(); - - $this->loadSchema(__DIR__ . '/schema.php'); - } - public function test1(): void { $user = new Entity\User1(); @@ -69,6 +60,15 @@ public function test4(): void $this->assertNumWrites(0); } + public function setUp(): void + { + // Init DB + parent::setUp(); + $this->makeTables(); + + $this->loadSchema(__DIR__ . '/schema.php'); + } + private function makeTables(): void { // Make tables diff --git a/tests/ORM/Functional/Driver/Common/Integration/Case346/CaseTest.php b/tests/ORM/Functional/Driver/Common/Integration/Case346/CaseTest.php index c6324da3..2b39ae08 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Case346/CaseTest.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Case346/CaseTest.php @@ -14,16 +14,6 @@ abstract class CaseTest extends BaseTest use IntegrationTestTrait; use TableTrait; - public function setUp(): void - { - // Init DB - parent::setUp(); - $this->makeTables(); - $this->fillData(); - - $this->loadSchema(__DIR__ . '/schema.php'); - } - public function testSelect(): void { /** @var Entity\Post $post */ @@ -42,6 +32,16 @@ public function testSelect(): void $this->orm->getHeap()->clean(); } + public function setUp(): void + { + // Init DB + parent::setUp(); + $this->makeTables(); + $this->fillData(); + + $this->loadSchema(__DIR__ . '/schema.php'); + } + private function makeTables(): void { // Make tables diff --git a/tests/ORM/Functional/Driver/Common/Integration/Case346/Entity/Post.php b/tests/ORM/Functional/Driver/Common/Integration/Case346/Entity/Post.php index 852069d4..12792db5 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Case346/Entity/Post.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Case346/Entity/Post.php @@ -4,8 +4,6 @@ namespace Cycle\ORM\Tests\Functional\Driver\Common\Integration\Case346\Entity; -use DateTimeImmutable; - class Post { public ?int $id = null; @@ -13,10 +11,10 @@ class Post public string $title = ''; public bool $public = false; public string $content = ''; - public DateTimeImmutable $created_at; - public DateTimeImmutable $updated_at; - public ?DateTimeImmutable $published_at = null; - public ?DateTimeImmutable $deleted_at = null; + public \DateTimeImmutable $created_at; + public \DateTimeImmutable $updated_at; + public ?\DateTimeImmutable $published_at = null; + public ?\DateTimeImmutable $deleted_at = null; public User $user; public ?int $user_id = null; @@ -24,8 +22,8 @@ public function __construct(string $title = '', string $content = '') { $this->title = $title; $this->content = $content; - $this->created_at = new DateTimeImmutable(); - $this->updated_at = new DateTimeImmutable(); + $this->created_at = new \DateTimeImmutable(); + $this->updated_at = new \DateTimeImmutable(); $this->resetSlug(); } diff --git a/tests/ORM/Functional/Driver/Common/Integration/Case346/Entity/User.php b/tests/ORM/Functional/Driver/Common/Integration/Case346/Entity/User.php index 355e998e..6b2d8890 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Case346/Entity/User.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Case346/Entity/User.php @@ -4,23 +4,22 @@ namespace Cycle\ORM\Tests\Functional\Driver\Common\Integration\Case346\Entity; -use DateTimeImmutable; - class User { public const ROLE = 'user'; public ?int $id = null; public string $login; - public DateTimeImmutable $created_at; - public DateTimeImmutable $updated_at; + public \DateTimeImmutable $created_at; + public \DateTimeImmutable $updated_at; + /** @var iterable */ public iterable $posts = []; public function __construct(string $login, string $password) { $this->login = $login; - $this->created_at = new DateTimeImmutable(); - $this->updated_at = new DateTimeImmutable(); + $this->created_at = new \DateTimeImmutable(); + $this->updated_at = new \DateTimeImmutable(); } } diff --git a/tests/ORM/Functional/Driver/Common/Integration/Case383/CaseTest.php b/tests/ORM/Functional/Driver/Common/Integration/Case383/CaseTest.php index ce9ede44..81867f92 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Case383/CaseTest.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Case383/CaseTest.php @@ -13,27 +13,6 @@ abstract class CaseTest extends BaseTest use IntegrationTestTrait; use TableTrait; - public function setUp(): void - { - $this->applyDriverOptions(static::$config[static::DRIVER], ['withDatetimeMicroseconds' => true]); - - // Init DB - parent::setUp(); - - $this->makeTables(); - $this->fillData(); - - $this->loadSchema(__DIR__ . '/schema.php'); - } - - public function tearDown(): void - { - parent::tearDown(); - - $this->applyDriverOptions(static::$config[static::DRIVER], ['withDatetimeMicroseconds' => false]); - $this->driver = null; - } - public function test1WithClean(): void { $user = new Entity\User('test', 'test'); @@ -55,6 +34,27 @@ public function test2WithoutClean(): void $this->assertEquals($user->id, $get_user->id); } + public function setUp(): void + { + $this->applyDriverOptions(static::$config[static::DRIVER], ['withDatetimeMicroseconds' => true]); + + // Init DB + parent::setUp(); + + $this->makeTables(); + $this->fillData(); + + $this->loadSchema(__DIR__ . '/schema.php'); + } + + public function tearDown(): void + { + parent::tearDown(); + + $this->applyDriverOptions(static::$config[static::DRIVER], ['withDatetimeMicroseconds' => false]); + $this->driver = null; + } + private function makeTables(): void { // Make tables diff --git a/tests/ORM/Functional/Driver/Common/Integration/Case383/Entity/Comment.php b/tests/ORM/Functional/Driver/Common/Integration/Case383/Entity/Comment.php index 1690bf43..9236c7be 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Case383/Entity/Comment.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Case383/Entity/Comment.php @@ -4,17 +4,15 @@ namespace Cycle\ORM\Tests\Functional\Driver\Common\Integration\Case383\Entity; -use DateTimeImmutable; - class Comment { public ?int $id = null; public bool $public = false; public string $content; - public DateTimeImmutable $created_at; - public DateTimeImmutable $updated_at; - public ?DateTimeImmutable $published_at = null; - public ?DateTimeImmutable $deleted_at = null; + public \DateTimeImmutable $created_at; + public \DateTimeImmutable $updated_at; + public ?\DateTimeImmutable $published_at = null; + public ?\DateTimeImmutable $deleted_at = null; public User $user; public ?int $user_id = null; public ?Post $post = null; @@ -23,7 +21,7 @@ class Comment public function __construct(string $content) { $this->content = $content; - $this->created_at = new DateTimeImmutable(); - $this->updated_at = new DateTimeImmutable(); + $this->created_at = new \DateTimeImmutable(); + $this->updated_at = new \DateTimeImmutable(); } } diff --git a/tests/ORM/Functional/Driver/Common/Integration/Case383/Entity/Post.php b/tests/ORM/Functional/Driver/Common/Integration/Case383/Entity/Post.php index 35ddb3d5..839d26ef 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Case383/Entity/Post.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Case383/Entity/Post.php @@ -4,8 +4,6 @@ namespace Cycle\ORM\Tests\Functional\Driver\Common\Integration\Case383\Entity; -use DateTimeImmutable; - class Post { public ?int $id = null; @@ -13,15 +11,18 @@ class Post public string $title = ''; public bool $public = false; public string $content = ''; - public DateTimeImmutable $created_at; - public DateTimeImmutable $updated_at; - public ?DateTimeImmutable $published_at = null; - public ?DateTimeImmutable $deleted_at = null; + public \DateTimeImmutable $created_at; + public \DateTimeImmutable $updated_at; + public ?\DateTimeImmutable $published_at = null; + public ?\DateTimeImmutable $deleted_at = null; public User $user; public ?int $user_id = null; + /** @var iterable */ public iterable $tags = []; + public ?int $tag_id = null; + /** @var iterable */ public iterable $comments = []; @@ -29,8 +30,8 @@ public function __construct(string $title = '', string $content = '') { $this->title = $title; $this->content = $content; - $this->created_at = new DateTimeImmutable(); - $this->updated_at = new DateTimeImmutable(); + $this->created_at = new \DateTimeImmutable(); + $this->updated_at = new \DateTimeImmutable(); $this->resetSlug(); } diff --git a/tests/ORM/Functional/Driver/Common/Integration/Case383/Entity/Tag.php b/tests/ORM/Functional/Driver/Common/Integration/Case383/Entity/Tag.php index 3696588b..d2945b0b 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Case383/Entity/Tag.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Case383/Entity/Tag.php @@ -4,19 +4,18 @@ namespace Cycle\ORM\Tests\Functional\Driver\Common\Integration\Case383\Entity; -use DateTimeImmutable; - class Tag { public ?int $id = null; public string $label; - public DateTimeImmutable $created_at; + public \DateTimeImmutable $created_at; + /** @var iterable */ public iterable $posts = []; public function __construct(string $label) { $this->label = $label; - $this->created_at = new DateTimeImmutable(); + $this->created_at = new \DateTimeImmutable(); } } diff --git a/tests/ORM/Functional/Driver/Common/Integration/Case383/Entity/User.php b/tests/ORM/Functional/Driver/Common/Integration/Case383/Entity/User.php index 96a6ae75..174c8200 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Case383/Entity/User.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Case383/Entity/User.php @@ -4,8 +4,6 @@ namespace Cycle\ORM\Tests\Functional\Driver\Common\Integration\Case383\Entity; -use DateTimeImmutable; - class User { public const ROLE = 'user'; @@ -13,18 +11,20 @@ class User public ?int $id = null; public string $login; public string $passwordHash; - public DateTimeImmutable $created_at; - public DateTimeImmutable $updated_at; + public \DateTimeImmutable $created_at; + public \DateTimeImmutable $updated_at; + /** @var iterable */ public iterable $posts = []; + /** @var iterable */ public iterable $comments = []; public function __construct(string $login, string $password) { $this->login = $login; - $this->created_at = new DateTimeImmutable(); - $this->updated_at = new DateTimeImmutable(); + $this->created_at = new \DateTimeImmutable(); + $this->updated_at = new \DateTimeImmutable(); $this->setPassword($password); } diff --git a/tests/ORM/Functional/Driver/Common/Integration/Case398/CaseTest.php b/tests/ORM/Functional/Driver/Common/Integration/Case398/CaseTest.php index 8ae84563..64c0094d 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Case398/CaseTest.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Case398/CaseTest.php @@ -16,15 +16,6 @@ abstract class CaseTest extends BaseTest use IntegrationTestTrait; use TableTrait; - public function setUp(): void - { - parent::setUp(); - $this->makeTables(); - $this->fillData(); - - $this->loadSchema(__DIR__ . '/schema.php'); - } - public function testSelectWithJoin(): void { $select = new Select($this->orm, Product::class); @@ -80,6 +71,15 @@ public function testSelectWithFullJoin(): void $this->assertSame('Product-2', $product->title); } + public function setUp(): void + { + parent::setUp(); + $this->makeTables(); + $this->fillData(); + + $this->loadSchema(__DIR__ . '/schema.php'); + } + private function makeTables(): void { $this->makeTable('products', [ diff --git a/tests/ORM/Functional/Driver/Common/Integration/Case398/Entity/FilterProduct.php b/tests/ORM/Functional/Driver/Common/Integration/Case398/Entity/FilterProduct.php index 3a155cf1..8dde9133 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Case398/Entity/FilterProduct.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Case398/Entity/FilterProduct.php @@ -11,6 +11,5 @@ class FilterProduct public function __construct( public int $productId, public int $filterId, - ) { - } + ) {} } diff --git a/tests/ORM/Functional/Driver/Common/Integration/Case398/Entity/Product.php b/tests/ORM/Functional/Driver/Common/Integration/Case398/Entity/Product.php index 7a78caaa..21dd48be 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Case398/Entity/Product.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Case398/Entity/Product.php @@ -12,6 +12,5 @@ class Product public function __construct( public string $title, - ) { - } + ) {} } diff --git a/tests/ORM/Functional/Driver/Common/Integration/Case4/CaseTest.php b/tests/ORM/Functional/Driver/Common/Integration/Case4/CaseTest.php index 0debd6f2..4ee145d8 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Case4/CaseTest.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Case4/CaseTest.php @@ -17,6 +17,21 @@ abstract class CaseTest extends BaseTest use IntegrationTestTrait; use TableTrait; + public function testSelect(): void + { + $model = (new Select($this->orm, Entity\Node::class)) + ->wherePK(2) + ->fetchOne(); + + $this->save($model); + + $model = (new Select($this->orm, Entity\Node::class)) + ->wherePK(3) + ->fetchOne(); + + $this->save($model); + } + public function setUp(): void { // Init DB @@ -40,19 +55,4 @@ public function setUp(): void ], ); } - - public function testSelect(): void - { - $model = (new Select($this->orm, Entity\Node::class)) - ->wherePK(2) - ->fetchOne(); - - $this->save($model); - - $model = (new Select($this->orm, Entity\Node::class)) - ->wherePK(3) - ->fetchOne(); - - $this->save($model); - } } diff --git a/tests/ORM/Functional/Driver/Common/Integration/Case4/Entity/Node.php b/tests/ORM/Functional/Driver/Common/Integration/Case4/Entity/Node.php index a46cc494..dd082e87 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Case4/Entity/Node.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Case4/Entity/Node.php @@ -7,8 +7,6 @@ class Node { private int $id; - private string $key; - private ?self $parent = null; } diff --git a/tests/ORM/Functional/Driver/Common/Integration/Case408/CaseTest.php b/tests/ORM/Functional/Driver/Common/Integration/Case408/CaseTest.php index 0cf37ff3..d470b6b0 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Case408/CaseTest.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Case408/CaseTest.php @@ -15,16 +15,6 @@ abstract class CaseTest extends BaseTest use IntegrationTestTrait; use TableTrait; - public function setUp(): void - { - // Init DB - parent::setUp(); - $this->makeTables(); - $this->fillData(); - - $this->loadSchema(__DIR__ . '/schema.php'); - } - public function testSelectHasMany(): void { // Get entity @@ -47,6 +37,16 @@ public function testSelectManyManyToMany(): void self::assertCount(2, $group->getManyTargets()); } + public function setUp(): void + { + // Init DB + parent::setUp(); + $this->makeTables(); + $this->fillData(); + + $this->loadSchema(__DIR__ . '/schema.php'); + } + private function makeTables(): void { // Make tables diff --git a/tests/ORM/Functional/Driver/Common/Integration/Case408/Entity/TargetGroup.php b/tests/ORM/Functional/Driver/Common/Integration/Case408/Entity/TargetGroup.php index 7faba122..f47e5cd8 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Case408/Entity/TargetGroup.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Case408/Entity/TargetGroup.php @@ -11,7 +11,6 @@ class TargetGroup { private ?TargetGroupId $id = null; private TargetGroupName $name; - private iterable $targets = []; private iterable $manyTargets = []; diff --git a/tests/ORM/Functional/Driver/Common/Integration/Case408/Type/IntegerTrait.php b/tests/ORM/Functional/Driver/Common/Integration/Case408/Type/IntegerTrait.php index 108a2b1e..019c5eba 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Case408/Type/IntegerTrait.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Case408/Type/IntegerTrait.php @@ -8,8 +8,7 @@ trait IntegerTrait { private function __construct( private int $id, - ) { - } + ) {} public static function create(int|string $id): self { diff --git a/tests/ORM/Functional/Driver/Common/Integration/Case408/Type/StringTrait.php b/tests/ORM/Functional/Driver/Common/Integration/Case408/Type/StringTrait.php index 58832725..8c746d1d 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Case408/Type/StringTrait.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Case408/Type/StringTrait.php @@ -8,8 +8,7 @@ trait StringTrait { private function __construct( private string $id, - ) { - } + ) {} public static function create(int|string $id): self { diff --git a/tests/ORM/Functional/Driver/Common/Integration/Case408/Type/ValueObjectInterface.php b/tests/ORM/Functional/Driver/Common/Integration/Case408/Type/ValueObjectInterface.php index ed39d981..85a0a381 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Case408/Type/ValueObjectInterface.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Case408/Type/ValueObjectInterface.php @@ -4,9 +4,7 @@ namespace Cycle\ORM\Tests\Functional\Driver\Common\Integration\Case408\Type; -use Stringable; - -interface ValueObjectInterface extends Stringable +interface ValueObjectInterface extends \Stringable { public static function create(string $id): self; } diff --git a/tests/ORM/Functional/Driver/Common/Integration/Case416/CaseTest.php b/tests/ORM/Functional/Driver/Common/Integration/Case416/CaseTest.php index d9e8dad7..cea71f82 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Case416/CaseTest.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Case416/CaseTest.php @@ -18,15 +18,6 @@ abstract class CaseTest extends BaseTest use IntegrationTestTrait; use TableTrait; - public function setUp(): void - { - // Init DB - parent::setUp(); - $this->makeTables(); - - $this->loadSchema(__DIR__ . '/schema.php'); - } - public function testSelect(): void { $uuid = Uuid::uuid7(); @@ -44,7 +35,7 @@ public function testSelect(): void // Get entity (new Select($this->orm, Entity\Account::class)) ->load('identity.profile') - ->wherePK((string)$uuid) + ->wherePK((string) $uuid) ->fetchOne(); // There is no any exception like this: @@ -61,6 +52,15 @@ public function testSelect(): void $this->orm->getHeap()->clean(); } + public function setUp(): void + { + // Init DB + parent::setUp(); + $this->makeTables(); + + $this->loadSchema(__DIR__ . '/schema.php'); + } + private function makeTables(): void { $this->makeTable(Entity\Identity::ROLE, [ diff --git a/tests/ORM/Functional/Driver/Common/Integration/Case416/Entity/Account.php b/tests/ORM/Functional/Driver/Common/Integration/Case416/Entity/Account.php index 6a4b8496..152985de 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Case416/Entity/Account.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Case416/Entity/Account.php @@ -4,20 +4,18 @@ namespace Cycle\ORM\Tests\Functional\Driver\Common\Integration\Case416\Entity; -use DateTimeInterface; use Ramsey\Uuid\UuidInterface; class Account { public const ROLE = 'account'; - public const F_UUID = 'uuid'; public const F_EMAIL = 'email'; public const F_PASSWORD_HASH = 'passwordHash'; public const F_UPDATED_AT = 'updatedAt'; /** @readonly */ - public DateTimeInterface $updatedAt; + public \DateTimeInterface $updatedAt; public Identity $identity; diff --git a/tests/ORM/Functional/Driver/Common/Integration/Case416/Entity/Identity.php b/tests/ORM/Functional/Driver/Common/Integration/Case416/Entity/Identity.php index 36c831ff..e840fae3 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Case416/Entity/Identity.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Case416/Entity/Identity.php @@ -4,27 +4,26 @@ namespace Cycle\ORM\Tests\Functional\Driver\Common\Integration\Case416\Entity; -use DateTimeInterface; use Ramsey\Uuid\UuidInterface; class Identity { public const ROLE = 'identity'; - public const F_UUID = 'uuid'; public const F_CREATED_AT = 'createdAt'; public const F_UPDATED_AT = 'updatedAt'; public const F_DELETED_AT = 'deletedAt'; /** @readonly */ - public DateTimeInterface $createdAt; + public \DateTimeInterface $createdAt; + /** @readonly */ - public DateTimeInterface $updatedAt; + public \DateTimeInterface $updatedAt; + /** @readonly */ - public ?DateTimeInterface $deletedAt = null; + public ?\DateTimeInterface $deletedAt = null; public Profile $profile; - public Account $account; public function __construct( diff --git a/tests/ORM/Functional/Driver/Common/Integration/Case416/Entity/Profile.php b/tests/ORM/Functional/Driver/Common/Integration/Case416/Entity/Profile.php index b758b6ac..5116782d 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Case416/Entity/Profile.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Case416/Entity/Profile.php @@ -4,18 +4,16 @@ namespace Cycle\ORM\Tests\Functional\Driver\Common\Integration\Case416\Entity; -use DateTimeInterface; use Ramsey\Uuid\UuidInterface; class Profile { public const ROLE = 'profile'; - public const F_UUID = 'uuid'; public const F_UPDATED_AT = 'updatedAt'; /** @readonly */ - public DateTimeInterface $updatedAt; + public \DateTimeInterface $updatedAt; /** @psalm-suppress InvalidArgument */ public UserName $name; diff --git a/tests/ORM/Functional/Driver/Common/Integration/Case416/Entity/UserName.php b/tests/ORM/Functional/Driver/Common/Integration/Case416/Entity/UserName.php index c9755cde..84c9f1c1 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Case416/Entity/UserName.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Case416/Entity/UserName.php @@ -7,13 +7,11 @@ class UserName { public const ROLE = 'UserName'; - public const F_FIRST_NAME = 'firstName'; public const F_LAST_NAME = 'lastName'; public function __construct( public string $firstName = '', public string $lastName = '', - ) { - } + ) {} } diff --git a/tests/ORM/Functional/Driver/Common/Integration/Case427/CaseTest.php b/tests/ORM/Functional/Driver/Common/Integration/Case427/CaseTest.php index e2264d54..c0fd6033 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Case427/CaseTest.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Case427/CaseTest.php @@ -19,6 +19,30 @@ abstract class CaseTest extends BaseTest use IntegrationTestTrait; use TableTrait; + public function testSelect(): void + { + $buyer = (new Select($this->orm, Buyer::class)) + ->wherePK(4) + ->fetchOne(); + + $this->assertInstanceOf(Buyer::class, $buyer); + $this->assertSame(4, $buyer->id); + $this->assertSame('foo', $buyer->address); + + $this->assertCount(2, $buyer->partners); + + $user1 = $buyer->partners[0]; + $user2 = $buyer->partners[1]; + + \assert($user1 instanceof User); + \assert($user2 instanceof User); + + $this->assertSame('00000000-0000-0000-0000-000000000001', $user1->id->toString()); + $this->assertSame('00000000-0000-0000-0000-000000000002', $user2->id->toString()); + $this->assertSame('John', $user1->name); + $this->assertSame('Sam', $user2->name); + } + public function setUp(): void { // Init DB @@ -61,28 +85,4 @@ public function setUp(): void [[4, '00000000-0000-0000-0000-000000000001'], [4, '00000000-0000-0000-0000-000000000002']], ); } - - public function testSelect(): void - { - $buyer = (new Select($this->orm, Buyer::class)) - ->wherePK(4) - ->fetchOne(); - - $this->assertInstanceOf(Buyer::class, $buyer); - $this->assertSame(4, $buyer->id); - $this->assertSame('foo', $buyer->address); - - $this->assertCount(2, $buyer->partners); - - $user1 = $buyer->partners[0]; - $user2 = $buyer->partners[1]; - - \assert($user1 instanceof User); - \assert($user2 instanceof User); - - $this->assertSame('00000000-0000-0000-0000-000000000001', $user1->id->toString()); - $this->assertSame('00000000-0000-0000-0000-000000000002', $user2->id->toString()); - $this->assertSame('John', $user1->name); - $this->assertSame('Sam', $user2->name); - } } diff --git a/tests/ORM/Functional/Driver/Common/Integration/Case427/Entity/Buyer.php b/tests/ORM/Functional/Driver/Common/Integration/Case427/Entity/Buyer.php index 52f5e0f7..401e3847 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Case427/Entity/Buyer.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Case427/Entity/Buyer.php @@ -11,6 +11,5 @@ class Buyer public function __construct( public int $id, public string $address, - ) { - } + ) {} } diff --git a/tests/ORM/Functional/Driver/Common/Integration/Case427/UuidTypecast.php b/tests/ORM/Functional/Driver/Common/Integration/Case427/UuidTypecast.php index d95a5ad9..dade5093 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Case427/UuidTypecast.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Case427/UuidTypecast.php @@ -55,7 +55,7 @@ public function uncast(array $data): array TestCase::fail(\sprintf( 'Expected UuidInterface, got %s: %s', \get_debug_type($data[$column]), - \print_r($data[$column], true) + \print_r($data[$column], true), )); } diff --git a/tests/ORM/Functional/Driver/Common/Integration/Case5/CaseTest.php b/tests/ORM/Functional/Driver/Common/Integration/Case5/CaseTest.php index 0dd6a329..4e8cabd3 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Case5/CaseTest.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Case5/CaseTest.php @@ -15,6 +15,24 @@ abstract class CaseTest extends BaseTest use IntegrationTestTrait; use TableTrait; + public function testSelect(): void + { + /** @var Buyer $buyer */ + $buyer = (new Select($this->orm, Buyer::class)) + ->wherePK(1) + ->fetchOne(); + + // It's important. $buyer->partners - will trigger relation load and we test it + $this->assertTrue($buyer->partners->exists(function (int $key, Buyer $element): bool { + return $element->id === 2; + })); + $this->assertTrue($buyer->partners->exists(function (int $key, Buyer $element): bool { + return $element->id === 3; + })); + $this->assertCount(2, $buyer->partners); + $this->assertSame('lab', $buyer->badge->label); + } + public function setUp(): void { // Init DB @@ -61,22 +79,4 @@ public function setUp(): void [[1, 2], [1, 3]], ); } - - public function testSelect(): void - { - /** @var Buyer $buyer */ - $buyer = (new Select($this->orm, Buyer::class)) - ->wherePK(1) - ->fetchOne(); - - // It's important. $buyer->partners - will trigger relation load and we test it - $this->assertTrue($buyer->partners->exists(function (int $key, Buyer $element): bool { - return $element->id === 2; - })); - $this->assertTrue($buyer->partners->exists(function (int $key, Buyer $element): bool { - return $element->id === 3; - })); - $this->assertCount(2, $buyer->partners); - $this->assertSame('lab', $buyer->badge->label); - } } diff --git a/tests/ORM/Functional/Driver/Common/Integration/Case5/Entity/Badge.php b/tests/ORM/Functional/Driver/Common/Integration/Case5/Entity/Badge.php index b35d02f6..deb13f7a 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Case5/Entity/Badge.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Case5/Entity/Badge.php @@ -9,6 +9,5 @@ class Badge public function __construct( public int $id, public string $label, - ) { - } + ) {} } diff --git a/tests/ORM/Functional/Driver/Common/Integration/CaseTemplate/CaseTest.php b/tests/ORM/Functional/Driver/Common/Integration/CaseTemplate/CaseTest.php index 5c33e132..511f57f4 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/CaseTemplate/CaseTest.php +++ b/tests/ORM/Functional/Driver/Common/Integration/CaseTemplate/CaseTest.php @@ -14,16 +14,6 @@ abstract class CaseTest extends BaseTest use IntegrationTestTrait; use TableTrait; - public function setUp(): void - { - // Init DB - parent::setUp(); - $this->makeTables(); - $this->fillData(); - - $this->loadSchema(__DIR__ . '/schema.php'); - } - public function testSelect(): void { // Get entity @@ -54,6 +44,16 @@ public function testSave(): void $this->assertNumWrites(1); } + public function setUp(): void + { + // Init DB + parent::setUp(); + $this->makeTables(); + $this->fillData(); + + $this->loadSchema(__DIR__ . '/schema.php'); + } + private function makeTables(): void { // Make tables diff --git a/tests/ORM/Functional/Driver/Common/Integration/CaseTemplate/Entity/Comment.php b/tests/ORM/Functional/Driver/Common/Integration/CaseTemplate/Entity/Comment.php index 28ae9d67..64e6a1ef 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/CaseTemplate/Entity/Comment.php +++ b/tests/ORM/Functional/Driver/Common/Integration/CaseTemplate/Entity/Comment.php @@ -4,17 +4,15 @@ namespace Cycle\ORM\Tests\Functional\Driver\Common\Integration\CaseTemplate\Entity; -use DateTimeImmutable; - class Comment { public ?int $id = null; public bool $public = false; public string $content; - public DateTimeImmutable $created_at; - public DateTimeImmutable $updated_at; - public ?DateTimeImmutable $published_at = null; - public ?DateTimeImmutable $deleted_at = null; + public \DateTimeImmutable $created_at; + public \DateTimeImmutable $updated_at; + public ?\DateTimeImmutable $published_at = null; + public ?\DateTimeImmutable $deleted_at = null; public User $user; public ?int $user_id = null; public ?Post $post = null; @@ -23,7 +21,7 @@ class Comment public function __construct(string $content) { $this->content = $content; - $this->created_at = new DateTimeImmutable(); - $this->updated_at = new DateTimeImmutable(); + $this->created_at = new \DateTimeImmutable(); + $this->updated_at = new \DateTimeImmutable(); } } diff --git a/tests/ORM/Functional/Driver/Common/Integration/CaseTemplate/Entity/Post.php b/tests/ORM/Functional/Driver/Common/Integration/CaseTemplate/Entity/Post.php index ee8ec059..84ef7343 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/CaseTemplate/Entity/Post.php +++ b/tests/ORM/Functional/Driver/Common/Integration/CaseTemplate/Entity/Post.php @@ -4,8 +4,6 @@ namespace Cycle\ORM\Tests\Functional\Driver\Common\Integration\CaseTemplate\Entity; -use DateTimeImmutable; - class Post { public ?int $id = null; @@ -13,15 +11,18 @@ class Post public string $title = ''; public bool $public = false; public string $content = ''; - public DateTimeImmutable $created_at; - public DateTimeImmutable $updated_at; - public ?DateTimeImmutable $published_at = null; - public ?DateTimeImmutable $deleted_at = null; + public \DateTimeImmutable $created_at; + public \DateTimeImmutable $updated_at; + public ?\DateTimeImmutable $published_at = null; + public ?\DateTimeImmutable $deleted_at = null; public User $user; public ?int $user_id = null; + /** @var iterable */ public iterable $tags = []; + public ?int $tag_id = null; + /** @var iterable */ public iterable $comments = []; @@ -29,8 +30,8 @@ public function __construct(string $title = '', string $content = '') { $this->title = $title; $this->content = $content; - $this->created_at = new DateTimeImmutable(); - $this->updated_at = new DateTimeImmutable(); + $this->created_at = new \DateTimeImmutable(); + $this->updated_at = new \DateTimeImmutable(); $this->resetSlug(); } diff --git a/tests/ORM/Functional/Driver/Common/Integration/CaseTemplate/Entity/Tag.php b/tests/ORM/Functional/Driver/Common/Integration/CaseTemplate/Entity/Tag.php index 3711c5ed..a71ad123 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/CaseTemplate/Entity/Tag.php +++ b/tests/ORM/Functional/Driver/Common/Integration/CaseTemplate/Entity/Tag.php @@ -4,19 +4,18 @@ namespace Cycle\ORM\Tests\Functional\Driver\Common\Integration\CaseTemplate\Entity; -use DateTimeImmutable; - class Tag { public ?int $id = null; public string $label; - public DateTimeImmutable $created_at; + public \DateTimeImmutable $created_at; + /** @var iterable */ public iterable $posts = []; public function __construct(string $label) { $this->label = $label; - $this->created_at = new DateTimeImmutable(); + $this->created_at = new \DateTimeImmutable(); } } diff --git a/tests/ORM/Functional/Driver/Common/Integration/CaseTemplate/Entity/User.php b/tests/ORM/Functional/Driver/Common/Integration/CaseTemplate/Entity/User.php index 96927f8a..5c93b190 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/CaseTemplate/Entity/User.php +++ b/tests/ORM/Functional/Driver/Common/Integration/CaseTemplate/Entity/User.php @@ -4,8 +4,6 @@ namespace Cycle\ORM\Tests\Functional\Driver\Common\Integration\CaseTemplate\Entity; -use DateTimeImmutable; - class User { public const ROLE = 'user'; @@ -13,18 +11,20 @@ class User public ?int $id = null; public string $login; public string $passwordHash; - public DateTimeImmutable $created_at; - public DateTimeImmutable $updated_at; + public \DateTimeImmutable $created_at; + public \DateTimeImmutable $updated_at; + /** @var iterable */ public iterable $posts = []; + /** @var iterable */ public iterable $comments = []; public function __construct(string $login, string $password) { $this->login = $login; - $this->created_at = new DateTimeImmutable(); - $this->updated_at = new DateTimeImmutable(); + $this->created_at = new \DateTimeImmutable(); + $this->updated_at = new \DateTimeImmutable(); $this->setPassword($password); } diff --git a/tests/ORM/Functional/Driver/Common/Integration/Issue322/CaseTest.php b/tests/ORM/Functional/Driver/Common/Integration/Issue322/CaseTest.php index eb137b18..0f09528e 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Issue322/CaseTest.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Issue322/CaseTest.php @@ -19,16 +19,6 @@ abstract class CaseTest extends BaseTest use IntegrationTestTrait; use TableTrait; - public function setUp(): void - { - // Init DB - parent::setUp(); - $this->makeTables(); - $this->fillData(); - - $this->loadSchema(__DIR__ . '/schema.php'); - } - /** * There pivoted collection is replaced with new one but one target is from old collection */ @@ -85,6 +75,16 @@ public function testPivotedCollectionUniqueIndexWithNewPivot(): void $this->assertNumWrites(3); } + public function setUp(): void + { + // Init DB + parent::setUp(); + $this->makeTables(); + $this->fillData(); + + $this->loadSchema(__DIR__ . '/schema.php'); + } + private function makeTables(): void { // Make tables diff --git a/tests/ORM/Functional/Driver/Common/Integration/Issue322/Entity/Comment.php b/tests/ORM/Functional/Driver/Common/Integration/Issue322/Entity/Comment.php index 505642aa..022f90e4 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Issue322/Entity/Comment.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Issue322/Entity/Comment.php @@ -4,17 +4,15 @@ namespace Cycle\ORM\Tests\Functional\Driver\Common\Integration\Issue322\Entity; -use DateTimeImmutable; - class Comment { public ?int $id = null; public bool $public = false; public string $content; - public DateTimeImmutable $created_at; - public DateTimeImmutable $updated_at; - public ?DateTimeImmutable $published_at = null; - public ?DateTimeImmutable $deleted_at = null; + public \DateTimeImmutable $created_at; + public \DateTimeImmutable $updated_at; + public ?\DateTimeImmutable $published_at = null; + public ?\DateTimeImmutable $deleted_at = null; public User $user; public ?int $user_id = null; public ?Post $post = null; @@ -23,7 +21,7 @@ class Comment public function __construct(string $content) { $this->content = $content; - $this->created_at = new DateTimeImmutable(); - $this->updated_at = new DateTimeImmutable(); + $this->created_at = new \DateTimeImmutable(); + $this->updated_at = new \DateTimeImmutable(); } } diff --git a/tests/ORM/Functional/Driver/Common/Integration/Issue322/Entity/Post.php b/tests/ORM/Functional/Driver/Common/Integration/Issue322/Entity/Post.php index 18e02e71..3c456dbc 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Issue322/Entity/Post.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Issue322/Entity/Post.php @@ -5,7 +5,6 @@ namespace Cycle\ORM\Tests\Functional\Driver\Common\Integration\Issue322\Entity; use Cycle\ORM\Collection\Pivoted\PivotedCollection; -use DateTimeImmutable; class Post { @@ -14,15 +13,18 @@ class Post public string $title = ''; public bool $public = false; public string $content = ''; - public DateTimeImmutable $created_at; - public DateTimeImmutable $updated_at; - public ?DateTimeImmutable $published_at = null; - public ?DateTimeImmutable $deleted_at = null; + public \DateTimeImmutable $created_at; + public \DateTimeImmutable $updated_at; + public ?\DateTimeImmutable $published_at = null; + public ?\DateTimeImmutable $deleted_at = null; public User $user; public ?int $user_id = null; + /** @var iterable */ public iterable $tags; + public ?int $tag_id = null; + /** @var iterable */ public iterable $comments = []; @@ -30,8 +32,8 @@ public function __construct(string $title = '', string $content = '') { $this->title = $title; $this->content = $content; - $this->created_at = new DateTimeImmutable(); - $this->updated_at = new DateTimeImmutable(); + $this->created_at = new \DateTimeImmutable(); + $this->updated_at = new \DateTimeImmutable(); $this->tags = new PivotedCollection(); $this->resetSlug(); } diff --git a/tests/ORM/Functional/Driver/Common/Integration/Issue322/Entity/Tag.php b/tests/ORM/Functional/Driver/Common/Integration/Issue322/Entity/Tag.php index faff3468..aef8ca18 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Issue322/Entity/Tag.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Issue322/Entity/Tag.php @@ -4,19 +4,18 @@ namespace Cycle\ORM\Tests\Functional\Driver\Common\Integration\Issue322\Entity; -use DateTimeImmutable; - class Tag { public ?int $id = null; public string $label; - public DateTimeImmutable $created_at; + public \DateTimeImmutable $created_at; + /** @var iterable */ public iterable $posts = []; public function __construct(string $label) { $this->label = $label; - $this->created_at = new DateTimeImmutable(); + $this->created_at = new \DateTimeImmutable(); } } diff --git a/tests/ORM/Functional/Driver/Common/Integration/Issue322/Entity/User.php b/tests/ORM/Functional/Driver/Common/Integration/Issue322/Entity/User.php index b9a53e14..723a488c 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Issue322/Entity/User.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Issue322/Entity/User.php @@ -4,8 +4,6 @@ namespace Cycle\ORM\Tests\Functional\Driver\Common\Integration\Issue322\Entity; -use DateTimeImmutable; - class User { public const ROLE = 'user'; @@ -13,18 +11,20 @@ class User public ?int $id = null; public string $login; public string $passwordHash; - public DateTimeImmutable $created_at; - public DateTimeImmutable $updated_at; + public \DateTimeImmutable $created_at; + public \DateTimeImmutable $updated_at; + /** @var iterable */ public iterable $posts = []; + /** @var iterable */ public iterable $comments = []; public function __construct(string $login, string $password) { $this->login = $login; - $this->created_at = new DateTimeImmutable(); - $this->updated_at = new DateTimeImmutable(); + $this->created_at = new \DateTimeImmutable(); + $this->updated_at = new \DateTimeImmutable(); $this->setPassword($password); } diff --git a/tests/ORM/Functional/Driver/Common/Integration/Issue380/CaseTest.php b/tests/ORM/Functional/Driver/Common/Integration/Issue380/CaseTest.php index 88262639..432c23b3 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Issue380/CaseTest.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Issue380/CaseTest.php @@ -16,16 +16,6 @@ abstract class CaseTest extends BaseTest use IntegrationTestTrait; use TableTrait; - public function setUp(): void - { - // Init DB - parent::setUp(); - $this->makeTables(); - $this->fillData(); - - $this->loadSchema(__DIR__ . '/schema.php'); - } - public function testInsertOnce(): void { /** @var User $user */ @@ -36,14 +26,14 @@ public function testInsertOnce(): void $i = 0; - $em->persist(new User\Alias($user, (string)++$i)); - $em->persist(new User\Alias($user, (string)++$i)); + $em->persist(new User\Alias($user, (string) ++$i)); + $em->persist(new User\Alias($user, (string) ++$i)); - $em->persist(new User\Email($user, (string)++$i)); - $em->persist(new User\Email($user, (string)++$i)); + $em->persist(new User\Email($user, (string) ++$i)); + $em->persist(new User\Email($user, (string) ++$i)); - $em->persist(new User\Phone($user, (string)++$i)); - $em->persist(new User\Phone($user, (string)++$i)); + $em->persist(new User\Phone($user, (string) ++$i)); + $em->persist(new User\Phone($user, (string) ++$i)); $em->run(); @@ -66,7 +56,7 @@ public function testInsertOnce(): void 'alias' => $this->fetchFromTable('user_alias'), 'email' => $this->fetchFromTable('user_email'), 'phone' => $this->fetchFromTable('user_phone'), - ] + ], ); } @@ -85,17 +75,17 @@ public function testInsertMatrix(int $cnt1, int $cnt2, int $cnt3): void $expected = []; for ($id = 1; $id <= $cnt1; $id++) { - $em->persist(new User\Alias($user, $v = (string)++$i)); + $em->persist(new User\Alias($user, $v = (string) ++$i)); $expected['alias'][] = ['id' => $id, 'value' => $v]; } for ($id = 1; $id <= $cnt2; $id++) { - $em->persist(new User\Email($user, $v = (string)++$i)); + $em->persist(new User\Email($user, $v = (string) ++$i)); $expected['email'][] = ['id' => $id, 'value' => $v]; } for ($id = 1; $id <= $cnt3; $id++) { - $em->persist(new User\Phone($user, $v = (string)++$i)); + $em->persist(new User\Phone($user, $v = (string) ++$i)); $expected['phone'][] = ['id' => $id, 'value' => $v]; } $em->run(); @@ -106,7 +96,7 @@ public function testInsertMatrix(int $cnt1, int $cnt2, int $cnt3): void 'alias' => $this->fetchFromTable('user_alias'), 'email' => $this->fetchFromTable('user_email'), 'phone' => $this->fetchFromTable('user_phone'), - ] + ], ); } @@ -200,6 +190,16 @@ public function testDeleteAndInsertFainOnDuplicateUniqueKey(): void self::assertTrue(true); } + public function setUp(): void + { + // Init DB + parent::setUp(); + $this->makeTables(); + $this->fillData(); + + $this->loadSchema(__DIR__ . '/schema.php'); + } + private function fetchFromTable(string $tableName): array { $db = $this->orm->getSource(User::class)->getDatabase(); @@ -210,7 +210,7 @@ private function fetchFromTable(string $tableName): array ->fetchAll(); // cast id to int specially for mssql return \array_map(function (array $row): array { - $row['id'] = (int)$row['id']; + $row['id'] = (int) $row['id']; return $row; }, $rows); } diff --git a/tests/ORM/Functional/Driver/Common/Integration/Issue380/Entity/User.php b/tests/ORM/Functional/Driver/Common/Integration/Issue380/Entity/User.php index 89750e5c..10dd77d4 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Issue380/Entity/User.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Issue380/Entity/User.php @@ -7,9 +7,7 @@ class User { public int $id; - public string $username; - public int $age = 0; public function __construct(string $username) diff --git a/tests/ORM/Functional/Driver/Common/Integration/Issue380/Entity/User/Alias.php b/tests/ORM/Functional/Driver/Common/Integration/Issue380/Entity/User/Alias.php index f99924a6..08c53b3d 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Issue380/Entity/User/Alias.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Issue380/Entity/User/Alias.php @@ -9,9 +9,7 @@ class Alias { public int $id; - public string $value; - public User $user; public function __construct(User $user, string $value) diff --git a/tests/ORM/Functional/Driver/Common/Integration/Issue380/Entity/User/Email.php b/tests/ORM/Functional/Driver/Common/Integration/Issue380/Entity/User/Email.php index ae020fc0..d84064e6 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Issue380/Entity/User/Email.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Issue380/Entity/User/Email.php @@ -9,9 +9,7 @@ class Email { public int $id; - public string $value; - public User $user; public function __construct(User $user, string $value) diff --git a/tests/ORM/Functional/Driver/Common/Integration/Issue380/Entity/User/Phone.php b/tests/ORM/Functional/Driver/Common/Integration/Issue380/Entity/User/Phone.php index afa73a30..b9ddf42d 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Issue380/Entity/User/Phone.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Issue380/Entity/User/Phone.php @@ -9,9 +9,7 @@ class Phone { public int $id; - public string $value; - public User $user; public function __construct(User $user, string $value) diff --git a/tests/ORM/Functional/Driver/Common/Integration/Issue422/CaseTest.php b/tests/ORM/Functional/Driver/Common/Integration/Issue422/CaseTest.php index 911ea911..2d3c23a0 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Issue422/CaseTest.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Issue422/CaseTest.php @@ -16,16 +16,6 @@ abstract class CaseTest extends BaseTest use IntegrationTestTrait; use TableTrait; - public function setUp(): void - { - // Init DB - parent::setUp(); - $this->makeTables(); - $this->fillData(); - - $this->loadSchema(__DIR__ . '/schema.php'); - } - public function testSelect(): void { /** @var User $user */ @@ -44,6 +34,16 @@ public function testSelect(): void $this->assertSame(200, $user->otherEmbedded->propertyInt); } + public function setUp(): void + { + // Init DB + parent::setUp(); + $this->makeTables(); + $this->fillData(); + + $this->loadSchema(__DIR__ . '/schema.php'); + } + private function makeTables(): void { // Make tables diff --git a/tests/ORM/Functional/Driver/Common/Integration/Issue422/Entity/Billing.php b/tests/ORM/Functional/Driver/Common/Integration/Issue422/Entity/Billing.php index ff42ccdb..6b1d6af3 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Issue422/Entity/Billing.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Issue422/Entity/Billing.php @@ -7,6 +7,5 @@ class Billing { public ?int $id = null; - public SomeEmbedded $someEmbedded; } diff --git a/tests/ORM/Functional/Driver/Common/Integration/Issue422/Entity/SomeEmbedded.php b/tests/ORM/Functional/Driver/Common/Integration/Issue422/Entity/SomeEmbedded.php index c8beaaaa..1db19435 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Issue422/Entity/SomeEmbedded.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Issue422/Entity/SomeEmbedded.php @@ -7,6 +7,5 @@ class SomeEmbedded { public string $propertyString = ''; - public int $propertyInt = 0; } diff --git a/tests/ORM/Functional/Driver/Common/Integration/Issue482/AbstractTestCase.php b/tests/ORM/Functional/Driver/Common/Integration/Issue482/AbstractTestCase.php index fd8cf1fa..ff0bdf46 100644 --- a/tests/ORM/Functional/Driver/Common/Integration/Issue482/AbstractTestCase.php +++ b/tests/ORM/Functional/Driver/Common/Integration/Issue482/AbstractTestCase.php @@ -16,16 +16,6 @@ abstract class AbstractTestCase extends BaseTest use IntegrationTestTrait; use TableTrait; - public function setUp(): void - { - // Init DB - parent::setUp(); - $this->makeTables(); - $this->fillData(); - - $this->loadSchema(__DIR__ . '/schema.php'); - } - public function testSelect(): void { $select = $this->orm->getRepository(Country::class) @@ -70,10 +60,10 @@ public function testSelect(): void ], \array_column( \array_merge( - ...\array_column($data, 'translations') + ...\array_column($data, 'translations'), ), - 'title' - ) + 'title', + ), ); $all = $select->fetchAll(); @@ -89,14 +79,26 @@ static function (Country $c) { self::assertCount(1, $c->translations); return $c->translations[0]->title; }, - $all - ) + $all, + ), ); } + public function setUp(): void + { + // Init DB + parent::setUp(); + $this->makeTables(); + $this->fillData(); + + $this->loadSchema(__DIR__ . '/schema.php'); + } + + abstract protected function getExpectedSql(): string; + private function assertExpectedSql(Select $select): void { - $actual = (string)$select->buildQuery(); + $actual = (string) $select->buildQuery(); $expected = $this->getExpectedSql(); $this->assertSame( \array_map('trim', \explode("\n", $expected)), @@ -170,6 +172,4 @@ private function fillData(): void ], ); } - - abstract protected function getExpectedSql(): string; } diff --git a/tests/ORM/Functional/Driver/Common/Mapper/AutoTimestampsTest.php b/tests/ORM/Functional/Driver/Common/Mapper/AutoTimestampsTest.php index 42b16923..30ce0e5e 100644 --- a/tests/ORM/Functional/Driver/Common/Mapper/AutoTimestampsTest.php +++ b/tests/ORM/Functional/Driver/Common/Mapper/AutoTimestampsTest.php @@ -18,45 +18,6 @@ abstract class AutoTimestampsTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable( - 'user', - [ - 'id' => 'primary', - 'email' => 'string', - 'balance' => 'float', - 'created_at' => 'datetime', - 'updated_at' => 'datetime', - ] - ); - - $this->orm = $this->withSchema( - new Schema( - [ - User::class => [ - SchemaInterface::ROLE => 'user', - SchemaInterface::MAPPER => TimestampedMapper::class, - SchemaInterface::DATABASE => 'default', - SchemaInterface::TABLE => 'user', - SchemaInterface::PRIMARY_KEY => 'id', - SchemaInterface::COLUMNS => ['id', 'email', 'balance', 'created_at', 'updated_at'], - SchemaInterface::TYPECAST => [ - 'id' => 'int', - 'balance' => 'float', - 'created_at' => 'datetime', - 'updated_at' => 'datetime', - ], - SchemaInterface::SCHEMA => [], - SchemaInterface::RELATIONS => [], - ], - ] - ) - ); - } - public function testCreate(): void { $u = new User(); @@ -108,4 +69,43 @@ public function testUpdate(): void $this->save($u); $this->assertNumWrites(1); } + + public function setUp(): void + { + parent::setUp(); + + $this->makeTable( + 'user', + [ + 'id' => 'primary', + 'email' => 'string', + 'balance' => 'float', + 'created_at' => 'datetime', + 'updated_at' => 'datetime', + ], + ); + + $this->orm = $this->withSchema( + new Schema( + [ + User::class => [ + SchemaInterface::ROLE => 'user', + SchemaInterface::MAPPER => TimestampedMapper::class, + SchemaInterface::DATABASE => 'default', + SchemaInterface::TABLE => 'user', + SchemaInterface::PRIMARY_KEY => 'id', + SchemaInterface::COLUMNS => ['id', 'email', 'balance', 'created_at', 'updated_at'], + SchemaInterface::TYPECAST => [ + 'id' => 'int', + 'balance' => 'float', + 'created_at' => 'datetime', + 'updated_at' => 'datetime', + ], + SchemaInterface::SCHEMA => [], + SchemaInterface::RELATIONS => [], + ], + ], + ), + ); + } } diff --git a/tests/ORM/Functional/Driver/Common/Mapper/BaseMapperTest.php b/tests/ORM/Functional/Driver/Common/Mapper/BaseMapperTest.php index 1ae8c1bb..1a6a7fd1 100644 --- a/tests/ORM/Functional/Driver/Common/Mapper/BaseMapperTest.php +++ b/tests/ORM/Functional/Driver/Common/Mapper/BaseMapperTest.php @@ -8,6 +8,4 @@ use Cycle\ORM\Tests\Util\DontGenerateAttribute; #[DontGenerateAttribute] -abstract class BaseMapperTest extends BaseTest -{ -} +abstract class BaseMapperTest extends BaseTest {} diff --git a/tests/ORM/Functional/Driver/Common/Mapper/ClasslessMapper/ClasslessMapperTest.php b/tests/ORM/Functional/Driver/Common/Mapper/ClasslessMapper/ClasslessMapperTest.php index fe29f381..4e2c2ef0 100644 --- a/tests/ORM/Functional/Driver/Common/Mapper/ClasslessMapper/ClasslessMapperTest.php +++ b/tests/ORM/Functional/Driver/Common/Mapper/ClasslessMapper/ClasslessMapperTest.php @@ -17,45 +17,6 @@ abstract class ClasslessMapperTest extends BaseMapperTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable( - 'user', - [ - 'id' => 'primary', - 'email' => 'string', - 'balance' => 'float,nullable', - ] - ); - - $this->getDatabase()->table('user')->insertMultiple( - ['email', 'balance'], - [ - ['hello@world.com', 100], - ['another@world.com', 200], - ] - ); - - $this->orm = $this->withSchema( - new Schema( - [ - 'user' => [ - Schema::MAPPER => ClasslessMapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'user', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'email', 'balance'], - Schema::TYPECAST => ['balance' => 'float'], - Schema::SCHEMA => [], - Schema::RELATIONS => [], - ], - ] - ) - ); - } - public function testFetchData(): void { $this->assertEquals( @@ -71,7 +32,7 @@ public function testFetchData(): void 'balance' => 200.0, ], ], - (new Select($this->orm, 'user'))->fetchData() + (new Select($this->orm, 'user'))->fetchData(), ); } @@ -201,7 +162,7 @@ public function testHeap(): void 'email' => 'hello@world.com', 'balance' => 100.0, ], - $this->orm->getHeap()->get($result)->getData() + $this->orm->getHeap()->get($result)->getData(), ); } @@ -345,4 +306,43 @@ public function testNullableValuesInASndOut(): void $u = $this->orm->getRepository('user')->findByPK(1); $this->assertNull($u->balance); } + + public function setUp(): void + { + parent::setUp(); + + $this->makeTable( + 'user', + [ + 'id' => 'primary', + 'email' => 'string', + 'balance' => 'float,nullable', + ], + ); + + $this->getDatabase()->table('user')->insertMultiple( + ['email', 'balance'], + [ + ['hello@world.com', 100], + ['another@world.com', 200], + ], + ); + + $this->orm = $this->withSchema( + new Schema( + [ + 'user' => [ + Schema::MAPPER => ClasslessMapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'user', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'email', 'balance'], + Schema::TYPECAST => ['balance' => 'float'], + Schema::SCHEMA => [], + Schema::RELATIONS => [], + ], + ], + ), + ); + } } diff --git a/tests/ORM/Functional/Driver/Common/Mapper/MapperTest.php b/tests/ORM/Functional/Driver/Common/Mapper/MapperTest.php index cad14248..c927552f 100644 --- a/tests/ORM/Functional/Driver/Common/Mapper/MapperTest.php +++ b/tests/ORM/Functional/Driver/Common/Mapper/MapperTest.php @@ -21,97 +21,6 @@ abstract class MapperTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable( - 'user', - [ - 'id' => 'primary', - 'email' => 'string', - 'balance' => 'float,nullable', - 'protected' => 'int,nullable', - 'private' => 'int,nullable', - ] - ); - - $this->makeTable( - 'post', - [ - 'id' => 'primary', - 'user_id' => 'int', - ] - ); - - $this->getDatabase()->table('user')->insertMultiple( - ['email', 'balance', 'protected', 'private'], - [ - ['hello@world.com', 100, 12, 13], - ['another@world.com', 200, 14, 15], - ] - ); - $this->getDatabase()->table('post')->insertMultiple( - ['user_id'], - [ - [1], - [1], - [1], - ] - ); - - $this->orm = $this->withSchema( - new Schema( - [ - User::class => [ - SchemaInterface::ROLE => 'user', - SchemaInterface::MAPPER => Mapper::class, - SchemaInterface::DATABASE => 'default', - SchemaInterface::TABLE => 'user', - SchemaInterface::PRIMARY_KEY => 'id', - SchemaInterface::COLUMNS => ['id', 'email', 'balance', 'protected', 'private'], - SchemaInterface::TYPECAST => ['balance' => 'float'], - SchemaInterface::SCHEMA => [], - SchemaInterface::RELATIONS => [ - 'protectedRelation' => [ - Relation::TYPE => Relation::HAS_MANY, - Relation::TARGET => 'post', - Relation::LOAD => Relation::LOAD_EAGER, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::NULLABLE => false, - Relation::INNER_KEY => 'id', - Relation::OUTER_KEY => 'user', - ], - ], - 'privateRelation' => [ - Relation::TYPE => Relation::HAS_MANY, - Relation::TARGET => 'post', - Relation::LOAD => Relation::LOAD_EAGER, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::NULLABLE => false, - Relation::INNER_KEY => 'id', - Relation::OUTER_KEY => 'user', - ], - ], - ], - ], - Post::class => [ - SchemaInterface::ROLE => 'post', - SchemaInterface::MAPPER => Mapper::class, - SchemaInterface::DATABASE => 'default', - SchemaInterface::TABLE => 'post', - SchemaInterface::PRIMARY_KEY => 'id', - SchemaInterface::COLUMNS => ['id', 'user' => 'user_id'], - SchemaInterface::SCHEMA => [], - SchemaInterface::RELATIONS => [], - ], - ] - ) - ); - } - public function testFetchData(): void { $selector = new Select($this->orm, User::class); @@ -145,7 +54,7 @@ public function testFetchData(): void 'privateRelation' => [], ], ], - $selector->fetchData() + $selector->fetchData(), ); } @@ -318,7 +227,7 @@ public function testHeap(): void 'protected' => 12, 'private' => 13, ], - $this->orm->getHeap()->get($result)->getData() + $this->orm->getHeap()->get($result)->getData(), ); } @@ -462,4 +371,95 @@ public function testNullableValuesInASndOut(): void $u = $this->orm->getRepository(User::class)->findByPK(1); $this->assertNull($u->balance); } + + public function setUp(): void + { + parent::setUp(); + + $this->makeTable( + 'user', + [ + 'id' => 'primary', + 'email' => 'string', + 'balance' => 'float,nullable', + 'protected' => 'int,nullable', + 'private' => 'int,nullable', + ], + ); + + $this->makeTable( + 'post', + [ + 'id' => 'primary', + 'user_id' => 'int', + ], + ); + + $this->getDatabase()->table('user')->insertMultiple( + ['email', 'balance', 'protected', 'private'], + [ + ['hello@world.com', 100, 12, 13], + ['another@world.com', 200, 14, 15], + ], + ); + $this->getDatabase()->table('post')->insertMultiple( + ['user_id'], + [ + [1], + [1], + [1], + ], + ); + + $this->orm = $this->withSchema( + new Schema( + [ + User::class => [ + SchemaInterface::ROLE => 'user', + SchemaInterface::MAPPER => Mapper::class, + SchemaInterface::DATABASE => 'default', + SchemaInterface::TABLE => 'user', + SchemaInterface::PRIMARY_KEY => 'id', + SchemaInterface::COLUMNS => ['id', 'email', 'balance', 'protected', 'private'], + SchemaInterface::TYPECAST => ['balance' => 'float'], + SchemaInterface::SCHEMA => [], + SchemaInterface::RELATIONS => [ + 'protectedRelation' => [ + Relation::TYPE => Relation::HAS_MANY, + Relation::TARGET => 'post', + Relation::LOAD => Relation::LOAD_EAGER, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::NULLABLE => false, + Relation::INNER_KEY => 'id', + Relation::OUTER_KEY => 'user', + ], + ], + 'privateRelation' => [ + Relation::TYPE => Relation::HAS_MANY, + Relation::TARGET => 'post', + Relation::LOAD => Relation::LOAD_EAGER, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::NULLABLE => false, + Relation::INNER_KEY => 'id', + Relation::OUTER_KEY => 'user', + ], + ], + ], + ], + Post::class => [ + SchemaInterface::ROLE => 'post', + SchemaInterface::MAPPER => Mapper::class, + SchemaInterface::DATABASE => 'default', + SchemaInterface::TABLE => 'post', + SchemaInterface::PRIMARY_KEY => 'id', + SchemaInterface::COLUMNS => ['id', 'user' => 'user_id'], + SchemaInterface::SCHEMA => [], + SchemaInterface::RELATIONS => [], + ], + ], + ), + ); + } } diff --git a/tests/ORM/Functional/Driver/Common/Mapper/ProxyEntityMapper/EntityHydrationTest.php b/tests/ORM/Functional/Driver/Common/Mapper/ProxyEntityMapper/EntityHydrationTest.php index 6a2ac3d1..da8e8c96 100644 --- a/tests/ORM/Functional/Driver/Common/Mapper/ProxyEntityMapper/EntityHydrationTest.php +++ b/tests/ORM/Functional/Driver/Common/Mapper/ProxyEntityMapper/EntityHydrationTest.php @@ -14,48 +14,6 @@ class EntityHydrationTest extends BaseMapperTest { public const DRIVER = 'sqlite'; - public function setUp(): void - { - parent::setUp(); - - $this->orm = $this->withSchema( - new Schema( - [ - EntityHydrationUser::class => [ - SchemaInterface::MAPPER => Mapper::class, - SchemaInterface::DATABASE => 'default', - SchemaInterface::TABLE => 'user', - SchemaInterface::PRIMARY_KEY => 'uuid', - SchemaInterface::COLUMNS => ['id', 'username', 'email'], - SchemaInterface::TYPECAST => [], - SchemaInterface::SCHEMA => [], - SchemaInterface::RELATIONS => [], - ], - ExtendedEntityHydrationUser::class => [ - SchemaInterface::MAPPER => Mapper::class, - SchemaInterface::DATABASE => 'default', - SchemaInterface::TABLE => 'user', - SchemaInterface::PRIMARY_KEY => 'uuid', - SchemaInterface::COLUMNS => ['id', 'username', 'email', 'isVerified', 'profileId'], - SchemaInterface::TYPECAST => [], - SchemaInterface::SCHEMA => [], - SchemaInterface::RELATIONS => [], - ], - EntityHydrationIdentityUser::class => [ - SchemaInterface::MAPPER => Mapper::class, - SchemaInterface::DATABASE => 'default', - SchemaInterface::TABLE => 'user', - SchemaInterface::PRIMARY_KEY => 'id', - SchemaInterface::COLUMNS => ['id', 'value'], - SchemaInterface::TYPECAST => [], - SchemaInterface::SCHEMA => [], - SchemaInterface::RELATIONS => [], - ], - ] - ) - ); - } - public function testDataForBaseClassShouldBeExtracted(): void { $user = new EntityHydrationUser(123, 'guest', 'guest@site.com'); @@ -184,6 +142,48 @@ public function testHydrateBadType(): void throw $e; } } + + public function setUp(): void + { + parent::setUp(); + + $this->orm = $this->withSchema( + new Schema( + [ + EntityHydrationUser::class => [ + SchemaInterface::MAPPER => Mapper::class, + SchemaInterface::DATABASE => 'default', + SchemaInterface::TABLE => 'user', + SchemaInterface::PRIMARY_KEY => 'uuid', + SchemaInterface::COLUMNS => ['id', 'username', 'email'], + SchemaInterface::TYPECAST => [], + SchemaInterface::SCHEMA => [], + SchemaInterface::RELATIONS => [], + ], + ExtendedEntityHydrationUser::class => [ + SchemaInterface::MAPPER => Mapper::class, + SchemaInterface::DATABASE => 'default', + SchemaInterface::TABLE => 'user', + SchemaInterface::PRIMARY_KEY => 'uuid', + SchemaInterface::COLUMNS => ['id', 'username', 'email', 'isVerified', 'profileId'], + SchemaInterface::TYPECAST => [], + SchemaInterface::SCHEMA => [], + SchemaInterface::RELATIONS => [], + ], + EntityHydrationIdentityUser::class => [ + SchemaInterface::MAPPER => Mapper::class, + SchemaInterface::DATABASE => 'default', + SchemaInterface::TABLE => 'user', + SchemaInterface::PRIMARY_KEY => 'id', + SchemaInterface::COLUMNS => ['id', 'value'], + SchemaInterface::TYPECAST => [], + SchemaInterface::SCHEMA => [], + SchemaInterface::RELATIONS => [], + ], + ], + ), + ); + } } // phpcs:disable class EntityHydrationIdentityUser @@ -205,18 +205,6 @@ public function __construct(int $id, string $username, string $email) $this->email = $email; } - public function __set(string $name, $value): void - { - $this->attributes[$name] = $value; - } - - public function __get(string $name) - { - if (isset($this->attributes[$name])) { - return $this->attributes[$name]; - } - } - public function getId(): int { return $this->id; @@ -236,6 +224,18 @@ public function getAttributes(): array { return $this->attributes; } + + public function __set(string $name, $value): void + { + $this->attributes[$name] = $value; + } + + public function __get(string $name) + { + if (isset($this->attributes[$name])) { + return $this->attributes[$name]; + } + } } diff --git a/tests/ORM/Functional/Driver/Common/Mapper/ProxyEntityMapper/EntityWithRelationCreationTest.php b/tests/ORM/Functional/Driver/Common/Mapper/ProxyEntityMapper/EntityWithRelationCreationTest.php index 2f770794..bc1c7b30 100644 --- a/tests/ORM/Functional/Driver/Common/Mapper/ProxyEntityMapper/EntityWithRelationCreationTest.php +++ b/tests/ORM/Functional/Driver/Common/Mapper/ProxyEntityMapper/EntityWithRelationCreationTest.php @@ -8,12 +8,28 @@ use Cycle\ORM\Relation; use Cycle\ORM\Schema; use Cycle\ORM\Tests\Functional\Driver\Common\Mapper\BaseMapperTest; -use ReflectionClass; class EntityWithRelationCreationTest extends BaseMapperTest { public const DRIVER = 'sqlite'; + public function testProxyEntityRelationPropertiesShouldBeUnsetAfterCreation(): void + { + $mapper = $this->orm->getMapper(EntityWithRelationCreationUser::class); + + $emptyObject = $mapper->init([]); + + $refl = new \ReflectionClass(EntityWithRelationCreationAbstractUser::class); + + $profileProperty = $refl->getProperty('profile'); + $profileProperty->setAccessible(true); + + $this->assertFalse($profileProperty->isInitialized($emptyObject)); + $this->assertEquals(123, $emptyObject->id); + $this->assertEquals('test', $emptyObject->getUsername()); + $this->assertEquals('test@site.com', $emptyObject->getEmail()); + } + public function setUp(): void { parent::setUp(); @@ -41,27 +57,10 @@ public function setUp(): void ], ], ], - ] - ) + ], + ), ); } - - public function testProxyEntityRelationPropertiesShouldBeUnsetAfterCreation(): void - { - $mapper = $this->orm->getMapper(EntityWithRelationCreationUser::class); - - $emptyObject = $mapper->init([]); - - $refl = new ReflectionClass(EntityWithRelationCreationAbstractUser::class); - - $profileProperty = $refl->getProperty('profile'); - $profileProperty->setAccessible(true); - - $this->assertFalse($profileProperty->isInitialized($emptyObject)); - $this->assertEquals(123, $emptyObject->id); - $this->assertEquals('test', $emptyObject->getUsername()); - $this->assertEquals('test@site.com', $emptyObject->getEmail()); - } } // phpcs:disable diff --git a/tests/ORM/Functional/Driver/Common/Mapper/ProxyEntityMapper/EntityWithRelationHydrationTest.php b/tests/ORM/Functional/Driver/Common/Mapper/ProxyEntityMapper/EntityWithRelationHydrationTest.php index 1da5d214..54730e84 100644 --- a/tests/ORM/Functional/Driver/Common/Mapper/ProxyEntityMapper/EntityWithRelationHydrationTest.php +++ b/tests/ORM/Functional/Driver/Common/Mapper/ProxyEntityMapper/EntityWithRelationHydrationTest.php @@ -20,6 +20,143 @@ class EntityWithRelationHydrationTest extends BaseMapperTest public const DRIVER = 'sqlite'; + public function testPrivateBelongsToRelationPropertyWithoutProxyShouldBeFilled(): void + { + $profile = new EntityWithRelationHydrationProfile('test'); + $profile->user_id = 1; + + $this->save($profile); + $this->assertEquals(1, $profile->getUser()->id); + // todo should be check? + // $this->assertInstanceOf(ReferenceInterface::class, $profile->getRefersUser()); + } + + public function testRelationWithMixedTypeShouldBeFilledAsReference(): void + { + $user = new EntityWithMixedTypeRelation(); + $user->email = 'foo@bar.com'; + $user->friend_id = 1; + + $this->save($user); + + $this->assertInstanceOf(ReferenceInterface::class, $user->friend); + } + + public function testRelationExistedInHeapMustFilledAsEntity(): void + { + $user = new EntityWithMixedTypeRelation(); + $user->email = 'foo@bar.com'; + $user->friend_id = 1; + + $this->orm->getRepository(EntityWithMixedTypeRelation::class)->findByPK(1); + + $this->save($user); + $this->assertInstanceOf(EntityWithMixedTypeRelation::class, $user->friend); + } + + public function testPrivateHasManyRelationPropertyWithoutProxyShouldBeFilled(): void + { + $profile = new EntityWithRelationHydrationProfile('test'); + $user = new EntityWithRelationHydrationUser('admin@site.com'); + $user->profiles[] = $profile; + + $this->save($user); + + $this->assertSame($user, $profile->getUser()); + } + + public function testPrivateManyToManyRelationPropertyWithoutProxyShouldBeFilled(): void + { + $tagContext = new EntityWithRelationHydrationTagContext(); + $tagContext->user_id = 1; + $tagContext->tag_id = 2; + + $this->save($tagContext); + + $this->assertInstanceOf(ReferenceInterface::class, $tagContext->getTag()); + $this->assertInstanceOf(ReferenceInterface::class, $tagContext->getUser()); + } + + /** + * TODO: error with shadow belongs to + */ + public function testPrivateMorphBelongsToRelationPropertyWithoutProxyShouldBeFilled(): void + { + $profile = new EntityWithRelationHydrationProfile('test'); + $profile->user_id = 1; + + $avatar = new EntityWithRelationHydrationImage(); + $avatar->url = 'http://site.com'; + $avatar->setParent($profile); + + $this->save($avatar); + } + + public function testPrivateRelationPropertyShouldBeFilled(): void + { + $selector = new Select($this->orm, EntityWithRelationHydrationProfile::class); + + $profile = $selector + ->load('user.profile') + ->fetchOne(); + + $this->assertEquals('1', $profile->getUser()->id); + $this->assertEquals('hello@world.com', $profile->getUser()->getEmail()); + $this->assertSame($profile, $profile->getUser()->getProfile()); + } + + public function testLazyLoad(): void + { + $selector = new Select($this->orm, EntityWithRelationHydrationProfile::class); + + $profile = $selector + ->fetchOne(); + + $this->assertEquals('1', $profile->getUser()->id); + $this->assertEquals('hello@world.com', $profile->getUser()->getEmail()); + $this->assertSame($profile, $profile->getUser()->getProfile()); + } + + public function testChangeLazyOverloadedArray(): void + { + $user = (new Select($this->orm, EntityWithRelationHydrationUser::class)) + ->fetchOne(); + + try { + $user->profiles[] = 'test-value'; + $this->fail('There should be error (notice) thrown "Indirect modification of overloaded property"'); + } catch (AssertionFailedError $e) { + throw $e; + } catch (\Exception $e) { + $this->stringStartsWith('Indirect modification of overloaded property')->evaluate($e->getMessage()); + // That's OK + } + + // $user->profile now loaded + $user->profiles[] = 'test-value'; + $this->assertContains('test-value', $user->profiles); + } + + public function testGetLinkValueFromLazyOverloadedRelation(): void + { + $user = (new Select($this->orm, EntityWithRelationHydrationUser::class)) + ->fetchOne(); + + try { + $collection = &$user->profiles; + $this->fail('There should be error (notice) thrown "Indirect modification of overloaded property"'); + } catch (AssertionFailedError $e) { + throw $e; + } catch (\Exception $e) { + $this->stringStartsWith('Indirect modification of overloaded property')->evaluate($e->getMessage()); + // That's OK + } + // $user->profile now loaded + $collection = &$user->profiles; + $collection[] = 'test-value'; + $this->assertContains('test-value', $user->profiles); + } + public function setUp(): void { parent::setUp(); @@ -32,17 +169,17 @@ public function setUp(): void $this->getDatabase()->table('user')->insertMultiple( ['email'], - [['hello@world.com'],] + [['hello@world.com'],], ); $this->getDatabase()->table('profile')->insertMultiple( ['user_id', 'name'], - [[1, 'John Smith'],] + [[1, 'John Smith'],], ); $this->getDatabase()->table('tag')->insertMultiple( ['name'], - [['tag a'], ['tag b'], ['tag c'],] + [['tag a'], ['tag b'], ['tag c'],], ); $this->orm = $this->withSchema(new Schema([ @@ -240,143 +377,6 @@ public function setUp(): void ], ])); } - - public function testPrivateBelongsToRelationPropertyWithoutProxyShouldBeFilled(): void - { - $profile = new EntityWithRelationHydrationProfile('test'); - $profile->user_id = 1; - - $this->save($profile); - $this->assertEquals(1, $profile->getUser()->id); - // todo should be check? - // $this->assertInstanceOf(ReferenceInterface::class, $profile->getRefersUser()); - } - - public function testRelationWithMixedTypeShouldBeFilledAsReference(): void - { - $user = new EntityWithMixedTypeRelation(); - $user->email = 'foo@bar.com'; - $user->friend_id = 1; - - $this->save($user); - - $this->assertInstanceOf(ReferenceInterface::class, $user->friend); - } - - public function testRelationExistedInHeapMustFilledAsEntity(): void - { - $user = new EntityWithMixedTypeRelation(); - $user->email = 'foo@bar.com'; - $user->friend_id = 1; - - $this->orm->getRepository(EntityWithMixedTypeRelation::class)->findByPK(1); - - $this->save($user); - $this->assertInstanceOf(EntityWithMixedTypeRelation::class, $user->friend); - } - - public function testPrivateHasManyRelationPropertyWithoutProxyShouldBeFilled(): void - { - $profile = new EntityWithRelationHydrationProfile('test'); - $user = new EntityWithRelationHydrationUser('admin@site.com'); - $user->profiles[] = $profile; - - $this->save($user); - - $this->assertSame($user, $profile->getUser()); - } - - public function testPrivateManyToManyRelationPropertyWithoutProxyShouldBeFilled(): void - { - $tagContext = new EntityWithRelationHydrationTagContext(); - $tagContext->user_id = 1; - $tagContext->tag_id = 2; - - $this->save($tagContext); - - $this->assertInstanceOf(ReferenceInterface::class, $tagContext->getTag()); - $this->assertInstanceOf(ReferenceInterface::class, $tagContext->getUser()); - } - - /** - * TODO: error with shadow belongs to - */ - public function testPrivateMorphBelongsToRelationPropertyWithoutProxyShouldBeFilled(): void - { - $profile = new EntityWithRelationHydrationProfile('test'); - $profile->user_id = 1; - - $avatar = new EntityWithRelationHydrationImage(); - $avatar->url = 'http://site.com'; - $avatar->setParent($profile); - - $this->save($avatar); - } - - public function testPrivateRelationPropertyShouldBeFilled(): void - { - $selector = new Select($this->orm, EntityWithRelationHydrationProfile::class); - - $profile = $selector - ->load('user.profile') - ->fetchOne(); - - $this->assertEquals('1', $profile->getUser()->id); - $this->assertEquals('hello@world.com', $profile->getUser()->getEmail()); - $this->assertSame($profile, $profile->getUser()->getProfile()); - } - - public function testLazyLoad(): void - { - $selector = new Select($this->orm, EntityWithRelationHydrationProfile::class); - - $profile = $selector - ->fetchOne(); - - $this->assertEquals('1', $profile->getUser()->id); - $this->assertEquals('hello@world.com', $profile->getUser()->getEmail()); - $this->assertSame($profile, $profile->getUser()->getProfile()); - } - - public function testChangeLazyOverloadedArray(): void - { - $user = (new Select($this->orm, EntityWithRelationHydrationUser::class)) - ->fetchOne(); - - try { - $user->profiles[] = 'test-value'; - $this->fail('There should be error (notice) thrown "Indirect modification of overloaded property"'); - } catch (AssertionFailedError $e) { - throw $e; - } catch (\Exception $e) { - $this->stringStartsWith('Indirect modification of overloaded property')->evaluate($e->getMessage()); - // That's OK - } - - // $user->profile now loaded - $user->profiles[] = 'test-value'; - $this->assertContains('test-value', $user->profiles); - } - - public function testGetLinkValueFromLazyOverloadedRelation(): void - { - $user = (new Select($this->orm, EntityWithRelationHydrationUser::class)) - ->fetchOne(); - - try { - $collection = &$user->profiles; - $this->fail('There should be error (notice) thrown "Indirect modification of overloaded property"'); - } catch (AssertionFailedError $e) { - throw $e; - } catch (\Exception $e) { - $this->stringStartsWith('Indirect modification of overloaded property')->evaluate($e->getMessage()); - // That's OK - } - // $user->profile now loaded - $collection = &$user->profiles; - $collection[] = 'test-value'; - $this->assertContains('test-value', $user->profiles); - } } class EntityWithRelationHydrationUser @@ -410,11 +410,11 @@ public function getProfile(): EntityWithRelationHydrationProfile class EntityWithRelationHydrationProfile { public $id; + public $user_id; private $name; private EntityWithRelationHydrationUser $user; private object $refers_user; private EntityWithRelationHydrationImage $avatar; - public $user_id; public function __construct(string $name) { @@ -456,11 +456,10 @@ public function __construct() class EntityWithRelationHydrationTagContext { - private $user; - private ReferenceInterface $tag; - public $tag_id; public $user_id; + private $user; + private ReferenceInterface $tag; public function getTag(): ReferenceInterface { @@ -476,8 +475,8 @@ public function getUser(): ReferenceInterface class EntityWithRelationHydrationImage { - private mixed $parent; public $url; + private mixed $parent; public function setParent($parent): void { diff --git a/tests/ORM/Functional/Driver/Common/Mapper/ProxyEntityMapper/Hydrator/ClassPropertiesExtractorTest.php b/tests/ORM/Functional/Driver/Common/Mapper/ProxyEntityMapper/Hydrator/ClassPropertiesExtractorTest.php index 18a98998..632b479f 100644 --- a/tests/ORM/Functional/Driver/Common/Mapper/ProxyEntityMapper/Hydrator/ClassPropertiesExtractorTest.php +++ b/tests/ORM/Functional/Driver/Common/Mapper/ProxyEntityMapper/Hydrator/ClassPropertiesExtractorTest.php @@ -11,13 +11,6 @@ class ClassPropertiesExtractorTest extends TestCase { private ClassPropertiesExtractor $extractor; - protected function setUp(): void - { - parent::setUp(); - - $this->extractor = new ClassPropertiesExtractor(); - } - public function testPropertyFromBaseClassShouldBeExtracted(): void { $class = User::class; @@ -127,6 +120,13 @@ public function testPropertyFromExtendedClassWithRelationsShouldBeExtracted(): v ], ], $map[ClassPropertiesExtractor::KEY_RELATIONS]->getProperties()); } + + protected function setUp(): void + { + parent::setUp(); + + $this->extractor = new ClassPropertiesExtractor(); + } } // phpcs:disable diff --git a/tests/ORM/Functional/Driver/Common/Mapper/ProxyEntityMapper/Hydrator/PropertyMapTest.php b/tests/ORM/Functional/Driver/Common/Mapper/ProxyEntityMapper/Hydrator/PropertyMapTest.php index 7083aa3f..2abc814f 100644 --- a/tests/ORM/Functional/Driver/Common/Mapper/ProxyEntityMapper/Hydrator/PropertyMapTest.php +++ b/tests/ORM/Functional/Driver/Common/Mapper/ProxyEntityMapper/Hydrator/PropertyMapTest.php @@ -11,26 +11,6 @@ class PropertyMapTest extends TestCase { private PropertyMap $properties; - protected function setUp(): void - { - parent::setUp(); - - $this->properties = new PropertyMap('User', [ - '' => [ - 'id' => 'id', - 'username' => 'username', - ], - 'Test\User\ExtendedUser' => [ - 'is_verified' => 'is_verified', - 'has_avatar' => 'has_avatar', - ], - 'Test\User\SuperUser' => [ - 'is_admin' => 'is_admin', - 'is_blocked' => 'is_blocked', - ], - ]); - } - public function testGetsPropertyClass(): void { $this->assertEquals('', $this->properties->getPropertyClass('id')); @@ -64,4 +44,24 @@ public function testGetsClass(): void { $this->assertEquals('User', $this->properties->getClass()); } + + protected function setUp(): void + { + parent::setUp(); + + $this->properties = new PropertyMap('User', [ + '' => [ + 'id' => 'id', + 'username' => 'username', + ], + 'Test\User\ExtendedUser' => [ + 'is_verified' => 'is_verified', + 'has_avatar' => 'has_avatar', + ], + 'Test\User\SuperUser' => [ + 'is_admin' => 'is_admin', + 'is_blocked' => 'is_blocked', + ], + ]); + } } diff --git a/tests/ORM/Functional/Driver/Common/Mapper/SoftDeletesTest.php b/tests/ORM/Functional/Driver/Common/Mapper/SoftDeletesTest.php index aec81e00..c62d6b5f 100644 --- a/tests/ORM/Functional/Driver/Common/Mapper/SoftDeletesTest.php +++ b/tests/ORM/Functional/Driver/Common/Mapper/SoftDeletesTest.php @@ -18,37 +18,6 @@ abstract class SoftDeletesTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('user', [ - 'id' => 'primary', - 'email' => 'string', - 'balance' => 'float', - 'deleted_at' => 'datetime,null', - ]); - - $this->orm = $this->withSchema(new Schema([ - User::class => [ - Schema::ROLE => 'user', - Schema::MAPPER => SoftDeletedMapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'user', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'email', 'balance', 'deleted_at'], - Schema::TYPECAST => [ - 'id' => 'int', - 'balance' => 'float', - 'deleted_at' => 'datetime', - ], - Schema::SCHEMA => [], - Schema::RELATIONS => [], - Schema::SCOPE => NotDeletedScope::class, - ], - ])); - } - public function testCreate(): void { $u = new User(); @@ -93,4 +62,35 @@ public function testDelete(): void $s->scope(null); $this->assertNotNull($s->fetchOne()); } + + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('user', [ + 'id' => 'primary', + 'email' => 'string', + 'balance' => 'float', + 'deleted_at' => 'datetime,null', + ]); + + $this->orm = $this->withSchema(new Schema([ + User::class => [ + Schema::ROLE => 'user', + Schema::MAPPER => SoftDeletedMapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'user', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'email', 'balance', 'deleted_at'], + Schema::TYPECAST => [ + 'id' => 'int', + 'balance' => 'float', + 'deleted_at' => 'datetime', + ], + Schema::SCHEMA => [], + Schema::RELATIONS => [], + Schema::SCOPE => NotDeletedScope::class, + ], + ])); + } } diff --git a/tests/ORM/Functional/Driver/Common/Mapper/UUIDTest.php b/tests/ORM/Functional/Driver/Common/Mapper/UUIDTest.php index 85d32aa4..66252d05 100644 --- a/tests/ORM/Functional/Driver/Common/Mapper/UUIDTest.php +++ b/tests/ORM/Functional/Driver/Common/Mapper/UUIDTest.php @@ -29,83 +29,6 @@ abstract class UUIDTest extends BaseTest private $c2; private $c3; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('user', [ - 'id' => 'string(36),primary', - 'email' => 'string', - 'balance' => 'float', - ]); - - $this->makeTable('comment', [ - 'id' => 'string(36),primary', - 'user_id' => 'string(36)', - 'message' => 'string', - ]); - - $this->makeFK('comment', 'user_id', 'user', 'id'); - - // seed - $this->u1 = Uuid::uuid4()->toString(); - $this->u2 = Uuid::uuid4()->toString(); - $this->c1 = Uuid::uuid4()->toString(); - $this->c2 = Uuid::uuid4()->toString(); - $this->c3 = Uuid::uuid4()->toString(); - - $this->getDatabase()->table('user')->insertMultiple( - ['id', 'email', 'balance'], - [ - [$this->u1, 'hello@world.com', 100], - [$this->u2, 'another@world.com', 200], - ] - ); - - $this->getDatabase()->table('comment')->insertMultiple( - ['id', 'user_id', 'message'], - [ - [$this->c1, $this->u1, 'msg 1'], - [$this->c2, $this->u1, 'msg 2'], - [$this->c3, $this->u1, 'msg 3'], - ] - ); - - $this->orm = $this->withSchema(new Schema([ - User::class => [ - Schema::ROLE => 'user', - Schema::MAPPER => UUIDMapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'user', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'email', 'balance'], - Schema::SCHEMA => [], - Schema::RELATIONS => [ - 'comments' => [ - Relation::TYPE => Relation::HAS_MANY, - Relation::TARGET => Comment::class, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::INNER_KEY => 'id', - Relation::OUTER_KEY => 'user_id', - ], - ], - ], - ], - Comment::class => [ - Schema::ROLE => 'comment', - Schema::MAPPER => UUIDMapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'comment', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'user_id', 'message'], - Schema::SCHEMA => [], - Schema::RELATIONS => [], - Schema::SCOPE => SortByMsgScope::class, - ], - ])); - } - public function testFetchRelation(): void { $selector = new Select($this->orm, User::class); @@ -386,4 +309,81 @@ public function testSliceAndSaveToAnotherParent(): void $this->assertEquals('new b', $b->comments[1]->message); } + + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('user', [ + 'id' => 'string(36),primary', + 'email' => 'string', + 'balance' => 'float', + ]); + + $this->makeTable('comment', [ + 'id' => 'string(36),primary', + 'user_id' => 'string(36)', + 'message' => 'string', + ]); + + $this->makeFK('comment', 'user_id', 'user', 'id'); + + // seed + $this->u1 = Uuid::uuid4()->toString(); + $this->u2 = Uuid::uuid4()->toString(); + $this->c1 = Uuid::uuid4()->toString(); + $this->c2 = Uuid::uuid4()->toString(); + $this->c3 = Uuid::uuid4()->toString(); + + $this->getDatabase()->table('user')->insertMultiple( + ['id', 'email', 'balance'], + [ + [$this->u1, 'hello@world.com', 100], + [$this->u2, 'another@world.com', 200], + ], + ); + + $this->getDatabase()->table('comment')->insertMultiple( + ['id', 'user_id', 'message'], + [ + [$this->c1, $this->u1, 'msg 1'], + [$this->c2, $this->u1, 'msg 2'], + [$this->c3, $this->u1, 'msg 3'], + ], + ); + + $this->orm = $this->withSchema(new Schema([ + User::class => [ + Schema::ROLE => 'user', + Schema::MAPPER => UUIDMapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'user', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'email', 'balance'], + Schema::SCHEMA => [], + Schema::RELATIONS => [ + 'comments' => [ + Relation::TYPE => Relation::HAS_MANY, + Relation::TARGET => Comment::class, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::INNER_KEY => 'id', + Relation::OUTER_KEY => 'user_id', + ], + ], + ], + ], + Comment::class => [ + Schema::ROLE => 'comment', + Schema::MAPPER => UUIDMapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'comment', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'user_id', 'message'], + Schema::SCHEMA => [], + Schema::RELATIONS => [], + Schema::SCOPE => SortByMsgScope::class, + ], + ])); + } } diff --git a/tests/ORM/Functional/Driver/Common/ORM/MemoryTest.php b/tests/ORM/Functional/Driver/Common/ORM/MemoryTest.php index ed4c1ece..dd459a56 100644 --- a/tests/ORM/Functional/Driver/Common/ORM/MemoryTest.php +++ b/tests/ORM/Functional/Driver/Common/ORM/MemoryTest.php @@ -17,8 +17,6 @@ use Cycle\ORM\Service\TypecastProviderInterface; use Cycle\ORM\Tests\Functional\Driver\Common\BaseTest; use Cycle\ORM\Tests\Traits\TableTrait; -use WeakMap; -use WeakReference; abstract class MemoryTest extends BaseTest { @@ -28,12 +26,6 @@ abstract class MemoryTest extends BaseTest private const ACTION_UNSET = 'unset'; private const ACTION_WITH = 'with'; - public function setUp(): void - { - parent::setUp(); - // Load all relations instances - } - // With `Collect Garbage Cycles` public function configProvider(): iterable @@ -77,7 +69,7 @@ public function testOrm(string $action, bool $garbage, bool $warmupOrm, bool $lo // Collect weak references $loadLinks and $map = $this->collectReferences($orm, $loadRoles); // Create main ORM reference - $link = WeakReference::create($orm); + $link = \WeakReference::create($orm); // Do main action switch ($action) { @@ -97,6 +89,12 @@ public function testOrm(string $action, bool $garbage, bool $warmupOrm, bool $lo $this->assertTrue($link->get() === null); } + public function setUp(): void + { + parent::setUp(); + // Load all relations instances + } + // Support private function createORM(): ORM @@ -105,9 +103,9 @@ private function createORM(): ORM return new ORM(new Factory($this->dbal), $schema); } - private function collectReferences(ORMInterface $orm, bool $loadRoles): WeakMap + private function collectReferences(ORMInterface $orm, bool $loadRoles): \WeakMap { - $map = new WeakMap(); + $map = new \WeakMap(); $schema = $orm->getSchema(); \assert($schema::class === Schema::class); diff --git a/tests/ORM/Functional/Driver/Common/ORM/ORMTest.php b/tests/ORM/Functional/Driver/Common/ORM/ORMTest.php index 2b02fbc1..d3137bae 100644 --- a/tests/ORM/Functional/Driver/Common/ORM/ORMTest.php +++ b/tests/ORM/Functional/Driver/Common/ORM/ORMTest.php @@ -15,6 +15,28 @@ abstract class ORMTest extends BaseTest { use TableTrait; + public function testORMGet(): void + { + $this->assertNull($this->orm->get(User::class, ['id' => 1], false)); + $this->assertInstanceOf(User::class, $this->orm->get(User::class, ['id' => 1], true)); + + $this->captureReadQueries(); + $this->assertInstanceOf(User::class, $this->orm->get(User::class, ['id' => 1])); + $this->assertNumReads(0); + + $this->assertCount(1, $this->orm->getSchema()->getRoles()); + } + + public function testORMGetByRole(): void + { + $this->assertNull($this->orm->get('user', ['id' => 1], false)); + $this->assertInstanceOf(User::class, $this->orm->get('user', ['id' => 1], true)); + + $this->captureReadQueries(); + $this->assertInstanceOf(User::class, $this->orm->get('user', ['id' => 1])); + $this->assertNumReads(0); + } + public function setUp(): void { parent::setUp(); @@ -30,7 +52,7 @@ public function setUp(): void [ ['hello@world.com', 100], ['another@world.com', 200], - ] + ], ); $this->orm = $this->withSchema(new Schema([ @@ -46,26 +68,4 @@ public function setUp(): void ], ])); } - - public function testORMGet(): void - { - $this->assertNull($this->orm->get(User::class, ['id' => 1], false)); - $this->assertInstanceOf(User::class, $this->orm->get(User::class, ['id' => 1], true)); - - $this->captureReadQueries(); - $this->assertInstanceOf(User::class, $this->orm->get(User::class, ['id' => 1])); - $this->assertNumReads(0); - - $this->assertCount(1, $this->orm->getSchema()->getRoles()); - } - - public function testORMGetByRole(): void - { - $this->assertNull($this->orm->get('user', ['id' => 1], false)); - $this->assertInstanceOf(User::class, $this->orm->get('user', ['id' => 1], true)); - - $this->captureReadQueries(); - $this->assertInstanceOf(User::class, $this->orm->get('user', ['id' => 1])); - $this->assertNumReads(0); - } } diff --git a/tests/ORM/Functional/Driver/Common/Relation/BelongsTo/BelongsToCompositeKeyTest.php b/tests/ORM/Functional/Driver/Common/Relation/BelongsTo/BelongsToCompositeKeyTest.php index c71b15dd..88233cca 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/BelongsTo/BelongsToCompositeKeyTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/BelongsTo/BelongsToCompositeKeyTest.php @@ -23,109 +23,24 @@ abstract class BelongsToCompositeKeyTest extends BaseTest { use TableTrait; - protected const - PARENT_CONTAINER = 'parent'; - protected const - CHILD_CONTAINER = 'child_entity'; - protected const - NESTED_CONTAINER = 'nested'; - protected const - PARENT_1 = ['key1' => 1, 'key2' => 1, 'key3' => 101]; - protected const - PARENT_2 = ['key1' => 1, 'key2' => 2, 'key3' => 102]; - protected const - PARENT_3 = ['key1' => 2, 'key2' => 1, 'key3' => 201]; - protected const - CHILD_1 = ['key1' => 1, 'key2' => 1, 'key3' => null, 'parent_key1' => 1, 'parent_key2' => 1]; - protected const - CHILD_2 = ['key1' => 1, 'key2' => 2, 'key3' => 'foo2', 'parent_key1' => 1, 'parent_key2' => 2]; - protected const - CHILD_3 = ['key1' => 1, 'key2' => 3, 'key3' => 'bar3', 'parent_key1' => 1, 'parent_key2' => 2]; - protected const - NESTED_1 = ['key3' => 'foo', 'parent_key1' => 1, 'parent_key2' => 1]; - protected const - CHILD_1_LOADED = self::CHILD_1 + [self::PARENT_CONTAINER => self::PARENT_1]; - protected const - CHILD_2_LOADED = self::CHILD_2 + [self::PARENT_CONTAINER => self::PARENT_2]; - protected const - CHILD_3_LOADED = self::CHILD_3 + [self::PARENT_CONTAINER => self::PARENT_2]; - protected const - CHILDREN_LOADED = [ - self::CHILD_1_LOADED, - self::CHILD_2_LOADED, - self::CHILD_3_LOADED, - ]; - - public function setUp(): void - { - parent::setUp(); - - $this->makeTable( - 'parent_entity', - [ - 'pField1' => 'bigInteger,primary', - 'pField2' => 'bigInteger,primary', - 'pField3' => 'integer,nullable', - ] - ); - $this->makeTable( - 'child_entity', - [ - 'field1' => 'bigInteger,primary', - 'field2' => 'bigInteger,primary', - 'field3' => 'string,nullable', - 'parent_field1' => 'bigInteger,null', - 'parent_field2' => 'bigInteger,null', - ] - ); - $this->makeTable( - 'nested_entity', - [ - 'field1' => 'primary', - 'field3' => 'string,null', - 'parent_field1' => 'bigInteger,null', - 'parent_field2' => 'bigInteger,null', - ] - ); - - $this->makeCompositeFK( - 'child_entity', - ['parent_field1', 'parent_field2'], - 'parent_entity', - ['pField1', 'pField2'] - ); - $this->makeCompositeFK( - 'nested_entity', - ['parent_field1', 'parent_field2'], - 'child_entity', - ['field1', 'field2'] - ); - - $this->getDatabase()->table('parent_entity')->insertMultiple( - ['pField1', 'pField2', 'pField3'], - [ - self::PARENT_1, - self::PARENT_2, - self::PARENT_3, - ] - ); - $this->getDatabase()->table('child_entity')->insertMultiple( - ['field1', 'field2', 'field3', 'parent_field1', 'parent_field2'], - [ - self::CHILD_1, - self::CHILD_2, - self::CHILD_3, - ] - ); - $this->getDatabase()->table('nested_entity')->insertMultiple( - ['field3', 'parent_field1', 'parent_field2'], - [ - self::NESTED_1, - ] - ); - - $this->orm = $this->withSchema(new Schema($this->getSchemaArray())); - } + protected const PARENT_CONTAINER = 'parent'; + protected const CHILD_CONTAINER = 'child_entity'; + protected const NESTED_CONTAINER = 'nested'; + protected const PARENT_1 = ['key1' => 1, 'key2' => 1, 'key3' => 101]; + protected const PARENT_2 = ['key1' => 1, 'key2' => 2, 'key3' => 102]; + protected const PARENT_3 = ['key1' => 2, 'key2' => 1, 'key3' => 201]; + protected const CHILD_1 = ['key1' => 1, 'key2' => 1, 'key3' => null, 'parent_key1' => 1, 'parent_key2' => 1]; + protected const CHILD_2 = ['key1' => 1, 'key2' => 2, 'key3' => 'foo2', 'parent_key1' => 1, 'parent_key2' => 2]; + protected const CHILD_3 = ['key1' => 1, 'key2' => 3, 'key3' => 'bar3', 'parent_key1' => 1, 'parent_key2' => 2]; + protected const NESTED_1 = ['key3' => 'foo', 'parent_key1' => 1, 'parent_key2' => 1]; + protected const CHILD_1_LOADED = self::CHILD_1 + [self::PARENT_CONTAINER => self::PARENT_1]; + protected const CHILD_2_LOADED = self::CHILD_2 + [self::PARENT_CONTAINER => self::PARENT_2]; + protected const CHILD_3_LOADED = self::CHILD_3 + [self::PARENT_CONTAINER => self::PARENT_2]; + protected const CHILDREN_LOADED = [ + self::CHILD_1_LOADED, + self::CHILD_2_LOADED, + self::CHILD_3_LOADED, + ]; public function testFetchRelation(): void { @@ -417,6 +332,77 @@ public function testWhereCompositePKNestedWithAlias(): void $this->assertSame('foo', $n->key3); } + public function setUp(): void + { + parent::setUp(); + + $this->makeTable( + 'parent_entity', + [ + 'pField1' => 'bigInteger,primary', + 'pField2' => 'bigInteger,primary', + 'pField3' => 'integer,nullable', + ], + ); + $this->makeTable( + 'child_entity', + [ + 'field1' => 'bigInteger,primary', + 'field2' => 'bigInteger,primary', + 'field3' => 'string,nullable', + 'parent_field1' => 'bigInteger,null', + 'parent_field2' => 'bigInteger,null', + ], + ); + $this->makeTable( + 'nested_entity', + [ + 'field1' => 'primary', + 'field3' => 'string,null', + 'parent_field1' => 'bigInteger,null', + 'parent_field2' => 'bigInteger,null', + ], + ); + + $this->makeCompositeFK( + 'child_entity', + ['parent_field1', 'parent_field2'], + 'parent_entity', + ['pField1', 'pField2'], + ); + $this->makeCompositeFK( + 'nested_entity', + ['parent_field1', 'parent_field2'], + 'child_entity', + ['field1', 'field2'], + ); + + $this->getDatabase()->table('parent_entity')->insertMultiple( + ['pField1', 'pField2', 'pField3'], + [ + self::PARENT_1, + self::PARENT_2, + self::PARENT_3, + ], + ); + $this->getDatabase()->table('child_entity')->insertMultiple( + ['field1', 'field2', 'field3', 'parent_field1', 'parent_field2'], + [ + self::CHILD_1, + self::CHILD_2, + self::CHILD_3, + ], + ); + $this->getDatabase()->table('nested_entity')->insertMultiple( + ['field3', 'parent_field1', 'parent_field2'], + [ + self::NESTED_1, + ], + ); + + $this->orm = $this->withSchema(new Schema($this->getSchemaArray())); + } + private function getSchemaArray(): array { return [ diff --git a/tests/ORM/Functional/Driver/Common/Relation/BelongsTo/BelongsToProxyMapperRenamedFieldsTest.php b/tests/ORM/Functional/Driver/Common/Relation/BelongsTo/BelongsToProxyMapperRenamedFieldsTest.php index 35e6d91f..ed08c550 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/BelongsTo/BelongsToProxyMapperRenamedFieldsTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/BelongsTo/BelongsToProxyMapperRenamedFieldsTest.php @@ -41,7 +41,7 @@ public function setUp(): void ['email', 'balance'], [ ['hello@world.com', 100], - ] + ], ); $this->getDatabase()->table('profile')->insertMultiple( @@ -50,14 +50,14 @@ public function setUp(): void [1, 'image.png'], [2, 'second.png'], [null, 'third.png'], - ] + ], ); $this->getDatabase()->table('nested')->insertMultiple( ['profile_id_field', 'label'], [ [1, 'nested-label'], - ] + ], ); $this->orm = $this->withSchema(new Schema([ diff --git a/tests/ORM/Functional/Driver/Common/Relation/BelongsTo/BelongsToProxyMapperTest.php b/tests/ORM/Functional/Driver/Common/Relation/BelongsTo/BelongsToProxyMapperTest.php index 3e438825..cd3a5d35 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/BelongsTo/BelongsToProxyMapperTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/BelongsTo/BelongsToProxyMapperTest.php @@ -20,89 +20,6 @@ abstract class BelongsToProxyMapperTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('user', [ - 'id' => 'primary', - 'email' => 'string', - 'balance' => 'float', - ]); - - $this->makeTable('profile', [ - 'id' => 'primary', - 'user_id' => 'integer,null', - 'image' => 'string', - ]); - - $this->makeTable('nested', [ - 'id' => 'primary', - 'profile_id' => 'integer', - 'label' => 'string', - ]); - - $this->makeFK('nested', 'profile_id', 'profile', 'id'); - - $this->getDatabase()->table('user')->insertMultiple( - ['email', 'balance'], - [ - ['hello@world.com', 100], - ] - ); - - $this->getDatabase()->table('profile')->insertMultiple( - ['user_id', 'image'], - [ - [1, 'image.png'], - [2, 'second.png'], - [null, 'third.png'], - ] - ); - - $this->getDatabase()->table('nested')->insertMultiple( - ['profile_id', 'label'], - [ - [1, 'nested-label'], - ] - ); - - $this->orm = $this->withSchema(new Schema([ - User::class => [ - Schema::ROLE => 'user', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'user', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'email', 'balance'], - Schema::SCHEMA => [], - Schema::RELATIONS => [], - ], - Profile::class => [ - Schema::ROLE => 'profile', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'profile', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'user_id', 'image'], - Schema::SCHEMA => [], - Schema::RELATIONS => [ - 'user' => [ - Relation::TYPE => Relation::BELONGS_TO, - Relation::TARGET => User::class, - Relation::LOAD => Relation::LOAD_PROMISE, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::INNER_KEY => 'user_id', - Relation::OUTER_KEY => 'id', - Relation::NULLABLE => true, - ], - ], - ], - ], - ])); - } - public function testFetchRelation(): void { $selector = new Select($this->orm, Profile::class); @@ -238,6 +155,89 @@ public function testEditPromised(): void $p = (new Select($this->orm->withHeap(new Heap()), Profile::class)) ->wherePK(1)->fetchOne(); - $this->assertSame(400, (int)$p->user->balance); + $this->assertSame(400, (int) $p->user->balance); + } + + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('user', [ + 'id' => 'primary', + 'email' => 'string', + 'balance' => 'float', + ]); + + $this->makeTable('profile', [ + 'id' => 'primary', + 'user_id' => 'integer,null', + 'image' => 'string', + ]); + + $this->makeTable('nested', [ + 'id' => 'primary', + 'profile_id' => 'integer', + 'label' => 'string', + ]); + + $this->makeFK('nested', 'profile_id', 'profile', 'id'); + + $this->getDatabase()->table('user')->insertMultiple( + ['email', 'balance'], + [ + ['hello@world.com', 100], + ], + ); + + $this->getDatabase()->table('profile')->insertMultiple( + ['user_id', 'image'], + [ + [1, 'image.png'], + [2, 'second.png'], + [null, 'third.png'], + ], + ); + + $this->getDatabase()->table('nested')->insertMultiple( + ['profile_id', 'label'], + [ + [1, 'nested-label'], + ], + ); + + $this->orm = $this->withSchema(new Schema([ + User::class => [ + Schema::ROLE => 'user', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'user', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'email', 'balance'], + Schema::SCHEMA => [], + Schema::RELATIONS => [], + ], + Profile::class => [ + Schema::ROLE => 'profile', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'profile', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'user_id', 'image'], + Schema::SCHEMA => [], + Schema::RELATIONS => [ + 'user' => [ + Relation::TYPE => Relation::BELONGS_TO, + Relation::TARGET => User::class, + Relation::LOAD => Relation::LOAD_PROMISE, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::INNER_KEY => 'user_id', + Relation::OUTER_KEY => 'id', + Relation::NULLABLE => true, + ], + ], + ], + ], + ])); } } diff --git a/tests/ORM/Functional/Driver/Common/Relation/BelongsTo/BelongsToRelationRenamedFieldsTest.php b/tests/ORM/Functional/Driver/Common/Relation/BelongsTo/BelongsToRelationRenamedFieldsTest.php index 7a0c0f62..666f078b 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/BelongsTo/BelongsToRelationRenamedFieldsTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/BelongsTo/BelongsToRelationRenamedFieldsTest.php @@ -29,7 +29,7 @@ public function setUp(): void [ ['hello@world.com', 100], ['another@world.com', 200], - ] + ], ); $this->makeTable('profile', [ @@ -44,7 +44,7 @@ public function setUp(): void [1, 'image.png'], [2, 'second.png'], [2, 'third.png'], - ] + ], ); $this->makeTable('nested', [ @@ -57,7 +57,7 @@ public function setUp(): void ['profile_id_field', 'label'], [ [1, 'nested-label'], - ] + ], ); $this->makeFK('profile', 'user_id_field', 'user', 'user_pk'); diff --git a/tests/ORM/Functional/Driver/Common/Relation/BelongsTo/BelongsToRelationTest.php b/tests/ORM/Functional/Driver/Common/Relation/BelongsTo/BelongsToRelationTest.php index 2df5b0c5..e50e3c54 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/BelongsTo/BelongsToRelationTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/BelongsTo/BelongsToRelationTest.php @@ -23,58 +23,6 @@ abstract class BelongsToRelationTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('user', [ - 'id' => 'primary', - 'email' => 'string', - 'balance' => 'float', - ]); - - $this->getDatabase()->table('user')->insertMultiple( - ['email', 'balance'], - [ - ['hello@world.com', 100], - ['another@world.com', 200], - ] - ); - - $this->makeTable('profile', [ - 'id' => 'primary', - 'user_id' => 'integer', - 'image' => 'string', - ]); - - $this->getDatabase()->table('profile')->insertMultiple( - ['user_id', 'image'], - [ - [1, 'image.png'], - [2, 'second.png'], - [2, 'third.png'], - ] - ); - - $this->makeTable('nested', [ - 'id' => 'primary', - 'profile_id' => 'integer', - 'label' => 'string', - ]); - - $this->getDatabase()->table('nested')->insertMultiple( - ['profile_id', 'label'], - [ - [1, 'nested-label'], - ] - ); - - $this->makeFK('profile', 'user_id', 'user', 'id'); - $this->makeFK('nested', 'profile_id', 'profile', 'id'); - - $this->orm = $this->withSchema(new Schema($this->getSchemaArray())); - } - public function testFetchRelation(): void { $selector = new Select($this->orm, Profile::class); @@ -151,7 +99,7 @@ public function testFetchRelationInload(): void { $selector = new Select($this->orm, Profile::class); $selector->load('user', ['method' => Select\JoinableLoader::INLOAD]) - ->orderBy('profile.id'); + ->orderBy('profile.id'); $this->assertEquals([ [ @@ -332,7 +280,7 @@ public function testChangeParent(): void ], ], ], (new Select($this->orm, Profile::class))->load('user')->wherePK( - 1 + 1, )->fetchData()); } @@ -357,7 +305,7 @@ public function testExchangeParents(): void $s = new Select($this->orm->withHeap(new Heap()), Profile::class); [$a2, $b2] = $s->wherePK(new Parameter([1, 2]))->orderBy('profile.id') - ->load('user')->fetchAll(); + ->load('user')->fetchAll(); $this->assertSame($a->user->id, $a2->user->id); $this->assertSame($b->user->id, $b2->user->id); @@ -410,8 +358,8 @@ public function testWhereNested(): void { $s = new Select($this->orm->withHeap(new Heap()), Nested::class); $n = $s->with('profile.user') - ->where('profile.user.id', 1) - ->fetchOne(); + ->where('profile.user.id', 1) + ->fetchOne(); $this->assertSame('nested-label', $n->label); } @@ -438,10 +386,62 @@ public function testSetNullable(): void $this->assertInstanceOf( Relation\BelongsTo::class, - $this->orm->getRelationMap(Profile::class)->getRelations()['user'] + $this->orm->getRelationMap(Profile::class)->getRelations()['user'], ); } + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('user', [ + 'id' => 'primary', + 'email' => 'string', + 'balance' => 'float', + ]); + + $this->getDatabase()->table('user')->insertMultiple( + ['email', 'balance'], + [ + ['hello@world.com', 100], + ['another@world.com', 200], + ], + ); + + $this->makeTable('profile', [ + 'id' => 'primary', + 'user_id' => 'integer', + 'image' => 'string', + ]); + + $this->getDatabase()->table('profile')->insertMultiple( + ['user_id', 'image'], + [ + [1, 'image.png'], + [2, 'second.png'], + [2, 'third.png'], + ], + ); + + $this->makeTable('nested', [ + 'id' => 'primary', + 'profile_id' => 'integer', + 'label' => 'string', + ]); + + $this->getDatabase()->table('nested')->insertMultiple( + ['profile_id', 'label'], + [ + [1, 'nested-label'], + ], + ); + + $this->makeFK('profile', 'user_id', 'user', 'id'); + $this->makeFK('nested', 'profile_id', 'profile', 'id'); + + $this->orm = $this->withSchema(new Schema($this->getSchemaArray())); + } + private function getSchemaArray(): array { return [ diff --git a/tests/ORM/Functional/Driver/Common/Relation/BelongsTo/BelongsToRelationWithNestedUuidTest.php b/tests/ORM/Functional/Driver/Common/Relation/BelongsTo/BelongsToRelationWithNestedUuidTest.php index 35a312eb..254a8b8e 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/BelongsTo/BelongsToRelationWithNestedUuidTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/BelongsTo/BelongsToRelationWithNestedUuidTest.php @@ -19,26 +19,6 @@ abstract class BelongsToRelationWithNestedUuidTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('user_with_uuid_pk', [ - 'uuid' => 'string(36),primary', - 'email' => 'string', - 'balance' => 'float', - ]); - - $this->makeTable('comment_with_uuid_user', [ - 'id' => 'primary', - 'message' => 'string,nullable', - 'parent_id' => 'integer,nullable', - 'user_id' => 'string(36),nullable', - ]); - - $this->orm = $this->withSchema(new Schema($this->getSchemaArray())); - } - public function testNestedWithUuidPK(): void { $uuid = Uuid::uuid4(); @@ -66,7 +46,7 @@ public function testNestedWithUuidPK(): void $this->assertInstanceOf( UserWithUUIDPrimaryKey::class, - $this->orm->getRepository(UserWithUUIDPrimaryKey::class)->findOne() + $this->orm->getRepository(UserWithUUIDPrimaryKey::class)->findOne(), ); $this->assertInstanceOf(Comment::class, $first); @@ -77,6 +57,26 @@ public function testNestedWithUuidPK(): void $this->assertInstanceOf(Comment::class, $second->parent); } + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('user_with_uuid_pk', [ + 'uuid' => 'string(36),primary', + 'email' => 'string', + 'balance' => 'float', + ]); + + $this->makeTable('comment_with_uuid_user', [ + 'id' => 'primary', + 'message' => 'string,nullable', + 'parent_id' => 'integer,nullable', + 'user_id' => 'string(36),nullable', + ]); + + $this->orm = $this->withSchema(new Schema($this->getSchemaArray())); + } + private function getSchemaArray(): array { return [ diff --git a/tests/ORM/Functional/Driver/Common/Relation/BelongsTo/BelongsToWithHasOneTest.php b/tests/ORM/Functional/Driver/Common/Relation/BelongsTo/BelongsToWithHasOneTest.php index a02452e6..8024d54b 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/BelongsTo/BelongsToWithHasOneTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/BelongsTo/BelongsToWithHasOneTest.php @@ -23,129 +23,6 @@ abstract class BelongsToWithHasOneTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('user', [ - 'id' => 'primary', - 'email' => 'string', - 'balance' => 'float', - ]); - - $this->getDatabase()->table('user')->insertMultiple( - ['email', 'balance'], - [ - ['hello@world.com', 100], - ['another@world.com', 200], - ] - ); - - $this->makeTable('profile', [ - 'id' => 'primary', - 'user_id' => 'integer', - 'image' => 'string', - ]); - - $this->getDatabase()->table('profile')->insertMultiple( - ['user_id', 'image'], - [ - [1, 'image.png'], - [2, 'second.png'], - [2, 'third.png'], - ] - ); - - $this->makeTable('nested', [ - 'id' => 'primary', - 'profile_id' => 'integer', - 'label' => 'string', - ]); - - $this->getDatabase()->table('nested')->insertMultiple( - ['profile_id', 'label'], - [ - [1, 'nested-label'], - ] - ); - - $this->makeFK('profile', 'user_id', 'user', 'id'); - $this->makeFK('nested', 'profile_id', 'profile', 'id'); - - $this->orm = $this->withSchema(new Schema([ - User::class => [ - Schema::ROLE => 'user', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'user', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'email', 'balance'], - Schema::SCHEMA => [], - Schema::RELATIONS => [ - 'profile' => [ - Relation::TYPE => Relation::HAS_ONE, - Relation::TARGET => Profile::class, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::INNER_KEY => 'id', - Relation::OUTER_KEY => 'user_id', - ], - ], - ], - ], - Profile::class => [ - Schema::ROLE => 'profile', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'profile', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'user_id', 'image'], - Schema::SCHEMA => [], - Schema::RELATIONS => [ - 'user' => [ - Relation::TYPE => Relation::BELONGS_TO, - Relation::TARGET => User::class, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::INNER_KEY => 'user_id', - Relation::OUTER_KEY => 'id', - ], - ], - 'nested' => [ - Relation::TYPE => Relation::HAS_ONE, - Relation::TARGET => Nested::class, - Relation::SCHEMA => [ - Relation::NULLABLE => true, // todo set false and connect with nested:profile - Relation::CASCADE => true, - Relation::INNER_KEY => 'id', - Relation::OUTER_KEY => 'profile_id', - ], - ], - ], - ], - Nested::class => [ - Schema::ROLE => 'nested', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'nested', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'profile_id', 'label'], - Schema::SCHEMA => [], - Schema::RELATIONS => [ - 'profile' => [ - Relation::TYPE => Relation::BELONGS_TO, - Relation::TARGET => Profile::class, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::INNER_KEY => 'profile_id', - Relation::OUTER_KEY => 'id', - ], - ], - ], - ], - ])); - } - public function testFetchRelation(): void { $selector = new Select($this->orm, Profile::class); @@ -222,7 +99,7 @@ public function testFetchRelationInload(): void { $selector = new Select($this->orm, Profile::class); $selector->load('user', ['method' => Select\JoinableLoader::INLOAD]) - ->orderBy('profile.id'); + ->orderBy('profile.id'); $this->assertEquals([ [ @@ -491,7 +368,7 @@ public function testChangeParent(): void ], ], ], (new Select($this->orm, Profile::class))->load('user')->wherePK( - 1 + 1, )->fetchData()); } @@ -516,7 +393,7 @@ public function testExchangeParents(): void $s = new Select($this->orm->withHeap(new Heap()), Profile::class); [$a2, $b2] = $s->wherePK(new Parameter([1, 2]))->orderBy('profile.id') - ->load('user')->fetchAll(); + ->load('user')->fetchAll(); $this->assertSame($a->user->id, $a2->user->id); $this->assertSame($b->user->id, $b2->user->id); @@ -571,8 +448,8 @@ public function testWhereNested(): void { $s = new Select($this->orm->withHeap(new Heap()), Nested::class); $n = $s->with('profile.user') - ->where('profile.user.id', 1) - ->fetchOne(); + ->where('profile.user.id', 1) + ->fetchOne(); $this->assertSame('nested-label', $n->label); } @@ -587,4 +464,127 @@ public function testWhereNestedWithAlias(): void $this->assertSame('nested-label', $n->label); } + + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('user', [ + 'id' => 'primary', + 'email' => 'string', + 'balance' => 'float', + ]); + + $this->getDatabase()->table('user')->insertMultiple( + ['email', 'balance'], + [ + ['hello@world.com', 100], + ['another@world.com', 200], + ], + ); + + $this->makeTable('profile', [ + 'id' => 'primary', + 'user_id' => 'integer', + 'image' => 'string', + ]); + + $this->getDatabase()->table('profile')->insertMultiple( + ['user_id', 'image'], + [ + [1, 'image.png'], + [2, 'second.png'], + [2, 'third.png'], + ], + ); + + $this->makeTable('nested', [ + 'id' => 'primary', + 'profile_id' => 'integer', + 'label' => 'string', + ]); + + $this->getDatabase()->table('nested')->insertMultiple( + ['profile_id', 'label'], + [ + [1, 'nested-label'], + ], + ); + + $this->makeFK('profile', 'user_id', 'user', 'id'); + $this->makeFK('nested', 'profile_id', 'profile', 'id'); + + $this->orm = $this->withSchema(new Schema([ + User::class => [ + Schema::ROLE => 'user', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'user', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'email', 'balance'], + Schema::SCHEMA => [], + Schema::RELATIONS => [ + 'profile' => [ + Relation::TYPE => Relation::HAS_ONE, + Relation::TARGET => Profile::class, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::INNER_KEY => 'id', + Relation::OUTER_KEY => 'user_id', + ], + ], + ], + ], + Profile::class => [ + Schema::ROLE => 'profile', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'profile', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'user_id', 'image'], + Schema::SCHEMA => [], + Schema::RELATIONS => [ + 'user' => [ + Relation::TYPE => Relation::BELONGS_TO, + Relation::TARGET => User::class, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::INNER_KEY => 'user_id', + Relation::OUTER_KEY => 'id', + ], + ], + 'nested' => [ + Relation::TYPE => Relation::HAS_ONE, + Relation::TARGET => Nested::class, + Relation::SCHEMA => [ + Relation::NULLABLE => true, // todo set false and connect with nested:profile + Relation::CASCADE => true, + Relation::INNER_KEY => 'id', + Relation::OUTER_KEY => 'profile_id', + ], + ], + ], + ], + Nested::class => [ + Schema::ROLE => 'nested', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'nested', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'profile_id', 'label'], + Schema::SCHEMA => [], + Schema::RELATIONS => [ + 'profile' => [ + Relation::TYPE => Relation::BELONGS_TO, + Relation::TARGET => Profile::class, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::INNER_KEY => 'profile_id', + Relation::OUTER_KEY => 'id', + ], + ], + ], + ], + ])); + } } diff --git a/tests/ORM/Functional/Driver/Common/Relation/BidirectionTest.php b/tests/ORM/Functional/Driver/Common/Relation/BidirectionTest.php index 085049c5..ff96862b 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/BidirectionTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/BidirectionTest.php @@ -19,88 +19,6 @@ abstract class BidirectionTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('user', [ - 'id' => 'primary', - 'email' => 'string', - 'balance' => 'float', - ]); - - $this->makeTable('comment', [ - 'id' => 'primary', - 'user_id' => 'integer,nullable', - 'message' => 'string', - ], [ - 'user_id' => ['table' => 'user', 'column' => 'id'], - ]); - - $this->makeFK('comment', 'user_id', 'user', 'id'); - - $this->getDatabase()->table('user')->insertMultiple( - ['email', 'balance'], - [ - ['hello@world.com', 100], - ['another@world.com', 200], - ] - ); - - $this->getDatabase()->table('comment')->insertMultiple( - ['user_id', 'message'], - [ - [1, 'msg 1'], - [1, 'msg 2'], - ] - ); - - $this->orm = $this->withSchema(new Schema([ - User::class => [ - Schema::ROLE => 'user', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'user', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'email', 'balance'], - Schema::SCHEMA => [], - Schema::RELATIONS => [ - 'comments' => [ - Relation::TYPE => Relation::HAS_MANY, - Relation::TARGET => Comment::class, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::NULLABLE => true, - Relation::INNER_KEY => 'id', - Relation::OUTER_KEY => 'user_id', - ], - ], - ], - ], - Comment::class => [ - Schema::ROLE => 'comment', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'comment', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'user_id', 'message'], - Schema::SCHEMA => [], - Schema::RELATIONS => [ - 'user' => [ - Relation::TYPE => Relation::BELONGS_TO, - Relation::TARGET => User::class, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::NULLABLE => true, - Relation::INNER_KEY => 'user_id', - Relation::OUTER_KEY => 'id', - ], - ], - ], - ], - ])); - } - public function testFetchData(): void { $selector = new Select($this->orm, User::class); @@ -223,4 +141,86 @@ public function testDoubleRemoval(): void $this->assertCount(1, $u->comments); } + + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('user', [ + 'id' => 'primary', + 'email' => 'string', + 'balance' => 'float', + ]); + + $this->makeTable('comment', [ + 'id' => 'primary', + 'user_id' => 'integer,nullable', + 'message' => 'string', + ], [ + 'user_id' => ['table' => 'user', 'column' => 'id'], + ]); + + $this->makeFK('comment', 'user_id', 'user', 'id'); + + $this->getDatabase()->table('user')->insertMultiple( + ['email', 'balance'], + [ + ['hello@world.com', 100], + ['another@world.com', 200], + ], + ); + + $this->getDatabase()->table('comment')->insertMultiple( + ['user_id', 'message'], + [ + [1, 'msg 1'], + [1, 'msg 2'], + ], + ); + + $this->orm = $this->withSchema(new Schema([ + User::class => [ + Schema::ROLE => 'user', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'user', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'email', 'balance'], + Schema::SCHEMA => [], + Schema::RELATIONS => [ + 'comments' => [ + Relation::TYPE => Relation::HAS_MANY, + Relation::TARGET => Comment::class, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::NULLABLE => true, + Relation::INNER_KEY => 'id', + Relation::OUTER_KEY => 'user_id', + ], + ], + ], + ], + Comment::class => [ + Schema::ROLE => 'comment', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'comment', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'user_id', 'message'], + Schema::SCHEMA => [], + Schema::RELATIONS => [ + 'user' => [ + Relation::TYPE => Relation::BELONGS_TO, + Relation::TARGET => User::class, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::NULLABLE => true, + Relation::INNER_KEY => 'user_id', + Relation::OUTER_KEY => 'id', + ], + ], + ], + ], + ])); + } } diff --git a/tests/ORM/Functional/Driver/Common/Relation/CyclicReferencesTest.php b/tests/ORM/Functional/Driver/Common/Relation/CyclicReferencesTest.php index e56557a4..ccb02a8a 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/CyclicReferencesTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/CyclicReferencesTest.php @@ -21,136 +21,6 @@ abstract class CyclicReferencesTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('user', [ - 'id' => 'primary', - 'email' => 'string', - 'balance' => 'float', - 'comment_id' => 'integer,nullable', - ]); - - $this->makeTable('comment', [ - 'id' => 'primary', - 'user_id' => 'integer', - 'message' => 'string', - ], [ - 'user_id' => ['table' => 'user', 'column' => 'id'], - ]); - - $this->makeTable('favorites', [ - 'id' => 'primary', - 'user_id' => 'integer', - 'comment_id' => 'integer', - ]); - - $this->makeFK('comment', 'user_id', 'user', 'id'); - $this->makeFK( - 'favorites', - 'user_id', - 'user', - 'id', - ForeignKeyInterface::NO_ACTION, - ForeignKeyInterface::NO_ACTION - ); - $this->makeFK( - 'favorites', - 'comment_id', - 'comment', - 'id', - ForeignKeyInterface::NO_ACTION, - ForeignKeyInterface::NO_ACTION - ); - $this->orm = $this->withSchema(new Schema([ - User::class => [ - Schema::ROLE => 'user', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'user', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'email', 'balance', 'comment_id'], - Schema::SCHEMA => [], - Schema::RELATIONS => [ - 'lastComment' => [ - Relation::TYPE => Relation::REFERS_TO, - Relation::TARGET => Comment::class, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::INNER_KEY => 'comment_id', - Relation::OUTER_KEY => 'id', - Relation::NULLABLE => true, - ], - ], - 'comments' => [ - Relation::TYPE => Relation::HAS_MANY, - Relation::TARGET => Comment::class, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::INNER_KEY => 'id', - Relation::OUTER_KEY => 'user_id', - ], - ], - 'favorites' => [ - Relation::TYPE => Relation::MANY_TO_MANY, - Relation::TARGET => Comment::class, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::THROUGH_ENTITY => Favorite::class, - Relation::INNER_KEY => 'id', - Relation::OUTER_KEY => 'id', - Relation::THROUGH_INNER_KEY => 'user_id', - Relation::THROUGH_OUTER_KEY => 'comment_id', - ], - ], - ], - ], - Comment::class => [ - Schema::ROLE => 'comment', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'comment', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'user_id', 'message'], - Schema::SCHEMA => [], - Schema::RELATIONS => [ - 'user' => [ - Relation::TYPE => Relation::BELONGS_TO, - Relation::TARGET => User::class, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::INNER_KEY => 'user_id', - Relation::OUTER_KEY => 'id', - ], - ], - 'favoredBy' => [ - Relation::TYPE => Relation::MANY_TO_MANY, - Relation::TARGET => User::class, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::THROUGH_ENTITY => Favorite::class, - Relation::INNER_KEY => 'id', - Relation::OUTER_KEY => 'id', - Relation::THROUGH_INNER_KEY => 'comment_id', - Relation::THROUGH_OUTER_KEY => 'user_id', - ], - ], - ], - ], - Favorite::class => [ - Schema::ROLE => 'favorite', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'favorites', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'user_id', 'comment_id'], - Schema::SCHEMA => [], - Schema::RELATIONS => [], - ], - ])); - } - public function testCreate(): void { $u = new User(); @@ -182,9 +52,9 @@ public function testCreate(): void $this->orm = $this->orm->withHeap(new Heap()); $selector = new Select($this->orm, User::class); $selector->load('lastComment.user') - ->load('comments.user') - ->load('comments.favoredBy') - ->load('favorites'); + ->load('comments.user') + ->load('comments.favoredBy') + ->load('favorites'); $u1 = $selector->wherePK(1)->fetchOne(); @@ -242,12 +112,12 @@ public function testCreateMultipleLinkedTrees(): void $this->assertEquals($u->favorites[0]->user->id, $u1->favorites[0]->user->id); $fav = [ - (string)$u1->favorites[0]->favoredBy[0]->id, - (string)$u1->favorites[0]->favoredBy[1]->id, + (string) $u1->favorites[0]->favoredBy[0]->id, + (string) $u1->favorites[0]->favoredBy[1]->id, ]; - $this->assertContains((string)$u->id, $fav); - $this->assertContains((string)$u2->id, $fav); + $this->assertContains((string) $u->id, $fav); + $this->assertContains((string) $u2->id, $fav); $this->orm = $this->orm->withHeap(new Heap()); @@ -304,4 +174,134 @@ public function testCreateMultipleLinkedTreesExchange(): void $tr->run(); $this->assertNumWrites(0); } + + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('user', [ + 'id' => 'primary', + 'email' => 'string', + 'balance' => 'float', + 'comment_id' => 'integer,nullable', + ]); + + $this->makeTable('comment', [ + 'id' => 'primary', + 'user_id' => 'integer', + 'message' => 'string', + ], [ + 'user_id' => ['table' => 'user', 'column' => 'id'], + ]); + + $this->makeTable('favorites', [ + 'id' => 'primary', + 'user_id' => 'integer', + 'comment_id' => 'integer', + ]); + + $this->makeFK('comment', 'user_id', 'user', 'id'); + $this->makeFK( + 'favorites', + 'user_id', + 'user', + 'id', + ForeignKeyInterface::NO_ACTION, + ForeignKeyInterface::NO_ACTION, + ); + $this->makeFK( + 'favorites', + 'comment_id', + 'comment', + 'id', + ForeignKeyInterface::NO_ACTION, + ForeignKeyInterface::NO_ACTION, + ); + $this->orm = $this->withSchema(new Schema([ + User::class => [ + Schema::ROLE => 'user', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'user', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'email', 'balance', 'comment_id'], + Schema::SCHEMA => [], + Schema::RELATIONS => [ + 'lastComment' => [ + Relation::TYPE => Relation::REFERS_TO, + Relation::TARGET => Comment::class, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::INNER_KEY => 'comment_id', + Relation::OUTER_KEY => 'id', + Relation::NULLABLE => true, + ], + ], + 'comments' => [ + Relation::TYPE => Relation::HAS_MANY, + Relation::TARGET => Comment::class, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::INNER_KEY => 'id', + Relation::OUTER_KEY => 'user_id', + ], + ], + 'favorites' => [ + Relation::TYPE => Relation::MANY_TO_MANY, + Relation::TARGET => Comment::class, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::THROUGH_ENTITY => Favorite::class, + Relation::INNER_KEY => 'id', + Relation::OUTER_KEY => 'id', + Relation::THROUGH_INNER_KEY => 'user_id', + Relation::THROUGH_OUTER_KEY => 'comment_id', + ], + ], + ], + ], + Comment::class => [ + Schema::ROLE => 'comment', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'comment', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'user_id', 'message'], + Schema::SCHEMA => [], + Schema::RELATIONS => [ + 'user' => [ + Relation::TYPE => Relation::BELONGS_TO, + Relation::TARGET => User::class, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::INNER_KEY => 'user_id', + Relation::OUTER_KEY => 'id', + ], + ], + 'favoredBy' => [ + Relation::TYPE => Relation::MANY_TO_MANY, + Relation::TARGET => User::class, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::THROUGH_ENTITY => Favorite::class, + Relation::INNER_KEY => 'id', + Relation::OUTER_KEY => 'id', + Relation::THROUGH_INNER_KEY => 'comment_id', + Relation::THROUGH_OUTER_KEY => 'user_id', + ], + ], + ], + ], + Favorite::class => [ + Schema::ROLE => 'favorite', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'favorites', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'user_id', 'comment_id'], + Schema::SCHEMA => [], + Schema::RELATIONS => [], + ], + ])); + } } diff --git a/tests/ORM/Functional/Driver/Common/Relation/DeepCyclicTest.php b/tests/ORM/Functional/Driver/Common/Relation/DeepCyclicTest.php index 3bdc113a..09c567e6 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/DeepCyclicTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/DeepCyclicTest.php @@ -18,52 +18,6 @@ abstract class DeepCyclicTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('cyclic', [ - 'id' => 'primary', - 'name' => 'string', - 'parent_id' => 'integer,nullable', - 'other_id' => 'integer,nullable', - ]); - - $this->orm = $this->withSchema(new Schema([ - Cyclic::class => [ - Schema::ROLE => 'cyclic', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'cyclic', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'parent_id', 'other_id', 'name'], - Schema::SCHEMA => [], - Schema::RELATIONS => [ - 'cyclic' => [ - Relation::TYPE => Relation::HAS_ONE, - Relation::TARGET => Cyclic::class, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::NULLABLE => true, - Relation::INNER_KEY => 'id', - Relation::OUTER_KEY => 'parent_id', - ], - ], - 'other' => [ - Relation::TYPE => Relation::HAS_ONE, - Relation::TARGET => Cyclic::class, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::NULLABLE => true, - Relation::INNER_KEY => 'id', - Relation::OUTER_KEY => 'other_id', - ], - ], - ], - ], - ])); - } - public function testCreateDeepCyclic(): void { $c1 = new Cyclic('C1'); @@ -262,4 +216,50 @@ public function testOverlappingCycles(): void $this->assertSame($c1->other, $c5); $this->assertSame($c5->other, $c2); } + + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('cyclic', [ + 'id' => 'primary', + 'name' => 'string', + 'parent_id' => 'integer,nullable', + 'other_id' => 'integer,nullable', + ]); + + $this->orm = $this->withSchema(new Schema([ + Cyclic::class => [ + Schema::ROLE => 'cyclic', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'cyclic', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'parent_id', 'other_id', 'name'], + Schema::SCHEMA => [], + Schema::RELATIONS => [ + 'cyclic' => [ + Relation::TYPE => Relation::HAS_ONE, + Relation::TARGET => Cyclic::class, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::NULLABLE => true, + Relation::INNER_KEY => 'id', + Relation::OUTER_KEY => 'parent_id', + ], + ], + 'other' => [ + Relation::TYPE => Relation::HAS_ONE, + Relation::TARGET => Cyclic::class, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::NULLABLE => true, + Relation::INNER_KEY => 'id', + Relation::OUTER_KEY => 'other_id', + ], + ], + ], + ], + ])); + } } diff --git a/tests/ORM/Functional/Driver/Common/Relation/DoubleLinkedTest.php b/tests/ORM/Functional/Driver/Common/Relation/DoubleLinkedTest.php index 470617dc..901b9938 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/DoubleLinkedTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/DoubleLinkedTest.php @@ -18,54 +18,6 @@ abstract class DoubleLinkedTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('cyclic', [ - 'id' => 'primary', - 'name' => 'string', - 'parent_id' => 'integer,nullable', - ]); - - $this->orm = $this->withSchema(new Schema([ - Cyclic::class => [ - Schema::ROLE => 'cyclic', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'cyclic', - Schema::PRIMARY_KEY => 'id', - Schema::FIND_BY_KEYS => ['parent_id'], - Schema::COLUMNS => ['id', 'parent_id', 'name'], - Schema::SCHEMA => [], - Schema::RELATIONS => [ - 'cyclic' => [ - Relation::TYPE => Relation::HAS_ONE, - Relation::TARGET => Cyclic::class, - Relation::LOAD => Relation::LOAD_PROMISE, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::NULLABLE => true, - Relation::INNER_KEY => 'id', - Relation::OUTER_KEY => 'parent_id', - ], - ], - 'other' => [ - Relation::TYPE => Relation::REFERS_TO, - Relation::TARGET => Cyclic::class, - Relation::LOAD => Relation::LOAD_PROMISE, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::NULLABLE => true, - Relation::INNER_KEY => 'parent_id', - Relation::OUTER_KEY => 'id', - ], - ], - ], - ], - ])); - } - public function testCreateDoubleLink(): void { $c1 = new Cyclic(); @@ -151,4 +103,52 @@ public function testSelfReference(): void $this->assertSame($a, $a->other); $this->assertNumReads(0); } + + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('cyclic', [ + 'id' => 'primary', + 'name' => 'string', + 'parent_id' => 'integer,nullable', + ]); + + $this->orm = $this->withSchema(new Schema([ + Cyclic::class => [ + Schema::ROLE => 'cyclic', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'cyclic', + Schema::PRIMARY_KEY => 'id', + Schema::FIND_BY_KEYS => ['parent_id'], + Schema::COLUMNS => ['id', 'parent_id', 'name'], + Schema::SCHEMA => [], + Schema::RELATIONS => [ + 'cyclic' => [ + Relation::TYPE => Relation::HAS_ONE, + Relation::TARGET => Cyclic::class, + Relation::LOAD => Relation::LOAD_PROMISE, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::NULLABLE => true, + Relation::INNER_KEY => 'id', + Relation::OUTER_KEY => 'parent_id', + ], + ], + 'other' => [ + Relation::TYPE => Relation::REFERS_TO, + Relation::TARGET => Cyclic::class, + Relation::LOAD => Relation::LOAD_PROMISE, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::NULLABLE => true, + Relation::INNER_KEY => 'parent_id', + Relation::OUTER_KEY => 'id', + ], + ], + ], + ], + ])); + } } diff --git a/tests/ORM/Functional/Driver/Common/Relation/Eager2Test.php b/tests/ORM/Functional/Driver/Common/Relation/Eager2Test.php index b32765a9..741d3a42 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/Eager2Test.php +++ b/tests/ORM/Functional/Driver/Common/Relation/Eager2Test.php @@ -18,6 +18,40 @@ abstract class Eager2Test extends BaseTest { use TableTrait; + public function testFetchEager(): void + { + $selector = new Select($this->orm, User::class); + + $this->assertEquals([ + [ + 'id' => 1, + 'email' => 'hello@world.com', + 'balance' => 100.0, + ], + [ + 'id' => 2, + 'email' => 'another@world.com', + 'balance' => 200.0, + ], + ], $selector->fetchData()); + } + + public function testFetchEager2(): void + { + $selector = new Select($this->orm, User::class); + $selector->where('profile.id', '>', 0); + + $this->assertCount(3, $selector->buildQuery()->getColumns()); + + $this->assertEquals([ + [ + 'id' => 1, + 'email' => 'hello@world.com', + 'balance' => 100.0, + ], + ], $selector->fetchData()); + } + public function setUp(): void { parent::setUp(); @@ -48,14 +82,14 @@ public function setUp(): void [ ['hello@world.com', 100], ['another@world.com', 200], - ] + ], ); $this->getDatabase()->table('profile')->insertMultiple( ['user_id', 'image'], [ [1, 'image.png'], - ] + ], ); @@ -63,7 +97,7 @@ public function setUp(): void ['profile_id', 'label'], [ [1, 'nested-label'], - ] + ], ); $this->orm = $this->withSchema(new Schema([ @@ -121,38 +155,4 @@ public function setUp(): void ], ])); } - - public function testFetchEager(): void - { - $selector = new Select($this->orm, User::class); - - $this->assertEquals([ - [ - 'id' => 1, - 'email' => 'hello@world.com', - 'balance' => 100.0, - ], - [ - 'id' => 2, - 'email' => 'another@world.com', - 'balance' => 200.0, - ], - ], $selector->fetchData()); - } - - public function testFetchEager2(): void - { - $selector = new Select($this->orm, User::class); - $selector->where('profile.id', '>', 0); - - $this->assertCount(3, $selector->buildQuery()->getColumns()); - - $this->assertEquals([ - [ - 'id' => 1, - 'email' => 'hello@world.com', - 'balance' => 100.0, - ], - ], $selector->fetchData()); - } } diff --git a/tests/ORM/Functional/Driver/Common/Relation/EagerTest.php b/tests/ORM/Functional/Driver/Common/Relation/EagerTest.php index 4194e05c..077d883a 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/EagerTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/EagerTest.php @@ -18,6 +18,35 @@ abstract class EagerTest extends BaseTest { use TableTrait; + public function testFetchEager(): void + { + $selector = new Select($this->orm, User::class); + + $this->assertEquals([ + [ + 'id' => 1, + 'email' => 'hello@world.com', + 'balance' => 100.0, + 'profile' => [ + 'id' => 1, + 'user_id' => 1, + 'image' => 'image.png', + 'nested' => [ + 'id' => 1, + 'profile_id' => 1, + 'label' => 'nested-label', + ], + ], + ], + [ + 'id' => 2, + 'email' => 'another@world.com', + 'balance' => 200.0, + 'profile' => null, + ], + ], $selector->fetchData()); + } + public function setUp(): void { parent::setUp(); @@ -48,14 +77,14 @@ public function setUp(): void [ ['hello@world.com', 100], ['another@world.com', 200], - ] + ], ); $this->getDatabase()->table('profile')->insertMultiple( ['user_id', 'image'], [ [1, 'image.png'], - ] + ], ); @@ -63,7 +92,7 @@ public function setUp(): void ['profile_id', 'label'], [ [1, 'nested-label'], - ] + ], ); $this->orm = $this->withSchema(new Schema([ @@ -121,33 +150,4 @@ public function setUp(): void ], ])); } - - public function testFetchEager(): void - { - $selector = new Select($this->orm, User::class); - - $this->assertEquals([ - [ - 'id' => 1, - 'email' => 'hello@world.com', - 'balance' => 100.0, - 'profile' => [ - 'id' => 1, - 'user_id' => 1, - 'image' => 'image.png', - 'nested' => [ - 'id' => 1, - 'profile_id' => 1, - 'label' => 'nested-label', - ], - ], - ], - [ - 'id' => 2, - 'email' => 'another@world.com', - 'balance' => 200.0, - 'profile' => null, - ], - ], $selector->fetchData()); - } } diff --git a/tests/ORM/Functional/Driver/Common/Relation/Embedded/DeepEmbeddedTest.php b/tests/ORM/Functional/Driver/Common/Relation/Embedded/DeepEmbeddedTest.php index 1da4ce92..191d826a 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/Embedded/DeepEmbeddedTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/Embedded/DeepEmbeddedTest.php @@ -18,109 +18,6 @@ abstract class DeepEmbeddedTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable( - 'group', - [ - 'id' => 'primary', - 'name' => 'string', - ] - ); - - $this->makeTable( - 'user', - [ - 'id' => 'primary', - 'group_id' => 'int', - 'email' => 'string', - 'balance' => 'float', - 'creds_username' => 'string', - 'creds_password' => 'string', - ] - ); - - $this->getDatabase()->table('group')->insertMultiple( - ['name'], - [ - ['first'], - ['second'], - ] - ); - - $this->getDatabase()->table('user')->insertMultiple( - ['email', 'group_id', 'balance', 'creds_username', 'creds_password'], - [ - ['hello@world.com', 1, 100, 'user1', 'pass1'], - ['another@world.com', 1, 200, 'user2', 'pass2'], - ['third@world.com', 2, 200, 'user3', 'pass3'], - ] - ); - - $this->orm = $this->withSchema( - new Schema( - [ - Group::class => [ - Schema::ROLE => 'group', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'group', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'name'], - Schema::SCHEMA => [], - Schema::TYPECAST => ['id' => 'int'], - Schema::RELATIONS => [ - 'users' => [ - Relation::TYPE => Relation::HAS_MANY, - Relation::TARGET => User::class, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::INNER_KEY => 'id', - Relation::OUTER_KEY => 'group_id', - ], - ], - ], - ], - User::class => [ - Schema::ROLE => 'user', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'user', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'group_id', 'email', 'balance'], - Schema::SCHEMA => [], - Schema::TYPECAST => ['id' => 'int', 'group_id' => 'int', 'balance' => 'float'], - Schema::RELATIONS => [ - 'credentials' => [ - Relation::TYPE => Relation::EMBEDDED, - Relation::TARGET => 'user:credentials', - Relation::LOAD => Relation::LOAD_EAGER, // IMPORTANT! - Relation::SCHEMA => [], - ], - ], - ], - UserCredentials::class => [ - Schema::ROLE => 'user:credentials', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'user', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => [ - 'id' => 'id', - 'username' => 'creds_username', - 'password' => 'creds_password', - ], - Schema::SCHEMA => [], - Schema::TYPECAST => ['id' => 'int'], - Schema::RELATIONS => [], - ], - ] - ) - ); - } - public function testFetchData(): void { $selector = new Select($this->orm, Group::class); @@ -171,7 +68,7 @@ public function testFetchData(): void ], ], ], - $selector->fetchData() + $selector->fetchData(), ); } @@ -191,7 +88,7 @@ public function testWithRelationIgnoreEager(): void 'name' => 'second', ], ], - $selector->fetchData() + $selector->fetchData(), ); // only parent entity! @@ -202,9 +99,9 @@ public function testFetchDataViaJoin(): void { $selector = new Select($this->orm, Group::class); $selector->with('users', ['as' => 'users']) - ->load('users', ['using' => 'users']) - ->orderBy('id', 'ASC') - ->orderBy('users.id', 'ASC'); + ->load('users', ['using' => 'users']) + ->orderBy('id', 'ASC') + ->orderBy('users.id', 'ASC'); $this->assertSame( [ @@ -251,9 +148,112 @@ public function testFetchDataViaJoin(): void ], ], ], - $selector->fetchData() + $selector->fetchData(), ); $this->assertCount(8, $selector->buildQuery()->getColumns()); } + + public function setUp(): void + { + parent::setUp(); + + $this->makeTable( + 'group', + [ + 'id' => 'primary', + 'name' => 'string', + ], + ); + + $this->makeTable( + 'user', + [ + 'id' => 'primary', + 'group_id' => 'int', + 'email' => 'string', + 'balance' => 'float', + 'creds_username' => 'string', + 'creds_password' => 'string', + ], + ); + + $this->getDatabase()->table('group')->insertMultiple( + ['name'], + [ + ['first'], + ['second'], + ], + ); + + $this->getDatabase()->table('user')->insertMultiple( + ['email', 'group_id', 'balance', 'creds_username', 'creds_password'], + [ + ['hello@world.com', 1, 100, 'user1', 'pass1'], + ['another@world.com', 1, 200, 'user2', 'pass2'], + ['third@world.com', 2, 200, 'user3', 'pass3'], + ], + ); + + $this->orm = $this->withSchema( + new Schema( + [ + Group::class => [ + Schema::ROLE => 'group', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'group', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'name'], + Schema::SCHEMA => [], + Schema::TYPECAST => ['id' => 'int'], + Schema::RELATIONS => [ + 'users' => [ + Relation::TYPE => Relation::HAS_MANY, + Relation::TARGET => User::class, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::INNER_KEY => 'id', + Relation::OUTER_KEY => 'group_id', + ], + ], + ], + ], + User::class => [ + Schema::ROLE => 'user', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'user', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'group_id', 'email', 'balance'], + Schema::SCHEMA => [], + Schema::TYPECAST => ['id' => 'int', 'group_id' => 'int', 'balance' => 'float'], + Schema::RELATIONS => [ + 'credentials' => [ + Relation::TYPE => Relation::EMBEDDED, + Relation::TARGET => 'user:credentials', + Relation::LOAD => Relation::LOAD_EAGER, // IMPORTANT! + Relation::SCHEMA => [], + ], + ], + ], + UserCredentials::class => [ + Schema::ROLE => 'user:credentials', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'user', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => [ + 'id' => 'id', + 'username' => 'creds_username', + 'password' => 'creds_password', + ], + Schema::SCHEMA => [], + Schema::TYPECAST => ['id' => 'int'], + Schema::RELATIONS => [], + ], + ], + ), + ); + } } diff --git a/tests/ORM/Functional/Driver/Common/Relation/Embedded/EmbeddedCompositeKeyTest.php b/tests/ORM/Functional/Driver/Common/Relation/Embedded/EmbeddedCompositeKeyTest.php index 99d781e6..3c4a0dbe 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/Embedded/EmbeddedCompositeKeyTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/Embedded/EmbeddedCompositeKeyTest.php @@ -19,60 +19,22 @@ abstract class EmbeddedCompositeKeyTest extends BaseTest { use TableTrait; - protected const - CHILD_CONTAINER = 'child_entity'; - protected const - CHILD_ROLE = 'parent_entity:' . self::CHILD_CONTAINER; - protected const - KEY_1 = ['key1' => 1, 'key2' => 1]; - protected const - KEY_2 = ['key1' => 1, 'key2' => 2]; - protected const - KEY_3 = ['key1' => 2, 'key2' => 1]; - protected const - PARENT_1 = ['key3' => 1]; - protected const - PARENT_2 = ['key3' => 2]; - protected const - PARENT_3 = ['key3' => 3]; - protected const - CHILD_1 = ['key3' => 'foo']; - protected const - CHILD_2 = ['key3' => 'bar']; - protected const - CHILD_3 = ['key3' => 'baz']; - protected const - ALL_LOADED = [ - self::KEY_1 + self::PARENT_1 + [self::CHILD_CONTAINER => self::CHILD_1], - self::KEY_2 + self::PARENT_2 + [self::CHILD_CONTAINER => self::CHILD_2], - self::KEY_3 + self::PARENT_3 + [self::CHILD_CONTAINER => self::CHILD_3], - ]; - - public function setUp(): void - { - parent::setUp(); - - $this->makeTable( - 'parent_entity', - [ - 'pField1' => 'bigInteger,primary', - 'pField2' => 'bigInteger,primary', - 'pField3' => 'integer', - 'cField3' => 'string', - ] - ); - - $this->getDatabase()->table('parent_entity')->insertMultiple( - ['pField1', 'pField2', 'pField3', 'cField3'], - [ - array_merge(self::KEY_1, array_values(self::PARENT_1), array_values(self::CHILD_1)), - array_merge(self::KEY_2, array_values(self::PARENT_2), array_values(self::CHILD_2)), - array_merge(self::KEY_3, array_values(self::PARENT_3), array_values(self::CHILD_3)), - ] - ); - - $this->orm = $this->withSchema(new Schema($this->getSchemaArray())); - } + protected const CHILD_CONTAINER = 'child_entity'; + protected const CHILD_ROLE = 'parent_entity:' . self::CHILD_CONTAINER; + protected const KEY_1 = ['key1' => 1, 'key2' => 1]; + protected const KEY_2 = ['key1' => 1, 'key2' => 2]; + protected const KEY_3 = ['key1' => 2, 'key2' => 1]; + protected const PARENT_1 = ['key3' => 1]; + protected const PARENT_2 = ['key3' => 2]; + protected const PARENT_3 = ['key3' => 3]; + protected const CHILD_1 = ['key3' => 'foo']; + protected const CHILD_2 = ['key3' => 'bar']; + protected const CHILD_3 = ['key3' => 'baz']; + protected const ALL_LOADED = [ + self::KEY_1 + self::PARENT_1 + [self::CHILD_CONTAINER => self::CHILD_1], + self::KEY_2 + self::PARENT_2 + [self::CHILD_CONTAINER => self::CHILD_2], + self::KEY_3 + self::PARENT_3 + [self::CHILD_CONTAINER => self::CHILD_3], + ]; public function testFetchData(): void { @@ -160,7 +122,7 @@ public function testUpdateEmbeddedValue(): void [ 'pField1' => $u->key1, 'pField2' => $u->key2, - ] + ], )->run(); $this->captureWriteQueries(); @@ -398,6 +360,32 @@ public function testNullify(): void $this->assertSame('user3', $u2->child_entity->key3); } + public function setUp(): void + { + parent::setUp(); + + $this->makeTable( + 'parent_entity', + [ + 'pField1' => 'bigInteger,primary', + 'pField2' => 'bigInteger,primary', + 'pField3' => 'integer', + 'cField3' => 'string', + ], + ); + + $this->getDatabase()->table('parent_entity')->insertMultiple( + ['pField1', 'pField2', 'pField3', 'cField3'], + [ + array_merge(self::KEY_1, array_values(self::PARENT_1), array_values(self::CHILD_1)), + array_merge(self::KEY_2, array_values(self::PARENT_2), array_values(self::CHILD_2)), + array_merge(self::KEY_3, array_values(self::PARENT_3), array_values(self::CHILD_3)), + ], + ); + + $this->orm = $this->withSchema(new Schema($this->getSchemaArray())); + } + private function getSchemaArray(): array { return [ diff --git a/tests/ORM/Functional/Driver/Common/Relation/Embedded/EmbeddedLoaderTest.php b/tests/ORM/Functional/Driver/Common/Relation/Embedded/EmbeddedLoaderTest.php index 554d2524..d72b37e5 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/Embedded/EmbeddedLoaderTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/Embedded/EmbeddedLoaderTest.php @@ -19,100 +19,6 @@ abstract class EmbeddedLoaderTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('user', [ - 'id' => 'primary', - 'email' => 'string', - 'balance' => 'float', - 'creds_username' => 'string', - 'creds_password' => 'string', - 'creds_num_logins' => 'int', - ]); - - $this->makeTable('comment', [ - 'id' => 'primary', - 'user_id' => 'integer,null', - 'message' => 'string', - ]); - - $this->makeFK('comment', 'user_id', 'user', 'id'); - - $this->getDatabase()->table('user')->insertMultiple( - ['email', 'balance', 'creds_username', 'creds_password', 'creds_num_logins'], - [ - ['hello@world.com', 100, 'user1', 'pass1', 0], - ['another@world.com', 200, 'user2', 'pass2', 1], - ] - ); - - $this->getDatabase()->table('comment')->insertMultiple( - ['user_id', 'message'], - [ - [1, 'msg 1'], - [1, 'msg 2'], - [2, 'msg 3'], - ] - ); - - $this->orm = $this->withSchema(new Schema([ - User::class => [ - Schema::ROLE => 'user', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'user', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'email', 'balance'], - Schema::SCHEMA => [], - Schema::RELATIONS => [ - 'credentials' => [ - Relation::TYPE => Relation::EMBEDDED, - Relation::TARGET => UserCredentials::class, - Relation::LOAD => null, - Relation::SCHEMA => [], - ], - 'comments' => [ - Relation::TYPE => Relation::HAS_MANY, - Relation::TARGET => Comment::class, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::INNER_KEY => 'id', - Relation::OUTER_KEY => 'user_id', - ], - ], - ], - ], - UserCredentials::class => [ - Schema::ROLE => 'user_credentials', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'user', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => [ - 'id' => 'id', - 'username' => 'creds_username', - 'password' => 'creds_password', - 'num_logins' => 'creds_num_logins', - ], - Schema::SCHEMA => [], - Schema::RELATIONS => [], - ], - Comment::class => [ - Schema::ROLE => 'comment', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'comment', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'user_id', 'message'], - Schema::SCHEMA => [], - Schema::RELATIONS => [], - Schema::SCOPE => SortByIDScope::class, - ], - ])); - } - public function testLoadDataNoRelation(): void { $selector = new Select($this->orm, User::class); @@ -429,4 +335,98 @@ public function testDeduplicateInload(): void ], ], $selector->fetchData()); } + + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('user', [ + 'id' => 'primary', + 'email' => 'string', + 'balance' => 'float', + 'creds_username' => 'string', + 'creds_password' => 'string', + 'creds_num_logins' => 'int', + ]); + + $this->makeTable('comment', [ + 'id' => 'primary', + 'user_id' => 'integer,null', + 'message' => 'string', + ]); + + $this->makeFK('comment', 'user_id', 'user', 'id'); + + $this->getDatabase()->table('user')->insertMultiple( + ['email', 'balance', 'creds_username', 'creds_password', 'creds_num_logins'], + [ + ['hello@world.com', 100, 'user1', 'pass1', 0], + ['another@world.com', 200, 'user2', 'pass2', 1], + ], + ); + + $this->getDatabase()->table('comment')->insertMultiple( + ['user_id', 'message'], + [ + [1, 'msg 1'], + [1, 'msg 2'], + [2, 'msg 3'], + ], + ); + + $this->orm = $this->withSchema(new Schema([ + User::class => [ + Schema::ROLE => 'user', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'user', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'email', 'balance'], + Schema::SCHEMA => [], + Schema::RELATIONS => [ + 'credentials' => [ + Relation::TYPE => Relation::EMBEDDED, + Relation::TARGET => UserCredentials::class, + Relation::LOAD => null, + Relation::SCHEMA => [], + ], + 'comments' => [ + Relation::TYPE => Relation::HAS_MANY, + Relation::TARGET => Comment::class, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::INNER_KEY => 'id', + Relation::OUTER_KEY => 'user_id', + ], + ], + ], + ], + UserCredentials::class => [ + Schema::ROLE => 'user_credentials', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'user', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => [ + 'id' => 'id', + 'username' => 'creds_username', + 'password' => 'creds_password', + 'num_logins' => 'creds_num_logins', + ], + Schema::SCHEMA => [], + Schema::RELATIONS => [], + ], + Comment::class => [ + Schema::ROLE => 'comment', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'comment', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'user_id', 'message'], + Schema::SCHEMA => [], + Schema::RELATIONS => [], + Schema::SCOPE => SortByIDScope::class, + ], + ])); + } } diff --git a/tests/ORM/Functional/Driver/Common/Relation/Embedded/EmbeddedRelationTest.php b/tests/ORM/Functional/Driver/Common/Relation/Embedded/EmbeddedRelationTest.php index e02efd44..0458548d 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/Embedded/EmbeddedRelationTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/Embedded/EmbeddedRelationTest.php @@ -21,61 +21,6 @@ abstract class EmbeddedRelationTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('user', [ - 'id' => 'primary', - 'email' => 'string', - 'balance' => 'float', - 'creds_username' => 'string', - 'creds_password' => 'string', - ]); - - $this->getDatabase()->table('user')->insertMultiple( - ['email', 'balance', 'creds_username', 'creds_password'], - [ - ['hello@world.com', 100, 'user1', 'pass1'], - ['another@world.com', 200, 'user2', 'pass2'], - ] - ); - - $this->orm = $this->withSchema(new Schema([ - User::class => [ - Schema::ROLE => 'user', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'user', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'email', 'balance'], - Schema::SCHEMA => [], - Schema::RELATIONS => [ - 'credentials' => [ - Relation::TYPE => Relation::EMBEDDED, - Relation::TARGET => 'user:credentials', - Relation::LOAD => Relation::LOAD_PROMISE, - Relation::SCHEMA => [], - ], - ], - ], - UserCredentials::class => [ - Schema::ROLE => 'user:credentials', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'user', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => [ - 'id' => 'id', - 'username' => 'creds_username', - 'password' => 'creds_password', - ], - Schema::SCHEMA => [], - Schema::RELATIONS => [], - ], - ])); - } - public function testFetchData(): void { $selector = new Select($this->orm, User::class); @@ -138,7 +83,7 @@ public function testCreateUserWithEmbedded(): void $this->save($u); $this->assertNumWrites(1); - $this->assertSame(3, (int)$u->id); + $this->assertSame(3, (int) $u->id); $selector = new Select($this->orm->withHeap(new Heap()), User::class); $u2 = $selector->load('credentials')->wherePK($u->id)->fetchOne(); @@ -174,7 +119,7 @@ public function testUpdateEmbeddedValue(): void ], [ 'id' => $u->id, - ] + ], )->run(); $this->captureWriteQueries(); @@ -430,4 +375,59 @@ public function testNullify(): void $this->assertEquals($u->id, $u2->id); $this->assertSame('user3', $u2->credentials->username); } + + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('user', [ + 'id' => 'primary', + 'email' => 'string', + 'balance' => 'float', + 'creds_username' => 'string', + 'creds_password' => 'string', + ]); + + $this->getDatabase()->table('user')->insertMultiple( + ['email', 'balance', 'creds_username', 'creds_password'], + [ + ['hello@world.com', 100, 'user1', 'pass1'], + ['another@world.com', 200, 'user2', 'pass2'], + ], + ); + + $this->orm = $this->withSchema(new Schema([ + User::class => [ + Schema::ROLE => 'user', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'user', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'email', 'balance'], + Schema::SCHEMA => [], + Schema::RELATIONS => [ + 'credentials' => [ + Relation::TYPE => Relation::EMBEDDED, + Relation::TARGET => 'user:credentials', + Relation::LOAD => Relation::LOAD_PROMISE, + Relation::SCHEMA => [], + ], + ], + ], + UserCredentials::class => [ + Schema::ROLE => 'user:credentials', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'user', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => [ + 'id' => 'id', + 'username' => 'creds_username', + 'password' => 'creds_password', + ], + Schema::SCHEMA => [], + Schema::RELATIONS => [], + ], + ])); + } } diff --git a/tests/ORM/Functional/Driver/Common/Relation/ExistingNestedRelationTest.php b/tests/ORM/Functional/Driver/Common/Relation/ExistingNestedRelationTest.php index 4b0fd269..63c038df 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/ExistingNestedRelationTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/ExistingNestedRelationTest.php @@ -20,6 +20,39 @@ abstract class ExistingNestedRelationTest extends BaseTest { use TableTrait; + public function testCreateForExisting(): void + { + $u = new User(); + $u->email = 'test@email.com'; + $u->balance = 1000; + + $this->captureWriteQueries(); + + $tr = new Transaction($this->orm); + $tr->persist($u); + $tr->run(); + + $this->assertNumWrites(1); + + $this->orm = $this->orm->withHeap(new Heap()); + + $selector = new Select($this->orm, User::class); + /** @var User $u */ + $u = $selector->wherePK($u->id)->fetchOne(); + + $c = new Comment(); + $c->user = $u; + $c->message = 'hello world'; + + $u->addComment($c); + + $this->captureWriteQueries(); + $tr = new Transaction($this->orm); + $tr->persist($u); + $tr->run(); + $this->assertNumWrites(1); + } + public function setUp(): void { parent::setUp(); @@ -112,37 +145,4 @@ public function setUp(): void ], ])); } - - public function testCreateForExisting(): void - { - $u = new User(); - $u->email = 'test@email.com'; - $u->balance = 1000; - - $this->captureWriteQueries(); - - $tr = new Transaction($this->orm); - $tr->persist($u); - $tr->run(); - - $this->assertNumWrites(1); - - $this->orm = $this->orm->withHeap(new Heap()); - - $selector = new Select($this->orm, User::class); - /** @var User $u */ - $u = $selector->wherePK($u->id)->fetchOne(); - - $c = new Comment(); - $c->user = $u; - $c->message = 'hello world'; - - $u->addComment($c); - - $this->captureWriteQueries(); - $tr = new Transaction($this->orm); - $tr->persist($u); - $tr->run(); - $this->assertNumWrites(1); - } } diff --git a/tests/ORM/Functional/Driver/Common/Relation/HasMany/Cyclic/CyclicHasManyReferencesTest.php b/tests/ORM/Functional/Driver/Common/Relation/HasMany/Cyclic/CyclicHasManyReferencesTest.php index 9f5c3ec1..5496559a 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/HasMany/Cyclic/CyclicHasManyReferencesTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/HasMany/Cyclic/CyclicHasManyReferencesTest.php @@ -19,99 +19,6 @@ abstract class CyclicHasManyReferencesTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('user', [ - 'id' => 'primary', - 'email' => 'string', - 'created_at' => 'datetime', - 'updated_at' => 'datetime', - ]); - - $this->makeTable('post', [ - 'id' => 'primary', - 'title' => 'string', - 'content' => 'string', - 'last_comment_id' => 'integer,nullable', - 'created_at' => 'datetime', - 'updated_at' => 'datetime', - ]); - - $this->makeTable('comment', [ - 'id' => 'primary', - 'post_id' => 'integer', - 'user_id' => 'integer', - 'message' => 'string', - 'created_at' => 'datetime', - 'updated_at' => 'datetime', - ]); - - $this->orm = $this->withSchema(new Schema([ - User::class => [ - Schema::ROLE => 'user', - Schema::MAPPER => TimestampedMapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'user', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'email', 'created_at', 'updated_at'], - Schema::SCHEMA => [], - Schema::RELATIONS => [], - ], - Comment::class => [ - Schema::ROLE => 'comment', - Schema::MAPPER => TimestampedMapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'comment', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'user_id', 'post_id', 'message', 'created_at', 'updated_at'], - Schema::SCHEMA => [], - Schema::RELATIONS => [ - 'user' => [ - Relation::TYPE => Relation::BELONGS_TO, - Relation::TARGET => User::class, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::INNER_KEY => 'user_id', - Relation::OUTER_KEY => 'id', - ], - ], - ], - ], - Post::class => [ - Schema::ROLE => 'post', - Schema::MAPPER => TimestampedMapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'post', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'title', 'content', 'last_comment_id', 'created_at', 'updated_at'], - Schema::SCHEMA => [], - Schema::RELATIONS => [ - 'lastComment' => [ - Relation::TYPE => Relation::REFERS_TO, - Relation::TARGET => Comment::class, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::INNER_KEY => 'last_comment_id', - Relation::OUTER_KEY => 'id', - Relation::NULLABLE => true, - ], - ], - 'comments' => [ - Relation::TYPE => Relation::HAS_MANY, - Relation::TARGET => Comment::class, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::INNER_KEY => 'id', - Relation::OUTER_KEY => 'post_id', - ], - ], - ], - ], - ])); - } - public function testCreate(): void { $u = new User(); @@ -139,7 +46,7 @@ public function testCreate(): void $this->orm = $this->orm->withHeap(new Heap()); $selector = new Select($this->orm, Post::class); $selector->load('lastComment.user') - ->load('comments.user'); + ->load('comments.user'); $p1 = $selector->wherePK(1)->fetchOne(); @@ -206,4 +113,97 @@ public function testReferenceUpdate(): void $this->assertEquals($pCommentIds, $p1CommentIds); $this->assertEquals($p1->id, $p1->comments[0]->post_id); } + + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('user', [ + 'id' => 'primary', + 'email' => 'string', + 'created_at' => 'datetime', + 'updated_at' => 'datetime', + ]); + + $this->makeTable('post', [ + 'id' => 'primary', + 'title' => 'string', + 'content' => 'string', + 'last_comment_id' => 'integer,nullable', + 'created_at' => 'datetime', + 'updated_at' => 'datetime', + ]); + + $this->makeTable('comment', [ + 'id' => 'primary', + 'post_id' => 'integer', + 'user_id' => 'integer', + 'message' => 'string', + 'created_at' => 'datetime', + 'updated_at' => 'datetime', + ]); + + $this->orm = $this->withSchema(new Schema([ + User::class => [ + Schema::ROLE => 'user', + Schema::MAPPER => TimestampedMapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'user', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'email', 'created_at', 'updated_at'], + Schema::SCHEMA => [], + Schema::RELATIONS => [], + ], + Comment::class => [ + Schema::ROLE => 'comment', + Schema::MAPPER => TimestampedMapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'comment', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'user_id', 'post_id', 'message', 'created_at', 'updated_at'], + Schema::SCHEMA => [], + Schema::RELATIONS => [ + 'user' => [ + Relation::TYPE => Relation::BELONGS_TO, + Relation::TARGET => User::class, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::INNER_KEY => 'user_id', + Relation::OUTER_KEY => 'id', + ], + ], + ], + ], + Post::class => [ + Schema::ROLE => 'post', + Schema::MAPPER => TimestampedMapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'post', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'title', 'content', 'last_comment_id', 'created_at', 'updated_at'], + Schema::SCHEMA => [], + Schema::RELATIONS => [ + 'lastComment' => [ + Relation::TYPE => Relation::REFERS_TO, + Relation::TARGET => Comment::class, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::INNER_KEY => 'last_comment_id', + Relation::OUTER_KEY => 'id', + Relation::NULLABLE => true, + ], + ], + 'comments' => [ + Relation::TYPE => Relation::HAS_MANY, + Relation::TARGET => Comment::class, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::INNER_KEY => 'id', + Relation::OUTER_KEY => 'post_id', + ], + ], + ], + ], + ])); + } } diff --git a/tests/ORM/Functional/Driver/Common/Relation/HasMany/Cyclic/CyclicHasManyReferencesWithCompositePKTest.php b/tests/ORM/Functional/Driver/Common/Relation/HasMany/Cyclic/CyclicHasManyReferencesWithCompositePKTest.php index 978cb926..2e0f2353 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/HasMany/Cyclic/CyclicHasManyReferencesWithCompositePKTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/HasMany/Cyclic/CyclicHasManyReferencesWithCompositePKTest.php @@ -18,6 +18,30 @@ abstract class CyclicHasManyReferencesWithCompositePKTest extends BaseTest { use TableTrait; + public function testCreate(): void + { + $t = new Tenant(); + $t->name = 'Google'; + + $p = new Preference(); + $p->flag = true; + $p->option = 'option1'; + + $t->setPreference($p); + $p->tenant = $t; + + $this->captureWriteQueries(); + $this->save($t); + $this->assertNumWrites(3); + + $this->assertNotNull($p->tenant_id); + + // no changes! + $this->captureWriteQueries(); + $this->save($t); + $this->assertNumWrites(0); + } + public function setUp(): void { parent::setUp(); @@ -149,28 +173,4 @@ public function setUp(): void ], ])); } - - public function testCreate(): void - { - $t = new Tenant(); - $t->name = 'Google'; - - $p = new Preference(); - $p->flag = true; - $p->option = 'option1'; - - $t->setPreference($p); - $p->tenant = $t; - - $this->captureWriteQueries(); - $this->save($t); - $this->assertNumWrites(3); - - $this->assertNotNull($p->tenant_id); - - // no changes! - $this->captureWriteQueries(); - $this->save($t); - $this->assertNumWrites(0); - } } diff --git a/tests/ORM/Functional/Driver/Common/Relation/HasMany/HasManyCollectionsTest.php b/tests/ORM/Functional/Driver/Common/Relation/HasMany/HasManyCollectionsTest.php index bafd7ede..f129558e 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/HasMany/HasManyCollectionsTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/HasMany/HasManyCollectionsTest.php @@ -31,56 +31,13 @@ abstract class HasManyCollectionsTest extends BaseTest */ private array $collectionFactory = []; - public function setUp(): void - { - parent::setUp(); - - $this->collectionFactory = []; - - $this->makeTable('user', [ - 'id' => 'primary', - 'email' => 'string', - 'balance' => 'float', - ]); - - $this->getDatabase()->table('user')->insertMultiple( - ['email', 'balance'], - [ - ['hello@world.com', 100], - ['another@world.com', 200], - ] - ); - - $this->makeTable('comment', [ - 'id' => 'primary', - 'user_id' => 'integer', - 'level' => 'integer', - 'message' => 'string', - ]); - - $this->getDatabase()->table('comment')->insertMultiple( - ['user_id', 'level', 'message'], - [ - [1, 1, 'msg 1'], - [1, 2, 'msg 2'], - [1, 3, 'msg 3'], - [1, 4, 'msg 4'], - [2, 1, 'msg 2.1'], - [2, 2, 'msg 2.2'], - [2, 3, 'msg 2.3'], - ] - ); - - $this->orm = $this->withSchema(new Schema($this->getSchemaArray())); - } - /** * @dataProvider collectionTypesProvider */ public function testCustomCollectionLoad(?string $factory, bool $lazy, string $class): void { $this->orm = $this->createOrm()->withSchema( - new Schema($this->schemaWithCollectionType(User::class, 'comments', $factory)) + new Schema($this->schemaWithCollectionType(User::class, 'comments', $factory)), ); $select = new Select($this->orm, User::class); @@ -98,7 +55,7 @@ public function testCustomCollectionLoad(?string $factory, bool $lazy, string $c public function testCustomCollectionPersist(string $factory, string $type): void { $this->orm = $this->createOrm()->withSchema( - new Schema($this->schemaWithCollectionType(User::class, 'comments', $factory)) + new Schema($this->schemaWithCollectionType(User::class, 'comments', $factory)), ); $comments = $this->collectionFactory[$factory]->collect([ $this->orm->make(Comment::class, ['level' => 90, 'message' => 'test 90']), @@ -157,6 +114,49 @@ public function collectionTypesProvider(): array ]; } + public function setUp(): void + { + parent::setUp(); + + $this->collectionFactory = []; + + $this->makeTable('user', [ + 'id' => 'primary', + 'email' => 'string', + 'balance' => 'float', + ]); + + $this->getDatabase()->table('user')->insertMultiple( + ['email', 'balance'], + [ + ['hello@world.com', 100], + ['another@world.com', 200], + ], + ); + + $this->makeTable('comment', [ + 'id' => 'primary', + 'user_id' => 'integer', + 'level' => 'integer', + 'message' => 'string', + ]); + + $this->getDatabase()->table('comment')->insertMultiple( + ['user_id', 'level', 'message'], + [ + [1, 1, 'msg 1'], + [1, 2, 'msg 2'], + [1, 3, 'msg 3'], + [1, 4, 'msg 4'], + [2, 1, 'msg 2.1'], + [2, 2, 'msg 2.2'], + [2, 3, 'msg 2.3'], + ], + ); + + $this->orm = $this->withSchema(new Schema($this->getSchemaArray())); + } + private function createOrm(): ORMInterface { $this->collectionFactory['doctrine'] = new DoctrineCollectionFactory(); @@ -168,21 +168,21 @@ private function createOrm(): ORMInterface $this->dbal, RelationConfig::getDefault(), null, - $this->collectionFactory['doctrine'] + $this->collectionFactory['doctrine'], )) ->withCollectionFactory( 'doctrine', - $this->collectionFactory['doctrine'] + $this->collectionFactory['doctrine'], ) ->withCollectionFactory( 'illuminate', - $this->collectionFactory['illuminate'] + $this->collectionFactory['illuminate'], ) ->withCollectionFactory( 'array', - $this->collectionFactory['array'] + $this->collectionFactory['array'], ), - new Schema([]) + new Schema([]), ); } @@ -190,7 +190,7 @@ private function schemaWithCollectionType( string $role, string $relation, ?string $collection, - array $schema = null + ?array $schema = null, ): array { $schema ??= $this->getSchemaArray(); $schema[$role][Schema::RELATIONS][$relation][Relation::COLLECTION_TYPE] = $collection; diff --git a/tests/ORM/Functional/Driver/Common/Relation/HasMany/HasManyCompositeKeyTest.php b/tests/ORM/Functional/Driver/Common/Relation/HasMany/HasManyCompositeKeyTest.php index a58b11f6..29cb77b1 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/HasMany/HasManyCompositeKeyTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/HasMany/HasManyCompositeKeyTest.php @@ -23,94 +23,26 @@ abstract class HasManyCompositeKeyTest extends BaseTest { use TableTrait; - protected const - CHILD_CONTAINER = 'children'; - protected const - PARENT_1 = ['key1' => 1, 'key2' => 1, 'key3' => 101]; - protected const - PARENT_2 = ['key1' => 1, 'key2' => 2, 'key3' => 102]; - protected const - PARENT_3 = ['key1' => 2, 'key2' => 1, 'key3' => 201]; - protected const - PARENT_4 = ['key1' => 2, 'key2' => 2, 'key3' => 202]; - protected const - CHILD_1_1 = ['key1' => 1, 'key2' => 1, 'key3' => null, 'parent_key1' => 1, 'parent_key2' => 1]; - protected const - CHILD_1_2 = ['key1' => 1, 'key2' => 2, 'key3' => 'foo1', 'parent_key1' => 1, 'parent_key2' => 1]; - protected const - CHILD_1_3 = ['key1' => 1, 'key2' => 3, 'key3' => 'bar1', 'parent_key1' => 1, 'parent_key2' => 1]; - protected const - CHILD_2_1 = ['key1' => 2, 'key2' => 1, 'key3' => 'foo2', 'parent_key1' => 1, 'parent_key2' => 2]; - protected const - CHILD_3_1 = ['key1' => 3, 'key2' => 1, 'key3' => 'bar3', 'parent_key1' => 2, 'parent_key2' => 1]; - protected const - PARENT_1_FULL = self::PARENT_1 + [self::CHILD_CONTAINER => [self::CHILD_1_1, self::CHILD_1_2, self::CHILD_1_3]]; - protected const - PARENT_2_FULL = self::PARENT_2 + [self::CHILD_CONTAINER => [self::CHILD_2_1]]; - protected const - PARENT_3_FULL = self::PARENT_3 + [self::CHILD_CONTAINER => [self::CHILD_3_1]]; - protected const - PARENT_4_FULL = self::PARENT_4 + [self::CHILD_CONTAINER => []]; - protected const - SET_FULL = [ - self::PARENT_1_FULL, - self::PARENT_2_FULL, - self::PARENT_3_FULL, - self::PARENT_4_FULL, - ]; - - public function setUp(): void - { - parent::setUp(); - - $this->makeTable( - 'parent_entity', - [ - 'pField1' => 'bigInteger,primary', - 'pField2' => 'bigInteger,primary', - 'pField3' => 'integer,nullable', - ] - ); - $this->makeTable( - 'child_entity', - [ - 'field1' => 'bigInteger,primary', - 'field2' => 'bigInteger,primary', - 'field3' => 'string,nullable', - 'parent_field1' => 'bigInteger,null', - 'parent_field2' => 'bigInteger,null', - ] - ); - - $this->makeCompositeFK( - 'child_entity', - ['parent_field1', 'parent_field2'], - 'parent_entity', - ['pField1', 'pField2'] - ); - - $this->getDatabase()->table('parent_entity')->insertMultiple( - ['pField1', 'pField2', 'pField3'], - [ - self::PARENT_1, - self::PARENT_2, - self::PARENT_3, - self::PARENT_4, - ] - ); - $this->getDatabase()->table('child_entity')->insertMultiple( - ['field1', 'field2', 'field3', 'parent_field1', 'parent_field2'], - [ - self::CHILD_1_1, - self::CHILD_1_2, - self::CHILD_1_3, - self::CHILD_2_1, - self::CHILD_3_1, - ] - ); - - $this->orm = $this->withSchema(new Schema($this->getSchemaArray())); - } + protected const CHILD_CONTAINER = 'children'; + protected const PARENT_1 = ['key1' => 1, 'key2' => 1, 'key3' => 101]; + protected const PARENT_2 = ['key1' => 1, 'key2' => 2, 'key3' => 102]; + protected const PARENT_3 = ['key1' => 2, 'key2' => 1, 'key3' => 201]; + protected const PARENT_4 = ['key1' => 2, 'key2' => 2, 'key3' => 202]; + protected const CHILD_1_1 = ['key1' => 1, 'key2' => 1, 'key3' => null, 'parent_key1' => 1, 'parent_key2' => 1]; + protected const CHILD_1_2 = ['key1' => 1, 'key2' => 2, 'key3' => 'foo1', 'parent_key1' => 1, 'parent_key2' => 1]; + protected const CHILD_1_3 = ['key1' => 1, 'key2' => 3, 'key3' => 'bar1', 'parent_key1' => 1, 'parent_key2' => 1]; + protected const CHILD_2_1 = ['key1' => 2, 'key2' => 1, 'key3' => 'foo2', 'parent_key1' => 1, 'parent_key2' => 2]; + protected const CHILD_3_1 = ['key1' => 3, 'key2' => 1, 'key3' => 'bar3', 'parent_key1' => 2, 'parent_key2' => 1]; + protected const PARENT_1_FULL = self::PARENT_1 + [self::CHILD_CONTAINER => [self::CHILD_1_1, self::CHILD_1_2, self::CHILD_1_3]]; + protected const PARENT_2_FULL = self::PARENT_2 + [self::CHILD_CONTAINER => [self::CHILD_2_1]]; + protected const PARENT_3_FULL = self::PARENT_3 + [self::CHILD_CONTAINER => [self::CHILD_3_1]]; + protected const PARENT_4_FULL = self::PARENT_4 + [self::CHILD_CONTAINER => []]; + protected const SET_FULL = [ + self::PARENT_1_FULL, + self::PARENT_2_FULL, + self::PARENT_3_FULL, + self::PARENT_4_FULL, + ]; public function testInitRelation(): void { @@ -245,7 +177,7 @@ public function testCreateWithRelations(): void ], ], ], - $selector->wherePK([91, 91])->fetchData() + $selector->wherePK([91, 91])->fetchData(), ); } @@ -404,6 +336,59 @@ public function testSliceAndSaveToAnotherParent(): void $this->assertSame('new value', $d->children[0]->key3); } + public function setUp(): void + { + parent::setUp(); + + $this->makeTable( + 'parent_entity', + [ + 'pField1' => 'bigInteger,primary', + 'pField2' => 'bigInteger,primary', + 'pField3' => 'integer,nullable', + ], + ); + $this->makeTable( + 'child_entity', + [ + 'field1' => 'bigInteger,primary', + 'field2' => 'bigInteger,primary', + 'field3' => 'string,nullable', + 'parent_field1' => 'bigInteger,null', + 'parent_field2' => 'bigInteger,null', + ], + ); + + $this->makeCompositeFK( + 'child_entity', + ['parent_field1', 'parent_field2'], + 'parent_entity', + ['pField1', 'pField2'], + ); + + $this->getDatabase()->table('parent_entity')->insertMultiple( + ['pField1', 'pField2', 'pField3'], + [ + self::PARENT_1, + self::PARENT_2, + self::PARENT_3, + self::PARENT_4, + ], + ); + $this->getDatabase()->table('child_entity')->insertMultiple( + ['field1', 'field2', 'field3', 'parent_field1', 'parent_field2'], + [ + self::CHILD_1_1, + self::CHILD_1_2, + self::CHILD_1_3, + self::CHILD_2_1, + self::CHILD_3_1, + ], + ); + + $this->orm = $this->withSchema(new Schema($this->getSchemaArray())); + } + private function getSchemaArray(): array { return [ diff --git a/tests/ORM/Functional/Driver/Common/Relation/HasMany/HasManyLoadingTest.php b/tests/ORM/Functional/Driver/Common/Relation/HasMany/HasManyLoadingTest.php index ddb2b5c8..19b28843 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/HasMany/HasManyLoadingTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/HasMany/HasManyLoadingTest.php @@ -17,75 +17,6 @@ abstract class HasManyLoadingTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('user', [ - 'id' => 'primary', - 'email' => 'string', - 'balance' => 'float', - ]); - - $this->makeTable('comment', [ - 'id' => 'primary', - 'user_id' => 'integer,null', - 'message' => 'string', - ]); - - $this->makeFK('comment', 'user_id', 'user', 'id'); - - $this->getDatabase()->table('user')->insertMultiple( - ['email', 'balance'], - [ - ['hello@world.com', 100], - ['another@world.com', 200], - ] - ); - - $this->getDatabase()->table('comment')->insertMultiple( - ['user_id', 'message'], - [ - [1, 'msg 1'], - [1, 'msg 2'], - [1, 'msg 3'], - ] - ); - - $this->orm = $this->withSchema(new Schema([ - User::class => [ - Schema::ROLE => 'user', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'user', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'email', 'balance'], - Schema::SCHEMA => [], - Schema::RELATIONS => [ - 'comments' => [ - Relation::TYPE => Relation::HAS_MANY, - Relation::TARGET => Comment::class, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::INNER_KEY => 'id', - Relation::OUTER_KEY => 'user_id', - ], - ], - ], - ], - Comment::class => [ - Schema::ROLE => 'comment', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'comment', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'user_id', 'message'], - Schema::SCHEMA => [], - Schema::RELATIONS => [], - ], - ])); - } - public function testFetchRelation(): void { $selector = new Select($this->orm, User::class); @@ -205,4 +136,73 @@ public function testFetchRelationLoadedInload(): void ], ], $selector->fetchData()); } + + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('user', [ + 'id' => 'primary', + 'email' => 'string', + 'balance' => 'float', + ]); + + $this->makeTable('comment', [ + 'id' => 'primary', + 'user_id' => 'integer,null', + 'message' => 'string', + ]); + + $this->makeFK('comment', 'user_id', 'user', 'id'); + + $this->getDatabase()->table('user')->insertMultiple( + ['email', 'balance'], + [ + ['hello@world.com', 100], + ['another@world.com', 200], + ], + ); + + $this->getDatabase()->table('comment')->insertMultiple( + ['user_id', 'message'], + [ + [1, 'msg 1'], + [1, 'msg 2'], + [1, 'msg 3'], + ], + ); + + $this->orm = $this->withSchema(new Schema([ + User::class => [ + Schema::ROLE => 'user', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'user', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'email', 'balance'], + Schema::SCHEMA => [], + Schema::RELATIONS => [ + 'comments' => [ + Relation::TYPE => Relation::HAS_MANY, + Relation::TARGET => Comment::class, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::INNER_KEY => 'id', + Relation::OUTER_KEY => 'user_id', + ], + ], + ], + ], + Comment::class => [ + Schema::ROLE => 'comment', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'comment', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'user_id', 'message'], + Schema::SCHEMA => [], + Schema::RELATIONS => [], + ], + ])); + } } diff --git a/tests/ORM/Functional/Driver/Common/Relation/HasMany/HasManyNestedConditionTest.php b/tests/ORM/Functional/Driver/Common/Relation/HasMany/HasManyNestedConditionTest.php index 3b43cb66..96cd425e 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/HasMany/HasManyNestedConditionTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/HasMany/HasManyNestedConditionTest.php @@ -20,116 +20,6 @@ abstract class HasManyNestedConditionTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('user', [ - 'id' => 'primary', - 'email' => 'string', - 'balance' => 'float', - ]); - - - $this->makeTable('post', [ - 'id' => 'primary', - 'user_id' => 'integer', - 'title' => 'string', - ]); - - $this->makeTable('comment', [ - 'id' => 'primary', - 'user_id' => 'integer,null', - 'post_id' => 'integer', - 'message' => 'string', - ]); - - $this->makeFK('post', 'user_id', 'user', 'id', 'NO ACTION', 'NO ACTION'); - $this->makeFK('comment', 'user_id', 'user', 'id', 'NO ACTION', 'NO ACTION'); - $this->makeFK('comment', 'post_id', 'post', 'id', 'NO ACTION', 'NO ACTION'); - - $this->getDatabase()->table('user')->insertMultiple( - ['email', 'balance'], - [ - ['hello@world.com', 100], - ['another@world.com', 200], - ] - ); - - $this->getDatabase()->table('post')->insertMultiple( - ['user_id', 'title'], - [ - [1, 'post 1'], - [1, 'post 2'], - [1, 'post 3'], - [2, 'post 4'], - ] - ); - - $this->getDatabase()->table('comment')->insertMultiple( - ['user_id', 'post_id', 'message'], - [ - [1, 1, 'msg 1'], - [2, 1, 'msg 2'], - [2, 2, 'msg 3'], - ] - ); - - $this->orm = $this->withSchema(new Schema([ - User::class => [ - Schema::ROLE => 'user', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'user', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'email', 'balance'], - Schema::SCHEMA => [], - Schema::RELATIONS => [ - 'posts' => [ - Relation::TYPE => Relation::HAS_MANY, - Relation::TARGET => Post::class, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::INNER_KEY => 'id', - Relation::OUTER_KEY => 'user_id', - ], - ], - ], - ], - Post::class => [ - Schema::ROLE => 'post', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'post', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'user_id', 'title'], - Schema::SCHEMA => [], - Schema::RELATIONS => [ - 'comments' => [ - Relation::TYPE => Relation::HAS_MANY, - Relation::TARGET => Comment::class, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::INNER_KEY => 'id', - Relation::OUTER_KEY => 'post_id', - ], - ], - ], - Schema::SCOPE => SortByIDScope::class, - ], - Comment::class => [ - Schema::ROLE => 'comment', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'comment', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'user_id', 'post_id', 'message'], - Schema::SCHEMA => [], - Schema::RELATIONS => [], - ], - ])); - } - public function testFetchRelation(): void { $selector = new Select($this->orm, User::class); @@ -243,8 +133,8 @@ public function testFetchFilteredNoComments(): void $users->load('posts', [ 'where' => function (Select\QueryBuilder $qb): void { $qb->distinct() - ->with('comments', ['method' => Select\JoinableLoader::LEFT_JOIN]) - ->where('comments.id', '=', null); + ->with('comments', ['method' => Select\JoinableLoader::LEFT_JOIN]) + ->where('comments.id', '=', null); }, ])->orderBy('user.id'); @@ -283,11 +173,11 @@ public function testFetchCrossLinked(): void $users->load('posts', [ 'where' => function (Select\QueryBuilder $qb): void { $qb->distinct() - ->where( - 'comments.user_id', - '=', - new Expression($qb->resolve('user_id')) - ); + ->where( + 'comments.user_id', + '=', + new Expression($qb->resolve('user_id')), + ); }, ])->orderBy('user.id'); @@ -354,4 +244,114 @@ public function testFindUsersWithoutPostCommentsLoadPostsWithComments(): void ], ], $users->fetchData()); } + + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('user', [ + 'id' => 'primary', + 'email' => 'string', + 'balance' => 'float', + ]); + + + $this->makeTable('post', [ + 'id' => 'primary', + 'user_id' => 'integer', + 'title' => 'string', + ]); + + $this->makeTable('comment', [ + 'id' => 'primary', + 'user_id' => 'integer,null', + 'post_id' => 'integer', + 'message' => 'string', + ]); + + $this->makeFK('post', 'user_id', 'user', 'id', 'NO ACTION', 'NO ACTION'); + $this->makeFK('comment', 'user_id', 'user', 'id', 'NO ACTION', 'NO ACTION'); + $this->makeFK('comment', 'post_id', 'post', 'id', 'NO ACTION', 'NO ACTION'); + + $this->getDatabase()->table('user')->insertMultiple( + ['email', 'balance'], + [ + ['hello@world.com', 100], + ['another@world.com', 200], + ], + ); + + $this->getDatabase()->table('post')->insertMultiple( + ['user_id', 'title'], + [ + [1, 'post 1'], + [1, 'post 2'], + [1, 'post 3'], + [2, 'post 4'], + ], + ); + + $this->getDatabase()->table('comment')->insertMultiple( + ['user_id', 'post_id', 'message'], + [ + [1, 1, 'msg 1'], + [2, 1, 'msg 2'], + [2, 2, 'msg 3'], + ], + ); + + $this->orm = $this->withSchema(new Schema([ + User::class => [ + Schema::ROLE => 'user', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'user', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'email', 'balance'], + Schema::SCHEMA => [], + Schema::RELATIONS => [ + 'posts' => [ + Relation::TYPE => Relation::HAS_MANY, + Relation::TARGET => Post::class, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::INNER_KEY => 'id', + Relation::OUTER_KEY => 'user_id', + ], + ], + ], + ], + Post::class => [ + Schema::ROLE => 'post', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'post', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'user_id', 'title'], + Schema::SCHEMA => [], + Schema::RELATIONS => [ + 'comments' => [ + Relation::TYPE => Relation::HAS_MANY, + Relation::TARGET => Comment::class, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::INNER_KEY => 'id', + Relation::OUTER_KEY => 'post_id', + ], + ], + ], + Schema::SCOPE => SortByIDScope::class, + ], + Comment::class => [ + Schema::ROLE => 'comment', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'comment', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'user_id', 'post_id', 'message'], + Schema::SCHEMA => [], + Schema::RELATIONS => [], + ], + ])); + } } diff --git a/tests/ORM/Functional/Driver/Common/Relation/HasMany/HasManyProxyMapperTest.php b/tests/ORM/Functional/Driver/Common/Relation/HasMany/HasManyProxyMapperTest.php index c5bda76d..c0ba0d25 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/HasMany/HasManyProxyMapperTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/HasMany/HasManyProxyMapperTest.php @@ -21,77 +21,6 @@ abstract class HasManyProxyMapperTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('user', [ - 'id' => 'primary', - 'email' => 'string', - 'balance' => 'float', - ]); - - $this->getDatabase()->table('user')->insertMultiple( - ['email', 'balance'], - [ - ['hello@world.com', 100], - ['another@world.com', 200], - ] - ); - - $this->makeTable('comment', [ - 'id' => 'primary', - 'user_id' => 'integer', - 'message' => 'string', - ]); - - $this->makeFK('comment', 'user_id', 'user', 'id'); - - $this->getDatabase()->table('comment')->insertMultiple( - ['user_id', 'message'], - [ - [1, 'msg 1'], - [1, 'msg 2'], - [1, 'msg 3'], - ] - ); - - $this->orm = $this->withSchema(new Schema([ - User::class => [ - Schema::ROLE => 'user', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'user', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'email', 'balance'], - Schema::SCHEMA => [], - Schema::RELATIONS => [ - 'comments' => [ - Relation::TYPE => Relation::HAS_MANY, - Relation::TARGET => Comment::class, - Relation::LOAD => Relation::LOAD_PROMISE, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::INNER_KEY => 'id', - Relation::OUTER_KEY => 'user_id', - ], - ], - ], - ], - Comment::class => [ - Schema::ROLE => 'comment', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'comment', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'user_id', 'message'], - Schema::SCHEMA => [], - Schema::RELATIONS => [], - Schema::SCOPE => SortByIDScope::class, - ], - ])); - } - public function testFetchRelation(): void { $selector = new Select($this->orm, User::class); @@ -321,4 +250,75 @@ public function testSliceAndSaveToAnotherParent(): void $this->assertEquals('new b', $b->comments[0]->message); } + + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('user', [ + 'id' => 'primary', + 'email' => 'string', + 'balance' => 'float', + ]); + + $this->getDatabase()->table('user')->insertMultiple( + ['email', 'balance'], + [ + ['hello@world.com', 100], + ['another@world.com', 200], + ], + ); + + $this->makeTable('comment', [ + 'id' => 'primary', + 'user_id' => 'integer', + 'message' => 'string', + ]); + + $this->makeFK('comment', 'user_id', 'user', 'id'); + + $this->getDatabase()->table('comment')->insertMultiple( + ['user_id', 'message'], + [ + [1, 'msg 1'], + [1, 'msg 2'], + [1, 'msg 3'], + ], + ); + + $this->orm = $this->withSchema(new Schema([ + User::class => [ + Schema::ROLE => 'user', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'user', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'email', 'balance'], + Schema::SCHEMA => [], + Schema::RELATIONS => [ + 'comments' => [ + Relation::TYPE => Relation::HAS_MANY, + Relation::TARGET => Comment::class, + Relation::LOAD => Relation::LOAD_PROMISE, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::INNER_KEY => 'id', + Relation::OUTER_KEY => 'user_id', + ], + ], + ], + ], + Comment::class => [ + Schema::ROLE => 'comment', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'comment', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'user_id', 'message'], + Schema::SCHEMA => [], + Schema::RELATIONS => [], + Schema::SCOPE => SortByIDScope::class, + ], + ])); + } } diff --git a/tests/ORM/Functional/Driver/Common/Relation/HasMany/HasManyRelationTest.php b/tests/ORM/Functional/Driver/Common/Relation/HasMany/HasManyRelationTest.php index e101dc4e..883cf488 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/HasMany/HasManyRelationTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/HasMany/HasManyRelationTest.php @@ -25,76 +25,6 @@ abstract class HasManyRelationTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('user', [ - 'id' => 'primary', - 'email' => 'string', - 'balance' => 'float', - ]); - - $this->makeTable('comment', [ - 'id' => 'primary', - 'user_id' => 'integer,null', - 'message' => 'string', - ]); - - $this->makeFK('comment', 'user_id', 'user', 'id'); - - $this->getDatabase()->table('user')->insertMultiple( - ['email', 'balance'], - [ - ['hello@world.com', 100], - ['another@world.com', 200], - ] - ); - - $this->getDatabase()->table('comment')->insertMultiple( - ['user_id', 'message'], - [ - [1, 'msg 1'], - [1, 'msg 2'], - [1, 'msg 3'], - ] - ); - - $this->orm = $this->withSchema(new Schema([ - User::class => [ - Schema::ROLE => 'user', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'user', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'email', 'balance'], - Schema::SCHEMA => [], - Schema::RELATIONS => [ - 'comments' => [ - Relation::TYPE => Relation::HAS_MANY, - Relation::TARGET => Comment::class, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::INNER_KEY => 'id', - Relation::OUTER_KEY => 'user_id', - ], - ], - ], - ], - Comment::class => [ - Schema::ROLE => 'comment', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'comment', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'user_id', 'message'], - Schema::SCHEMA => [], - Schema::RELATIONS => [], - Schema::SCOPE => SortByIDScope::class, - ], - ])); - } - public function testInitRelation(): void { $u = $this->orm->make(User::class); @@ -565,4 +495,74 @@ public function testRemoveChildrenUsingUnset(): void ->fetchOne(); $this->assertCount(0, $e->comments); } + + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('user', [ + 'id' => 'primary', + 'email' => 'string', + 'balance' => 'float', + ]); + + $this->makeTable('comment', [ + 'id' => 'primary', + 'user_id' => 'integer,null', + 'message' => 'string', + ]); + + $this->makeFK('comment', 'user_id', 'user', 'id'); + + $this->getDatabase()->table('user')->insertMultiple( + ['email', 'balance'], + [ + ['hello@world.com', 100], + ['another@world.com', 200], + ], + ); + + $this->getDatabase()->table('comment')->insertMultiple( + ['user_id', 'message'], + [ + [1, 'msg 1'], + [1, 'msg 2'], + [1, 'msg 3'], + ], + ); + + $this->orm = $this->withSchema(new Schema([ + User::class => [ + Schema::ROLE => 'user', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'user', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'email', 'balance'], + Schema::SCHEMA => [], + Schema::RELATIONS => [ + 'comments' => [ + Relation::TYPE => Relation::HAS_MANY, + Relation::TARGET => Comment::class, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::INNER_KEY => 'id', + Relation::OUTER_KEY => 'user_id', + ], + ], + ], + ], + Comment::class => [ + Schema::ROLE => 'comment', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'comment', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'user_id', 'message'], + Schema::SCHEMA => [], + Schema::RELATIONS => [], + Schema::SCOPE => SortByIDScope::class, + ], + ])); + } } diff --git a/tests/ORM/Functional/Driver/Common/Relation/HasMany/HasManyScopeTest.php b/tests/ORM/Functional/Driver/Common/Relation/HasMany/HasManyScopeTest.php index ad402332..45b222d0 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/HasMany/HasManyScopeTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/HasMany/HasManyScopeTest.php @@ -22,47 +22,6 @@ abstract class HasManyScopeTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('user', [ - 'id' => 'primary', - 'email' => 'string', - 'balance' => 'float', - ]); - - $this->getDatabase()->table('user')->insertMultiple( - ['email', 'balance'], - [ - ['hello@world.com', 100], - ['another@world.com', 200], - ] - ); - - $this->makeTable('comment', [ - 'id' => 'primary', - 'user_id' => 'integer', - 'level' => 'integer', - 'message' => 'string', - ]); - - $this->makeFK('comment', 'user_id', 'user', 'id'); - - $this->getDatabase()->table('comment')->insertMultiple( - ['user_id', 'level', 'message'], - [ - [1, 1, 'msg 1'], - [1, 2, 'msg 2'], - [1, 3, 'msg 3'], - [1, 4, 'msg 4'], - [2, 1, 'msg 2.1'], - [2, 2, 'msg 2.2'], - [2, 3, 'msg 2.3'], - ] - ); - } - public function testScopeOrdered(): void { $this->orm = $this->withCommentsSchema([ @@ -498,6 +457,47 @@ public function testInvalidOrderBy(): void ])->orderBy('user.id', 'DESC')->fetchAll(); } + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('user', [ + 'id' => 'primary', + 'email' => 'string', + 'balance' => 'float', + ]); + + $this->getDatabase()->table('user')->insertMultiple( + ['email', 'balance'], + [ + ['hello@world.com', 100], + ['another@world.com', 200], + ], + ); + + $this->makeTable('comment', [ + 'id' => 'primary', + 'user_id' => 'integer', + 'level' => 'integer', + 'message' => 'string', + ]); + + $this->makeFK('comment', 'user_id', 'user', 'id'); + + $this->getDatabase()->table('comment')->insertMultiple( + ['user_id', 'level', 'message'], + [ + [1, 1, 'msg 1'], + [1, 2, 'msg 2'], + [1, 3, 'msg 3'], + [1, 4, 'msg 4'], + [2, 1, 'msg 2.1'], + [2, 2, 'msg 2.2'], + [2, 3, 'msg 2.3'], + ], + ); + } + protected function withCommentsSchema(array $relationSchema): ORMInterface { $eSchema = []; diff --git a/tests/ORM/Functional/Driver/Common/Relation/HasMany/HasManySourceTest.php b/tests/ORM/Functional/Driver/Common/Relation/HasMany/HasManySourceTest.php index b4efc3cb..de3aebfb 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/HasMany/HasManySourceTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/HasMany/HasManySourceTest.php @@ -19,78 +19,6 @@ abstract class HasManySourceTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('user', [ - 'id' => 'primary', - 'email' => 'string', - 'balance' => 'float', - ]); - - $this->getDatabase()->table('user')->insertMultiple( - ['email', 'balance'], - [ - ['hello@world.com', 100], - ['another@world.com', 200], - ] - ); - - $this->makeTable('comment', [ - 'id' => 'primary', - 'user_id' => 'integer', - 'level' => 'integer', - 'message' => 'string', - ]); - - $this->getDatabase()->table('comment')->insertMultiple( - ['user_id', 'level', 'message'], - [ - [1, 1, 'msg 1'], - [1, 2, 'msg 2'], - [1, 3, 'msg 3'], - [1, 4, 'msg 4'], - [2, 1, 'msg 2.1'], - [2, 2, 'msg 2.2'], - [2, 3, 'msg 2.3'], - ] - ); - - $this->orm = $this->withSchema(new Schema([ - User::class => [ - Schema::ROLE => 'user', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'user', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'email', 'balance'], - Schema::SCHEMA => [], - Schema::RELATIONS => [ - 'comments' => [ - Relation::TYPE => Relation::HAS_MANY, - Relation::TARGET => Comment::class, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::INNER_KEY => 'id', - Relation::OUTER_KEY => 'user_id', - ], - ], - ], - ], - Comment::class => [ - Schema::ROLE => 'comment', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'comment', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'user_id', 'level', 'message'], - Schema::SCHEMA => [], - Schema::RELATIONS => [], - ], - ])); - } - public function testSelectUsers(): void { $s = new Select($this->orm, User::class); @@ -449,4 +377,76 @@ public function testScopeViaMapperRelationPromiseShort(): void $this->assertSame('msg 2.3', $b->comments[0]->message); } + + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('user', [ + 'id' => 'primary', + 'email' => 'string', + 'balance' => 'float', + ]); + + $this->getDatabase()->table('user')->insertMultiple( + ['email', 'balance'], + [ + ['hello@world.com', 100], + ['another@world.com', 200], + ], + ); + + $this->makeTable('comment', [ + 'id' => 'primary', + 'user_id' => 'integer', + 'level' => 'integer', + 'message' => 'string', + ]); + + $this->getDatabase()->table('comment')->insertMultiple( + ['user_id', 'level', 'message'], + [ + [1, 1, 'msg 1'], + [1, 2, 'msg 2'], + [1, 3, 'msg 3'], + [1, 4, 'msg 4'], + [2, 1, 'msg 2.1'], + [2, 2, 'msg 2.2'], + [2, 3, 'msg 2.3'], + ], + ); + + $this->orm = $this->withSchema(new Schema([ + User::class => [ + Schema::ROLE => 'user', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'user', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'email', 'balance'], + Schema::SCHEMA => [], + Schema::RELATIONS => [ + 'comments' => [ + Relation::TYPE => Relation::HAS_MANY, + Relation::TARGET => Comment::class, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::INNER_KEY => 'id', + Relation::OUTER_KEY => 'user_id', + ], + ], + ], + ], + Comment::class => [ + Schema::ROLE => 'comment', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'comment', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'user_id', 'level', 'message'], + Schema::SCHEMA => [], + Schema::RELATIONS => [], + ], + ])); + } } diff --git a/tests/ORM/Functional/Driver/Common/Relation/HasOne/HasOneCompositeKeyTest.php b/tests/ORM/Functional/Driver/Common/Relation/HasOne/HasOneCompositeKeyTest.php index ab576413..00ea0065 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/HasOne/HasOneCompositeKeyTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/HasOne/HasOneCompositeKeyTest.php @@ -23,130 +23,38 @@ abstract class HasOneCompositeKeyTest extends BaseTest { use TableTrait; - protected const - CHILD_CONTAINER = 'child_entity'; - protected const - NESTED_CONTAINER = 'nested'; - protected const - PARENT_1 = ['key1' => 1, 'key2' => 1, 'key3' => 101]; - protected const - PARENT_2 = ['key1' => 1, 'key2' => 2, 'key3' => 102]; - protected const - PARENT_3 = ['key1' => 2, 'key2' => 1, 'key3' => 201]; - protected const - PARENT_4 = ['key1' => 2, 'key2' => 2, 'key3' => 202]; - protected const - CHILD_1 = ['key1' => 1, 'key2' => 1, 'key3' => null, 'parent_key1' => 1, 'parent_key2' => 1]; - protected const - CHILD_2 = ['key1' => 1, 'key2' => 2, 'key3' => 'foo2', 'parent_key1' => 1, 'parent_key2' => 2]; - protected const - CHILD_3 = ['key1' => 1, 'key2' => 3, 'key3' => 'bar3', 'parent_key1' => 2, 'parent_key2' => 1]; - protected const - NESTED_1 = ['key3' => 'foo', 'parent_key1' => 1, 'parent_key2' => 1]; - protected const - PARENT_1_LOADED = self::PARENT_1 + [self::CHILD_CONTAINER => self::CHILD_1]; - protected const - PARENT_2_LOADED = self::PARENT_2 + [self::CHILD_CONTAINER => self::CHILD_2]; - protected const - PARENT_3_LOADED = self::PARENT_3 + [self::CHILD_CONTAINER => self::CHILD_3]; - protected const - PARENT_4_LOADED = self::PARENT_4 + [self::CHILD_CONTAINER => null]; - protected const - PARENT_1_NESTED = self::PARENT_1 + [self::CHILD_CONTAINER => self::CHILD_1 + [ - self::NESTED_CONTAINER => self::NESTED_1 + ['key1' => 1], - ]]; - protected const - PARENT_2_NESTED = self::PARENT_2 + [self::CHILD_CONTAINER => self::CHILD_2 + [self::NESTED_CONTAINER => null]]; - protected const - PARENT_3_NESTED = self::PARENT_3 + [self::CHILD_CONTAINER => self::CHILD_3 + [self::NESTED_CONTAINER => null]]; - protected const - PARENT_4_NESTED = self::PARENT_4 + [self::CHILD_CONTAINER => null]; - protected const - FULL_LOADED = [ - self::PARENT_1_LOADED, - self::PARENT_2_LOADED, - self::PARENT_3_LOADED, - self::PARENT_4_LOADED, - ]; - protected const - FULL_NESTED = [ - self::PARENT_1_NESTED, - self::PARENT_2_NESTED, - self::PARENT_3_NESTED, - self::PARENT_4_NESTED, - ]; - - public function setUp(): void - { - parent::setUp(); - - $this->makeTable( - 'parent_entity', - [ - 'pField1' => 'bigInteger,primary', - 'pField2' => 'bigInteger,primary', - 'pField3' => 'integer,nullable', - ] - ); - $this->makeTable( - 'child_entity', - [ - 'field1' => 'bigInteger,primary', - 'field2' => 'bigInteger,primary', - 'field3' => 'string,nullable', - 'parent_field1' => 'bigInteger,null', - 'parent_field2' => 'bigInteger,null', - ] - ); - $this->makeTable( - 'nested_entity', - [ - 'field1' => 'primary', - 'field3' => 'string,null', - 'parent_field1' => 'bigInteger,null', - 'parent_field2' => 'bigInteger,null', - ] - ); - - $this->makeCompositeFK( - 'child_entity', - ['parent_field1', 'parent_field2'], - 'parent_entity', - ['pField1', 'pField2'] - ); - $this->makeCompositeFK( - 'nested_entity', - ['parent_field1', 'parent_field2'], - 'child_entity', - ['field1', 'field2'] - ); - - $this->getDatabase()->table('parent_entity')->insertMultiple( - ['pField1', 'pField2', 'pField3'], - [ - self::PARENT_1, - self::PARENT_2, - self::PARENT_3, - self::PARENT_4, - ] - ); - $this->getDatabase()->table('child_entity')->insertMultiple( - ['field1', 'field2', 'field3', 'parent_field1', 'parent_field2'], - [ - self::CHILD_1, - self::CHILD_2, - self::CHILD_3, - ] - ); - $this->getDatabase()->table('nested_entity')->insertMultiple( - ['field3', 'parent_field1', 'parent_field2'], - [ - self::NESTED_1, - ] - ); - - $this->orm = $this->withSchema(new Schema($this->getSchemaArray())); - } + protected const CHILD_CONTAINER = 'child_entity'; + protected const NESTED_CONTAINER = 'nested'; + protected const PARENT_1 = ['key1' => 1, 'key2' => 1, 'key3' => 101]; + protected const PARENT_2 = ['key1' => 1, 'key2' => 2, 'key3' => 102]; + protected const PARENT_3 = ['key1' => 2, 'key2' => 1, 'key3' => 201]; + protected const PARENT_4 = ['key1' => 2, 'key2' => 2, 'key3' => 202]; + protected const CHILD_1 = ['key1' => 1, 'key2' => 1, 'key3' => null, 'parent_key1' => 1, 'parent_key2' => 1]; + protected const CHILD_2 = ['key1' => 1, 'key2' => 2, 'key3' => 'foo2', 'parent_key1' => 1, 'parent_key2' => 2]; + protected const CHILD_3 = ['key1' => 1, 'key2' => 3, 'key3' => 'bar3', 'parent_key1' => 2, 'parent_key2' => 1]; + protected const NESTED_1 = ['key3' => 'foo', 'parent_key1' => 1, 'parent_key2' => 1]; + protected const PARENT_1_LOADED = self::PARENT_1 + [self::CHILD_CONTAINER => self::CHILD_1]; + protected const PARENT_2_LOADED = self::PARENT_2 + [self::CHILD_CONTAINER => self::CHILD_2]; + protected const PARENT_3_LOADED = self::PARENT_3 + [self::CHILD_CONTAINER => self::CHILD_3]; + protected const PARENT_4_LOADED = self::PARENT_4 + [self::CHILD_CONTAINER => null]; + protected const PARENT_1_NESTED = self::PARENT_1 + [self::CHILD_CONTAINER => self::CHILD_1 + [ + self::NESTED_CONTAINER => self::NESTED_1 + ['key1' => 1], + ]]; + protected const PARENT_2_NESTED = self::PARENT_2 + [self::CHILD_CONTAINER => self::CHILD_2 + [self::NESTED_CONTAINER => null]]; + protected const PARENT_3_NESTED = self::PARENT_3 + [self::CHILD_CONTAINER => self::CHILD_3 + [self::NESTED_CONTAINER => null]]; + protected const PARENT_4_NESTED = self::PARENT_4 + [self::CHILD_CONTAINER => null]; + protected const FULL_LOADED = [ + self::PARENT_1_LOADED, + self::PARENT_2_LOADED, + self::PARENT_3_LOADED, + self::PARENT_4_LOADED, + ]; + protected const FULL_NESTED = [ + self::PARENT_1_NESTED, + self::PARENT_2_NESTED, + self::PARENT_3_NESTED, + self::PARENT_4_NESTED, + ]; public function testHasInSchema(): void { @@ -397,8 +305,8 @@ public function testMoveToAnotherEntity(): void { $selector = new Select($this->orm, CompositePK::class); /** - * @var $a CompositePK - * @var $b CompositePK + * @var CompositePK $a + * @var CompositePK $b */ [$a, $b] = $selector->load('child_entity') ->where('parent_entity.key3', '>', 200) @@ -425,7 +333,7 @@ public function testMoveToAnotherEntity(): void $this->assertNotNull($b->child_entity); $this->assertEquals( [$compareChild->key1, $compareChild->key2], - [$b->child_entity->key1, $b->child_entity->key2] + [$b->child_entity->key1, $b->child_entity->key2], ); } @@ -613,7 +521,7 @@ public function testDoNotOverwriteRelation(): void $this->save($u); $u4 = $this->orm->withHeap(new Heap())->getRepository(CompositePK::class) - ->select()->load('child_entity')->wherePK([1, 1])->fetchOne(); + ->select()->load('child_entity')->wherePK([1, 1])->fetchOne(); $this->assertSame('new', $u4->child_entity->key3); } @@ -643,6 +551,78 @@ public function testOverwritePromisedRelation(): void $this->assertNumWrites(0); } + public function setUp(): void + { + parent::setUp(); + + $this->makeTable( + 'parent_entity', + [ + 'pField1' => 'bigInteger,primary', + 'pField2' => 'bigInteger,primary', + 'pField3' => 'integer,nullable', + ], + ); + $this->makeTable( + 'child_entity', + [ + 'field1' => 'bigInteger,primary', + 'field2' => 'bigInteger,primary', + 'field3' => 'string,nullable', + 'parent_field1' => 'bigInteger,null', + 'parent_field2' => 'bigInteger,null', + ], + ); + $this->makeTable( + 'nested_entity', + [ + 'field1' => 'primary', + 'field3' => 'string,null', + 'parent_field1' => 'bigInteger,null', + 'parent_field2' => 'bigInteger,null', + ], + ); + + $this->makeCompositeFK( + 'child_entity', + ['parent_field1', 'parent_field2'], + 'parent_entity', + ['pField1', 'pField2'], + ); + $this->makeCompositeFK( + 'nested_entity', + ['parent_field1', 'parent_field2'], + 'child_entity', + ['field1', 'field2'], + ); + + $this->getDatabase()->table('parent_entity')->insertMultiple( + ['pField1', 'pField2', 'pField3'], + [ + self::PARENT_1, + self::PARENT_2, + self::PARENT_3, + self::PARENT_4, + ], + ); + $this->getDatabase()->table('child_entity')->insertMultiple( + ['field1', 'field2', 'field3', 'parent_field1', 'parent_field2'], + [ + self::CHILD_1, + self::CHILD_2, + self::CHILD_3, + ], + ); + $this->getDatabase()->table('nested_entity')->insertMultiple( + ['field3', 'parent_field1', 'parent_field2'], + [ + self::NESTED_1, + ], + ); + + $this->orm = $this->withSchema(new Schema($this->getSchemaArray())); + } + private function getSchemaArray(): array { return [ diff --git a/tests/ORM/Functional/Driver/Common/Relation/HasOne/HasOneCyclicTest.php b/tests/ORM/Functional/Driver/Common/Relation/HasOne/HasOneCyclicTest.php index 9f150346..045e8331 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/HasOne/HasOneCyclicTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/HasOne/HasOneCyclicTest.php @@ -17,51 +17,6 @@ abstract class HasOneCyclicTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('cyclic', [ - 'id' => 'primary', - 'name' => 'string', - 'parent_id' => 'integer,nullable', - ]); - - $this->getDatabase()->table('cyclic')->insertMultiple( - ['parent_id', 'name'], - [ - [null, 'first'], - [1, 'second'], - [3, 'self-reference'], - ] - ); - - $this->orm = $this->withSchema(new Schema([ - Cyclic::class => [ - Schema::ROLE => 'cyclic', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'cyclic', - Schema::PRIMARY_KEY => 'id', - Schema::FIND_BY_KEYS => ['parent_id'], - Schema::COLUMNS => ['id', 'parent_id', 'name'], - Schema::SCHEMA => [], - Schema::RELATIONS => [ - 'cyclic' => [ - Relation::TYPE => Relation::HAS_ONE, - Relation::TARGET => Cyclic::class, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::NULLABLE => true, - Relation::INNER_KEY => 'id', - Relation::OUTER_KEY => 'parent_id', - ], - ], - ], - ], - ])); - } - public function testFetchCyclic(): void { $selector = new Select($this->orm, Cyclic::class); @@ -147,4 +102,49 @@ public function testCreateCyclic(): void $this->assertEquals('new', $c->name); $this->assertSame($c, $c->cyclic); } + + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('cyclic', [ + 'id' => 'primary', + 'name' => 'string', + 'parent_id' => 'integer,nullable', + ]); + + $this->getDatabase()->table('cyclic')->insertMultiple( + ['parent_id', 'name'], + [ + [null, 'first'], + [1, 'second'], + [3, 'self-reference'], + ], + ); + + $this->orm = $this->withSchema(new Schema([ + Cyclic::class => [ + Schema::ROLE => 'cyclic', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'cyclic', + Schema::PRIMARY_KEY => 'id', + Schema::FIND_BY_KEYS => ['parent_id'], + Schema::COLUMNS => ['id', 'parent_id', 'name'], + Schema::SCHEMA => [], + Schema::RELATIONS => [ + 'cyclic' => [ + Relation::TYPE => Relation::HAS_ONE, + Relation::TARGET => Cyclic::class, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::NULLABLE => true, + Relation::INNER_KEY => 'id', + Relation::OUTER_KEY => 'parent_id', + ], + ], + ], + ], + ])); + } } diff --git a/tests/ORM/Functional/Driver/Common/Relation/HasOne/HasOneProxyMapperTest.php b/tests/ORM/Functional/Driver/Common/Relation/HasOne/HasOneProxyMapperTest.php index f17a4151..e7f14f75 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/HasOne/HasOneProxyMapperTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/HasOne/HasOneProxyMapperTest.php @@ -21,110 +21,6 @@ abstract class HasOneProxyMapperTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('user', [ - 'id' => 'primary', - 'email' => 'string', - 'balance' => 'float', - ]); - - $this->makeTable('profile', [ - 'id' => 'primary', - 'user_id' => 'integer', - 'image' => 'string', - ]); - - $this->makeTable('nested', [ - 'id' => 'primary', - 'profile_id' => 'integer', - 'label' => 'string', - ]); - - $this->makeFK('profile', 'user_id', 'user', 'id'); - $this->makeFK('nested', 'profile_id', 'profile', 'id'); - - $this->getDatabase()->table('user')->insertMultiple( - ['email', 'balance'], - [ - ['hello@world.com', 100], - ['another@world.com', 200], - ] - ); - - $this->getDatabase()->table('profile')->insertMultiple( - ['user_id', 'image'], - [ - [1, 'image.png'], - ] - ); - - - $this->getDatabase()->table('nested')->insertMultiple( - ['profile_id', 'label'], - [ - [1, 'nested-label'], - ] - ); - - $this->orm = $this->withSchema(new Schema([ - User::class => [ - Schema::ROLE => 'user', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'user', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'email', 'balance'], - Schema::SCHEMA => [], - Schema::RELATIONS => [ - 'profile' => [ - Relation::TYPE => Relation::HAS_ONE, - Relation::TARGET => Profile::class, - Relation::LOAD => Relation::LOAD_PROMISE, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::INNER_KEY => 'id', - Relation::OUTER_KEY => 'user_id', - ], - ], - ], - ], - Profile::class => [ - Schema::ROLE => 'profile', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'profile', - Schema::PRIMARY_KEY => 'id', - Schema::FIND_BY_KEYS => ['user_id'], - Schema::COLUMNS => ['id', 'user_id', 'image'], - Schema::SCHEMA => [], - Schema::RELATIONS => [ - 'nested' => [ - Relation::TYPE => Relation::HAS_ONE, - Relation::TARGET => Nested::class, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::INNER_KEY => 'id', - Relation::OUTER_KEY => 'profile_id', - ], - ], - ], - ], - Nested::class => [ - Schema::ROLE => 'nested', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'nested', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'profile_id', 'label'], - Schema::SCHEMA => [], - Schema::RELATIONS => [], - ], - ])); - } - public function testFetchRelation(): void { $selector = new Select($this->orm, User::class); @@ -332,4 +228,108 @@ public function testMoveToAnotherUserPartial(): void $this->assertNull($a->profile); $this->assertEquals(1, $b->profile->id); } + + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('user', [ + 'id' => 'primary', + 'email' => 'string', + 'balance' => 'float', + ]); + + $this->makeTable('profile', [ + 'id' => 'primary', + 'user_id' => 'integer', + 'image' => 'string', + ]); + + $this->makeTable('nested', [ + 'id' => 'primary', + 'profile_id' => 'integer', + 'label' => 'string', + ]); + + $this->makeFK('profile', 'user_id', 'user', 'id'); + $this->makeFK('nested', 'profile_id', 'profile', 'id'); + + $this->getDatabase()->table('user')->insertMultiple( + ['email', 'balance'], + [ + ['hello@world.com', 100], + ['another@world.com', 200], + ], + ); + + $this->getDatabase()->table('profile')->insertMultiple( + ['user_id', 'image'], + [ + [1, 'image.png'], + ], + ); + + + $this->getDatabase()->table('nested')->insertMultiple( + ['profile_id', 'label'], + [ + [1, 'nested-label'], + ], + ); + + $this->orm = $this->withSchema(new Schema([ + User::class => [ + Schema::ROLE => 'user', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'user', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'email', 'balance'], + Schema::SCHEMA => [], + Schema::RELATIONS => [ + 'profile' => [ + Relation::TYPE => Relation::HAS_ONE, + Relation::TARGET => Profile::class, + Relation::LOAD => Relation::LOAD_PROMISE, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::INNER_KEY => 'id', + Relation::OUTER_KEY => 'user_id', + ], + ], + ], + ], + Profile::class => [ + Schema::ROLE => 'profile', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'profile', + Schema::PRIMARY_KEY => 'id', + Schema::FIND_BY_KEYS => ['user_id'], + Schema::COLUMNS => ['id', 'user_id', 'image'], + Schema::SCHEMA => [], + Schema::RELATIONS => [ + 'nested' => [ + Relation::TYPE => Relation::HAS_ONE, + Relation::TARGET => Nested::class, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::INNER_KEY => 'id', + Relation::OUTER_KEY => 'profile_id', + ], + ], + ], + ], + Nested::class => [ + Schema::ROLE => 'nested', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'nested', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'profile_id', 'label'], + Schema::SCHEMA => [], + Schema::RELATIONS => [], + ], + ])); + } } diff --git a/tests/ORM/Functional/Driver/Common/Relation/HasOne/HasOneRelationTest.php b/tests/ORM/Functional/Driver/Common/Relation/HasOne/HasOneRelationTest.php index e73e28ac..8068dc19 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/HasOne/HasOneRelationTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/HasOne/HasOneRelationTest.php @@ -23,108 +23,6 @@ abstract class HasOneRelationTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('user', [ - 'id' => 'primary', - 'email' => 'string', - 'balance' => 'float', - ]); - - $this->makeTable('profile', [ - 'id' => 'primary', - 'user_id' => 'integer,nullable', - 'image' => 'string', - ]); - - $this->makeTable('nested', [ - 'id' => 'primary', - 'profile_id' => 'integer', - 'label' => 'string', - ]); - - $this->makeFK('profile', 'user_id', 'user', 'id'); - $this->makeFK('nested', 'profile_id', 'profile', 'id'); - - $this->getDatabase()->table('user')->insertMultiple( - ['email', 'balance'], - [ - ['hello@world.com', 100], - ['another@world.com', 200], - ] - ); - - $this->getDatabase()->table('profile')->insertMultiple( - ['user_id', 'image'], - [ - [1, 'image.png'], - ] - ); - - - $this->getDatabase()->table('nested')->insertMultiple( - ['profile_id', 'label'], - [ - [1, 'nested-label'], - ] - ); - - $this->orm = $this->withSchema(new Schema([ - User::class => [ - Schema::ROLE => 'user', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'user', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'email', 'balance'], - Schema::SCHEMA => [], - Schema::RELATIONS => [ - 'profile' => [ - Relation::TYPE => Relation::HAS_ONE, - Relation::TARGET => Profile::class, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::INNER_KEY => 'id', - Relation::OUTER_KEY => 'user_id', - ], - ], - ], - ], - Profile::class => [ - Schema::ROLE => 'profile', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'profile', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'user_id', 'image'], - Schema::SCHEMA => [], - Schema::RELATIONS => [ - 'nested' => [ - Relation::TYPE => Relation::HAS_ONE, - Relation::TARGET => Nested::class, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::INNER_KEY => 'id', - Relation::OUTER_KEY => 'profile_id', - ], - ], - ], - ], - Nested::class => [ - Schema::ROLE => 'nested', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'nested', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'profile_id', 'label'], - Schema::SCHEMA => [], - Schema::RELATIONS => [], - ], - ])); - } - public function testHasInSchema(): void { $this->assertSame(['profile'], $this->orm->getSchema()->getRelations('user')); @@ -660,7 +558,7 @@ public function testDoNotOverwriteRelation(): void $this->assertSame('new', $u2->profile->image); $u3 = $this->orm->withHeap(new Heap())->getRepository(User::class) - ->select()->load('profile')->wherePK(1)->fetchOne(); + ->select()->load('profile')->wherePK(1)->fetchOne(); $this->assertSame('image.png', $u3->profile->image); @@ -669,7 +567,7 @@ public function testDoNotOverwriteRelation(): void $t->run(); $u4 = $this->orm->withHeap(new Heap())->getRepository(User::class) - ->select()->load('profile')->wherePK(1)->fetchOne(); + ->select()->load('profile')->wherePK(1)->fetchOne(); $this->assertSame('new', $u4->profile->image); } @@ -685,14 +583,14 @@ public function testOverwritePromisedRelation(): void // relation is already set prior to loading $u2 = $this->orm->getRepository(User::class) - ->select() - ->load('profile') - ->wherePK(1)->fetchOne(); + ->select() + ->load('profile') + ->wherePK(1)->fetchOne(); $this->assertSame('image.png', $u2->profile->image); $u3 = $this->orm->withHeap(new Heap())->getRepository(User::class) - ->select()->load('profile')->wherePK(1)->fetchOne(); + ->select()->load('profile')->wherePK(1)->fetchOne(); $this->assertSame('image.png', $u3->profile->image); @@ -702,7 +600,7 @@ public function testOverwritePromisedRelation(): void // ovewrite values $u4 = $this->orm->withHeap(new Heap())->getRepository(User::class) - ->select()->load('profile')->wherePK(1)->fetchOne(); + ->select()->load('profile')->wherePK(1)->fetchOne(); $this->assertSame('image.png', $u4->profile->image); @@ -713,4 +611,106 @@ public function testOverwritePromisedRelation(): void $this->assertNumWrites(0); } + + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('user', [ + 'id' => 'primary', + 'email' => 'string', + 'balance' => 'float', + ]); + + $this->makeTable('profile', [ + 'id' => 'primary', + 'user_id' => 'integer,nullable', + 'image' => 'string', + ]); + + $this->makeTable('nested', [ + 'id' => 'primary', + 'profile_id' => 'integer', + 'label' => 'string', + ]); + + $this->makeFK('profile', 'user_id', 'user', 'id'); + $this->makeFK('nested', 'profile_id', 'profile', 'id'); + + $this->getDatabase()->table('user')->insertMultiple( + ['email', 'balance'], + [ + ['hello@world.com', 100], + ['another@world.com', 200], + ], + ); + + $this->getDatabase()->table('profile')->insertMultiple( + ['user_id', 'image'], + [ + [1, 'image.png'], + ], + ); + + + $this->getDatabase()->table('nested')->insertMultiple( + ['profile_id', 'label'], + [ + [1, 'nested-label'], + ], + ); + + $this->orm = $this->withSchema(new Schema([ + User::class => [ + Schema::ROLE => 'user', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'user', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'email', 'balance'], + Schema::SCHEMA => [], + Schema::RELATIONS => [ + 'profile' => [ + Relation::TYPE => Relation::HAS_ONE, + Relation::TARGET => Profile::class, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::INNER_KEY => 'id', + Relation::OUTER_KEY => 'user_id', + ], + ], + ], + ], + Profile::class => [ + Schema::ROLE => 'profile', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'profile', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'user_id', 'image'], + Schema::SCHEMA => [], + Schema::RELATIONS => [ + 'nested' => [ + Relation::TYPE => Relation::HAS_ONE, + Relation::TARGET => Nested::class, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::INNER_KEY => 'id', + Relation::OUTER_KEY => 'profile_id', + ], + ], + ], + ], + Nested::class => [ + Schema::ROLE => 'nested', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'nested', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'profile_id', 'label'], + Schema::SCHEMA => [], + Schema::RELATIONS => [], + ], + ])); + } } diff --git a/tests/ORM/Functional/Driver/Common/Relation/InverseRelationTest.php b/tests/ORM/Functional/Driver/Common/Relation/InverseRelationTest.php index 1f28e95c..f936aa21 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/InverseRelationTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/InverseRelationTest.php @@ -20,87 +20,6 @@ abstract class InverseRelationTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('user', [ - 'id' => 'primary', - 'email' => 'string', - 'balance' => 'float', - ]); - - $this->getDatabase()->table('user')->insertMultiple( - ['email', 'balance'], - [ - ['hello@world.com', 100], - ['another@world.com', 200], - ] - ); - - $this->makeTable('profile', [ - 'id' => 'primary', - 'user_id' => 'integer', - 'image' => 'string', - ]); - - $this->makeFK('profile', 'user_id', 'user', 'id'); - - $this->getDatabase()->table('profile')->insertMultiple( - ['user_id', 'image'], - [ - [1, 'image.png'], - [2, 'second.png'], - [2, 'third.png'], - ] - ); - - $this->orm = $this->withSchema(new Schema([ - User::class => [ - Schema::ROLE => 'user', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'user', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'email', 'balance'], - Schema::SCHEMA => [], - Schema::RELATIONS => [ - 'profile' => [ - Relation::TYPE => Relation::HAS_ONE, - Relation::TARGET => Profile::class, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::INNER_KEY => 'id', - Relation::OUTER_KEY => 'user_id', - ], - ], - ], - Schema::SCOPE => SortByIDScope::class, - ], - Profile::class => [ - Schema::ROLE => 'profile', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'profile', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'user_id', 'image'], - Schema::SCHEMA => [], - Schema::RELATIONS => [ - 'user' => [ - Relation::TYPE => Relation::BELONGS_TO, - Relation::TARGET => User::class, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::INNER_KEY => 'user_id', - Relation::OUTER_KEY => 'id', - ], - ], - ], - Schema::SCOPE => SortByIDScope::class, - ], - ])); - } - public function testFetchRelation(): void { $selector = new Select($this->orm, User::class); @@ -180,4 +99,85 @@ public function testCyclicThoughtInverse(): void $this->orm = $this->orm->withHeap(new Heap()); } + + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('user', [ + 'id' => 'primary', + 'email' => 'string', + 'balance' => 'float', + ]); + + $this->getDatabase()->table('user')->insertMultiple( + ['email', 'balance'], + [ + ['hello@world.com', 100], + ['another@world.com', 200], + ], + ); + + $this->makeTable('profile', [ + 'id' => 'primary', + 'user_id' => 'integer', + 'image' => 'string', + ]); + + $this->makeFK('profile', 'user_id', 'user', 'id'); + + $this->getDatabase()->table('profile')->insertMultiple( + ['user_id', 'image'], + [ + [1, 'image.png'], + [2, 'second.png'], + [2, 'third.png'], + ], + ); + + $this->orm = $this->withSchema(new Schema([ + User::class => [ + Schema::ROLE => 'user', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'user', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'email', 'balance'], + Schema::SCHEMA => [], + Schema::RELATIONS => [ + 'profile' => [ + Relation::TYPE => Relation::HAS_ONE, + Relation::TARGET => Profile::class, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::INNER_KEY => 'id', + Relation::OUTER_KEY => 'user_id', + ], + ], + ], + Schema::SCOPE => SortByIDScope::class, + ], + Profile::class => [ + Schema::ROLE => 'profile', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'profile', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'user_id', 'image'], + Schema::SCHEMA => [], + Schema::RELATIONS => [ + 'user' => [ + Relation::TYPE => Relation::BELONGS_TO, + Relation::TARGET => User::class, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::INNER_KEY => 'user_id', + Relation::OUTER_KEY => 'id', + ], + ], + ], + Schema::SCOPE => SortByIDScope::class, + ], + ])); + } } diff --git a/tests/ORM/Functional/Driver/Common/Relation/LinkedTreeTest.php b/tests/ORM/Functional/Driver/Common/Relation/LinkedTreeTest.php index dd0fe150..c50e28b1 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/LinkedTreeTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/LinkedTreeTest.php @@ -20,83 +20,6 @@ abstract class LinkedTreeTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('user', [ - 'id' => 'primary', - 'email' => 'string', - 'balance' => 'float', - ]); - - $this->getDatabase()->table('user')->insertMultiple( - ['email', 'balance'], - [ - ['hello@world.com', 100], - ['another@world.com', 200], - ] - ); - - $this->makeTable('nested', [ - 'id' => 'primary', - 'user_id' => 'integer', - 'owner_id' => 'integer', - 'label' => 'string', - ]); - - $this->makeFK('nested', 'user_id', 'user', 'id'); - - $this->getDatabase()->table('nested')->insertMultiple( - ['user_id', 'owner_id', 'label'], - [ - [1, 2, 'nested-label'], - ] - ); - - $this->orm = $this->withSchema(new Schema([ - User::class => [ - Schema::ROLE => 'user', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'user', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'email', 'balance'], - Schema::SCHEMA => [], - Schema::RELATIONS => [ - 'nested' => [ - Relation::TYPE => Relation::HAS_ONE, - Relation::TARGET => Nested::class, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::INNER_KEY => 'id', - Relation::OUTER_KEY => 'user_id', - ], - ], - 'owned' => [ - Relation::TYPE => Relation::HAS_ONE, - Relation::TARGET => Nested::class, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::INNER_KEY => 'id', - Relation::OUTER_KEY => 'owner_id', - ], - ], - ], - ], - Nested::class => [ - Schema::ROLE => 'nested', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'nested', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'user_id', 'owner_id', 'label'], - Schema::SCHEMA => [], - Schema::RELATIONS => [], - ], - ])); - } - public function testFetchRelations(): void { $selector = new Select($this->orm, User::class); @@ -191,4 +114,81 @@ public function testCreateDoubleLinked(): void [$u1, $u2] = $selector->fetchAll(); $this->assertSame($u1->nested, $u2->owned); } + + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('user', [ + 'id' => 'primary', + 'email' => 'string', + 'balance' => 'float', + ]); + + $this->getDatabase()->table('user')->insertMultiple( + ['email', 'balance'], + [ + ['hello@world.com', 100], + ['another@world.com', 200], + ], + ); + + $this->makeTable('nested', [ + 'id' => 'primary', + 'user_id' => 'integer', + 'owner_id' => 'integer', + 'label' => 'string', + ]); + + $this->makeFK('nested', 'user_id', 'user', 'id'); + + $this->getDatabase()->table('nested')->insertMultiple( + ['user_id', 'owner_id', 'label'], + [ + [1, 2, 'nested-label'], + ], + ); + + $this->orm = $this->withSchema(new Schema([ + User::class => [ + Schema::ROLE => 'user', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'user', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'email', 'balance'], + Schema::SCHEMA => [], + Schema::RELATIONS => [ + 'nested' => [ + Relation::TYPE => Relation::HAS_ONE, + Relation::TARGET => Nested::class, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::INNER_KEY => 'id', + Relation::OUTER_KEY => 'user_id', + ], + ], + 'owned' => [ + Relation::TYPE => Relation::HAS_ONE, + Relation::TARGET => Nested::class, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::INNER_KEY => 'id', + Relation::OUTER_KEY => 'owner_id', + ], + ], + ], + ], + Nested::class => [ + Schema::ROLE => 'nested', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'nested', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'user_id', 'owner_id', 'label'], + Schema::SCHEMA => [], + Schema::RELATIONS => [], + ], + ])); + } } diff --git a/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/Cyclic/CyclicManyToManyTest.php b/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/Cyclic/CyclicManyToManyTest.php index 851f7afa..760c3693 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/Cyclic/CyclicManyToManyTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/Cyclic/CyclicManyToManyTest.php @@ -19,141 +19,6 @@ abstract class CyclicManyToManyTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable( - 'user', - [ - 'id' => 'primary', - 'email' => 'string', - 'balance' => 'float', - ] - ); - - $this->makeTable( - 'tag', - [ - 'id' => 'primary', - 'name' => 'string', - ] - ); - - $this->makeTable( - 'tag_user_map', - [ - 'id' => 'primary', - 'user_id' => 'integer', - 'tag_id' => 'integer', - 'as' => 'string,nullable', - ] - ); - - $this->makeFK('tag_user_map', 'user_id', 'user', 'id'); - $this->makeFK('tag_user_map', 'tag_id', 'tag', 'id'); - $this->makeIndex('tag_user_map', ['user_id', 'tag_id'], true); - - $this->getDatabase()->table('user')->insertMultiple( - ['email', 'balance'], - [ - ['hello@world.com', 100], - ['another@world.com', 200], - ] - ); - - $this->getDatabase()->table('tag')->insertMultiple( - ['name'], - [ - ['tag a'], - ['tag b'], - ['tag c'], - ] - ); - - $this->getDatabase()->table('tag_user_map')->insertMultiple( - ['user_id', 'tag_id', 'as'], - [ - [1, 1, 'primary'], - [1, 2, 'secondary'], - [2, 3, 'primary'], - ] - ); - - $this->orm = $this->withSchema( - new Schema( - [ - User::class => [ - Schema::ROLE => 'user', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'user', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'email', 'balance'], - Schema::TYPECAST => ['id' => 'int', 'balance' => 'float'], - Schema::SCHEMA => [], - Schema::RELATIONS => [ - 'tags' => [ - Relation::TYPE => Relation::MANY_TO_MANY, - Relation::TARGET => Tag::class, - Relation::LOAD => Relation::LOAD_PROMISE, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::NULLABLE => false, - Relation::THROUGH_ENTITY => TagContext::class, - Relation::INNER_KEY => 'id', - Relation::OUTER_KEY => 'id', - Relation::THROUGH_INNER_KEY => 'user_id', - Relation::THROUGH_OUTER_KEY => 'tag_id', - Relation::WHERE => [], - ], - ], - ], - ], - Tag::class => [ - Schema::ROLE => 'tag', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'tag', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'name'], - Schema::TYPECAST => ['id' => 'int'], - Schema::SCHEMA => [], - Schema::RELATIONS => [ - 'users' => [ - Relation::TYPE => Relation::MANY_TO_MANY, - Relation::TARGET => User::class, - Relation::LOAD => Relation::LOAD_PROMISE, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::NULLABLE => false, - Relation::THROUGH_ENTITY => TagContext::class, - Relation::INNER_KEY => 'id', - Relation::OUTER_KEY => 'id', - Relation::THROUGH_INNER_KEY => 'tag_id', - Relation::THROUGH_OUTER_KEY => 'user_id', - Relation::WHERE => [], - Relation::THROUGH_WHERE => [], - ], - ], - ], - ], - TagContext::class => [ - Schema::ROLE => 'tag_context', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'tag_user_map', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'user_id', 'tag_id', 'as'], - Schema::TYPECAST => ['id' => 'int', 'user_id' => 'int', 'tag_id' => 'int'], - Schema::SCHEMA => [], - Schema::RELATIONS => [], - ], - ] - ) - ); - } - public function testLoadRelation(): void { $selector = new Select($this->orm, User::class); @@ -206,7 +71,7 @@ public function testLoadRelation(): void ], ], ], - $selector->fetchData() + $selector->fetchData(), ); } @@ -295,4 +160,139 @@ public function testCreateCyclicWithExisting(): void // // $this->assertTrue($found); } + + public function setUp(): void + { + parent::setUp(); + + $this->makeTable( + 'user', + [ + 'id' => 'primary', + 'email' => 'string', + 'balance' => 'float', + ], + ); + + $this->makeTable( + 'tag', + [ + 'id' => 'primary', + 'name' => 'string', + ], + ); + + $this->makeTable( + 'tag_user_map', + [ + 'id' => 'primary', + 'user_id' => 'integer', + 'tag_id' => 'integer', + 'as' => 'string,nullable', + ], + ); + + $this->makeFK('tag_user_map', 'user_id', 'user', 'id'); + $this->makeFK('tag_user_map', 'tag_id', 'tag', 'id'); + $this->makeIndex('tag_user_map', ['user_id', 'tag_id'], true); + + $this->getDatabase()->table('user')->insertMultiple( + ['email', 'balance'], + [ + ['hello@world.com', 100], + ['another@world.com', 200], + ], + ); + + $this->getDatabase()->table('tag')->insertMultiple( + ['name'], + [ + ['tag a'], + ['tag b'], + ['tag c'], + ], + ); + + $this->getDatabase()->table('tag_user_map')->insertMultiple( + ['user_id', 'tag_id', 'as'], + [ + [1, 1, 'primary'], + [1, 2, 'secondary'], + [2, 3, 'primary'], + ], + ); + + $this->orm = $this->withSchema( + new Schema( + [ + User::class => [ + Schema::ROLE => 'user', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'user', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'email', 'balance'], + Schema::TYPECAST => ['id' => 'int', 'balance' => 'float'], + Schema::SCHEMA => [], + Schema::RELATIONS => [ + 'tags' => [ + Relation::TYPE => Relation::MANY_TO_MANY, + Relation::TARGET => Tag::class, + Relation::LOAD => Relation::LOAD_PROMISE, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::NULLABLE => false, + Relation::THROUGH_ENTITY => TagContext::class, + Relation::INNER_KEY => 'id', + Relation::OUTER_KEY => 'id', + Relation::THROUGH_INNER_KEY => 'user_id', + Relation::THROUGH_OUTER_KEY => 'tag_id', + Relation::WHERE => [], + ], + ], + ], + ], + Tag::class => [ + Schema::ROLE => 'tag', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'tag', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'name'], + Schema::TYPECAST => ['id' => 'int'], + Schema::SCHEMA => [], + Schema::RELATIONS => [ + 'users' => [ + Relation::TYPE => Relation::MANY_TO_MANY, + Relation::TARGET => User::class, + Relation::LOAD => Relation::LOAD_PROMISE, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::NULLABLE => false, + Relation::THROUGH_ENTITY => TagContext::class, + Relation::INNER_KEY => 'id', + Relation::OUTER_KEY => 'id', + Relation::THROUGH_INNER_KEY => 'tag_id', + Relation::THROUGH_OUTER_KEY => 'user_id', + Relation::WHERE => [], + Relation::THROUGH_WHERE => [], + ], + ], + ], + ], + TagContext::class => [ + Schema::ROLE => 'tag_context', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'tag_user_map', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'user_id', 'tag_id', 'as'], + Schema::TYPECAST => ['id' => 'int', 'user_id' => 'int', 'tag_id' => 'int'], + Schema::SCHEMA => [], + Schema::RELATIONS => [], + ], + ], + ), + ); + } } diff --git a/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/Cyclic/CyclicManyToManyTypedTest.php b/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/Cyclic/CyclicManyToManyTypedTest.php index 6e25553a..d72217d1 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/Cyclic/CyclicManyToManyTypedTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/Cyclic/CyclicManyToManyTypedTest.php @@ -18,6 +18,23 @@ abstract class CyclicManyToManyTypedTest extends BaseTest { use TableTrait; + public function testCreateCyclicWithExisting(): void + { + $u = new User(); + $u->email = 'hello@world.com'; + $u->balance = 1; + + $tag = $this->orm->getRepository(Tag::class)->findByPK(1); + + $tag->users->add($u); + $u->tags->add($tag); + + $t = new Transaction($this->orm); + $t->persist($tag); + + $t->run(); + } + public function setUp(): void { if (!version_compare(PHP_VERSION, '7.4', '>=')) { @@ -54,7 +71,7 @@ public function setUp(): void [ ['hello@world.com', 100], ['another@world.com', 200], - ] + ], ); $this->getDatabase()->table('tag')->insertMultiple( @@ -63,7 +80,7 @@ public function setUp(): void ['tag a'], ['tag b'], ['tag c'], - ] + ], ); $this->getDatabase()->table('tag_user_map')->insertMultiple( @@ -72,7 +89,7 @@ public function setUp(): void [1, 1, 'primary'], [1, 2, 'secondary'], [2, 3, 'primary'], - ] + ], ); $this->orm = $this->withSchema(new Schema([ @@ -145,21 +162,4 @@ public function setUp(): void ], ])); } - - public function testCreateCyclicWithExisting(): void - { - $u = new User(); - $u->email = 'hello@world.com'; - $u->balance = 1; - - $tag = $this->orm->getRepository(Tag::class)->findByPK(1); - - $tag->users->add($u); - $u->tags->add($tag); - - $t = new Transaction($this->orm); - $t->persist($tag); - - $t->run(); - } } diff --git a/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/Cyclic/CyclingManyToManyWithTimestampsTest.php b/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/Cyclic/CyclingManyToManyWithTimestampsTest.php index f0f4cc36..465fd5d1 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/Cyclic/CyclingManyToManyWithTimestampsTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/Cyclic/CyclingManyToManyWithTimestampsTest.php @@ -18,6 +18,41 @@ abstract class CyclingManyToManyWithTimestampsTest extends BaseTest { use TableTrait; + public function testCreateCyclicWithExistingSingleTimestamp(): void + { + $u = new User(); + $u->email = 'hello@world.com'; + $u->balance = 1; + + $tag = $this->orm->getRepository(Tag::class)->findByPK(1); + + $tag->users->add($u); + $u->tags->add($tag); + + $this->captureWriteQueries(); + $t = new Transaction($this->orm); + $t->persist($tag); + $t->run(); + $this->assertNumWrites(2); + } + + public function testCreateCyclicWithNewSingleTimestamp(): void + { + $u = new User(); + $u->email = 'hello@world.com'; + $u->balance = 1; + + $tag = new Tag(); + $tag->name = 'new tag'; + + $tag->users->add($u); + $u->tags->add($tag); + + $this->captureWriteQueries(); + $this->save($tag); + $this->assertNumWrites(3); + } + public function setUp(): void { parent::setUp(); @@ -30,7 +65,7 @@ public function setUp(): void 'balance' => 'float', 'created_at' => 'datetime', 'updated_at' => 'datetime', - ] + ], ); $this->makeTable( @@ -40,7 +75,7 @@ public function setUp(): void 'name' => 'string', 'created_at' => 'datetime', 'updated_at' => 'datetime', - ] + ], ); $this->makeTable( @@ -52,7 +87,7 @@ public function setUp(): void 'as' => 'string,nullable', 'created_at' => 'datetime', 'updated_at' => 'datetime', - ] + ], ); $this->makeFK('tag_user_map', 'user_id', 'user', 'id'); @@ -64,7 +99,7 @@ public function setUp(): void [ ['hello@world.com', 100], ['another@world.com', 200], - ] + ], ); $this->getDatabase()->table('tag')->insertMultiple( @@ -73,7 +108,7 @@ public function setUp(): void ['tag a'], ['tag b'], ['tag c'], - ] + ], ); $this->getDatabase()->table('tag_user_map')->insertMultiple( @@ -82,7 +117,7 @@ public function setUp(): void [1, 1, 'primary'], [1, 2, 'secondary'], [2, 3, 'primary'], - ] + ], ); $this->orm = $this->withSchema( @@ -155,43 +190,8 @@ public function setUp(): void Schema::SCHEMA => [], Schema::RELATIONS => [], ], - ] - ) + ], + ), ); } - - public function testCreateCyclicWithExistingSingleTimestamp(): void - { - $u = new User(); - $u->email = 'hello@world.com'; - $u->balance = 1; - - $tag = $this->orm->getRepository(Tag::class)->findByPK(1); - - $tag->users->add($u); - $u->tags->add($tag); - - $this->captureWriteQueries(); - $t = new Transaction($this->orm); - $t->persist($tag); - $t->run(); - $this->assertNumWrites(2); - } - - public function testCreateCyclicWithNewSingleTimestamp(): void - { - $u = new User(); - $u->email = 'hello@world.com'; - $u->balance = 1; - - $tag = new Tag(); - $tag->name = 'new tag'; - - $tag->users->add($u); - $u->tags->add($tag); - - $this->captureWriteQueries(); - $this->save($tag); - $this->assertNumWrites(3); - } } diff --git a/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/ManyToManyBelongsToTest.php b/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/ManyToManyBelongsToTest.php index bfd205a5..534957a9 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/ManyToManyBelongsToTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/ManyToManyBelongsToTest.php @@ -28,76 +28,6 @@ abstract class ManyToManyBelongsToTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('user', [ - 'id' => 'primary', - 'email' => 'string', - ]); - - $this->makeTable('post', [ - 'id' => 'primary', - 'user_id' => 'integer', - 'title' => 'string', - ]); - - $this->makeTable('tag', [ - 'id' => 'primary', - 'name' => 'string', - ]); - - $this->makeTable('tag_post_map', [ - 'id' => 'primary', - 'post_id' => 'integer', - 'tag_id' => 'integer', - 'as' => 'string,nullable', - ]); - - $this->makeFK('post', 'user_id', 'user', 'id'); - $this->makeFK('tag_post_map', 'post_id', 'post', 'id'); - $this->makeFK('tag_post_map', 'tag_id', 'tag', 'id'); - - $this->getDatabase()->table('user')->insertMultiple( - ['email'], - [ - ['hello@world.com'], - ['another@world.com'], - ] - ); - $this->getDatabase()->table('post')->insertMultiple( - ['user_id', 'title'], - [ - [1, 'Post title 1-1'], - [1, 'Post title 1-2'], - [2, 'Post title 2-1'], - [2, 'Post title 2-2'], - [2, 'Post title 2-3'], - ] - ); - - $this->getDatabase()->table('tag')->insertMultiple( - ['name'], - [ - ['tag a'], - ['tag b'], - ['tag c'], - ] - ); - - $this->getDatabase()->table('tag_post_map')->insertMultiple( - ['post_id', 'tag_id', 'as'], - [ - [1, 1, 'primary'], - [1, 2, 'secondary'], - [2, 3, 'primary'], - ] - ); - - $this->orm = $this->withSchema(new Schema($this->getSchemaArray())); - } - public function testCreate(): void { $user = new User(); @@ -110,7 +40,7 @@ public function testCreate(): void [ new Tag(), new Tag(), - ] + ], ); $post->comments[0]->name = 'name 1'; $post->comments[1]->name = 'name 2'; @@ -144,7 +74,7 @@ public function testUpdate(): void [ new Tag(), new Tag(), - ] + ], ); $post->comments[0]->name = 'name 1'; $post->comments[1]->name = 'name 2'; @@ -170,6 +100,76 @@ public function testUpdate(): void $this->assertSame('new name', $p->comments[0]->name); } + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('user', [ + 'id' => 'primary', + 'email' => 'string', + ]); + + $this->makeTable('post', [ + 'id' => 'primary', + 'user_id' => 'integer', + 'title' => 'string', + ]); + + $this->makeTable('tag', [ + 'id' => 'primary', + 'name' => 'string', + ]); + + $this->makeTable('tag_post_map', [ + 'id' => 'primary', + 'post_id' => 'integer', + 'tag_id' => 'integer', + 'as' => 'string,nullable', + ]); + + $this->makeFK('post', 'user_id', 'user', 'id'); + $this->makeFK('tag_post_map', 'post_id', 'post', 'id'); + $this->makeFK('tag_post_map', 'tag_id', 'tag', 'id'); + + $this->getDatabase()->table('user')->insertMultiple( + ['email'], + [ + ['hello@world.com'], + ['another@world.com'], + ], + ); + $this->getDatabase()->table('post')->insertMultiple( + ['user_id', 'title'], + [ + [1, 'Post title 1-1'], + [1, 'Post title 1-2'], + [2, 'Post title 2-1'], + [2, 'Post title 2-2'], + [2, 'Post title 2-3'], + ], + ); + + $this->getDatabase()->table('tag')->insertMultiple( + ['name'], + [ + ['tag a'], + ['tag b'], + ['tag c'], + ], + ); + + $this->getDatabase()->table('tag_post_map')->insertMultiple( + ['post_id', 'tag_id', 'as'], + [ + [1, 1, 'primary'], + [1, 2, 'secondary'], + [2, 3, 'primary'], + ], + ); + + $this->orm = $this->withSchema(new Schema($this->getSchemaArray())); + } + private function getSchemaArray(): array { return [ diff --git a/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/ManyToManyCompositeKeyTest.php b/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/ManyToManyCompositeKeyTest.php index 93433038..bcdf126c 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/ManyToManyCompositeKeyTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/ManyToManyCompositeKeyTest.php @@ -22,170 +22,71 @@ abstract class ManyToManyCompositeKeyTest extends BaseTest { use TableTrait; - protected const - CHILDREN_CONTAINER = 'pivoted'; - protected const - PARENTS_CONTAINER = 'pivoted'; - protected const - PARENT_1 = ['key1' => 1, 'key2' => 1, 'key3' => 101]; - protected const - PARENT_2 = ['key1' => 1, 'key2' => 2, 'key3' => 102]; - protected const - PARENT_3 = ['key1' => 2, 'key2' => 1, 'key3' => 201]; - protected const - PARENT_4 = ['key1' => 2, 'key2' => 2, 'key3' => 202]; - protected const - CHILD_1 = ['key1' => 1, 'key2' => 1, 'key3' => null]; - protected const - CHILD_2 = ['key1' => 1, 'key2' => 2, 'key3' => 'foo1']; - protected const - CHILD_3 = ['key1' => 2, 'key2' => 1, 'key3' => 'bar1']; - protected const - CHILD_4 = ['key1' => 3, 'key2' => 3, 'key3' => 'fiz']; - protected const - PIVOT_1_1 = [ - 'parent_key1' => self::PARENT_1['key1'], 'parent_key2' => self::PARENT_1['key2'], - 'child_key1' => self::CHILD_1['key1'], 'child_key2' => self::CHILD_1['key2'], - 'as' => 'foo1', - ]; - protected const - PIVOT_1_2 = [ - 'parent_key1' => self::PARENT_1['key1'], 'parent_key2' => self::PARENT_1['key2'], - 'child_key1' => self::CHILD_2['key1'], 'child_key2' => self::CHILD_2['key2'], - 'as' => 'foo2', - ]; - protected const - PIVOT_1_3 = [ - 'parent_key1' => self::PARENT_1['key1'], 'parent_key2' => self::PARENT_1['key2'], - 'child_key1' => self::CHILD_3['key1'], 'child_key2' => self::CHILD_3['key2'], - 'as' => 'foo3', - ]; - protected const - PIVOT_2_2 = [ - 'parent_key1' => self::PARENT_2['key1'], 'parent_key2' => self::PARENT_2['key2'], - 'child_key1' => self::CHILD_2['key1'], 'child_key2' => self::CHILD_2['key2'], - 'as' => 'bar2', - ]; - protected const - PIVOT_2_3 = [ - 'parent_key1' => self::PARENT_2['key1'], 'parent_key2' => self::PARENT_2['key2'], - 'child_key1' => self::CHILD_3['key1'], 'child_key2' => self::CHILD_3['key2'], - 'as' => 'bar2', - ]; - protected const - PIVOT_3_3 = [ - 'parent_key1' => self::PARENT_3['key1'], 'parent_key2' => self::PARENT_3['key2'], - 'child_key1' => self::CHILD_3['key1'], 'child_key2' => self::CHILD_3['key2'], - 'as' => 'baz3', - ]; - protected const - PARENT_1_FULL = self::PARENT_1 + [ - self::CHILDREN_CONTAINER => [ - ['key1' => 1] + self::PIVOT_1_1 + ['@' => self::CHILD_1], - ['key1' => 2] + self::PIVOT_1_2 + ['@' => self::CHILD_2], - ['key1' => 3] + self::PIVOT_1_3 + ['@' => self::CHILD_3], - ], - ]; - protected const - PARENT_2_FULL = self::PARENT_2 + [ - self::CHILDREN_CONTAINER => [ - ['key1' => 4] + self::PIVOT_2_2 + ['@' => self::CHILD_2], - ['key1' => 5] + self::PIVOT_2_3 + ['@' => self::CHILD_3], - ], - ]; - protected const - PARENT_3_FULL = self::PARENT_3 + [ - self::CHILDREN_CONTAINER => [ - ['key1' => 6] + self::PIVOT_3_3 + ['@' => self::CHILD_3], - ], - ]; - protected const - PARENT_4_FULL = self::PARENT_4 + [self::CHILDREN_CONTAINER => []]; - protected const - PARENTS_FULL = [ - self::PARENT_1_FULL, - self::PARENT_2_FULL, - self::PARENT_3_FULL, - self::PARENT_4_FULL, - ]; - - public function setUp(): void - { - parent::setUp(); - - $this->makeTable( - 'parent_entity', - [ - 'pField1' => 'bigInteger,primary', - 'pField2' => 'bigInteger,primary', - 'pField3' => 'integer,nullable', - ] - ); - $this->makeTable( - 'child_entity', - [ - 'field1' => 'bigInteger,primary', - 'field2' => 'bigInteger,primary', - 'field3' => 'string,nullable', - 'parent_field1' => 'bigInteger,null', - 'parent_field2' => 'bigInteger,null', - ] - ); - $this->makeTable('pivot_entity', [ - 'pivot_id' => 'primary', - 'parent_field_1' => 'bigInteger', - 'parent_field_2' => 'bigInteger', - 'child_field_1' => 'bigInteger', - 'child_field_2' => 'bigInteger', - 'as' => 'string,nullable', - ]); - - $this->makeCompositeFK( - 'pivot_entity', - ['parent_field_1', 'parent_field_2'], - 'parent_entity', - ['pField1', 'pField2'] - ); - $this->makeCompositeFK( - 'pivot_entity', - ['child_field_1', 'child_field_2'], - 'child_entity', - ['field1', 'field2'] - ); - $this->makeIndex('pivot_entity', ['parent_field_1', 'parent_field_2', 'child_field_1', 'child_field_2'], true); - - $this->getDatabase()->table('parent_entity')->insertMultiple( - ['pField1', 'pField2', 'pField3'], - [ - self::PARENT_1, - self::PARENT_2, - self::PARENT_3, - self::PARENT_4, - ] - ); - $this->getDatabase()->table('child_entity')->insertMultiple( - ['field1', 'field2', 'field3'], - [ - self::CHILD_1, - self::CHILD_2, - self::CHILD_3, - self::CHILD_4, - ] - ); - $this->getDatabase()->table('pivot_entity')->insertMultiple( - ['parent_field_1', 'parent_field_2', 'child_field_1', 'child_field_2', 'as'], - [ - self::PIVOT_1_1, - self::PIVOT_1_2, - self::PIVOT_1_3, - self::PIVOT_2_2, - self::PIVOT_2_3, - self::PIVOT_3_3, - ] - ); - - $this->orm = $this->withSchema(new Schema($this->getSchemaArray())); - } + protected const CHILDREN_CONTAINER = 'pivoted'; + protected const PARENTS_CONTAINER = 'pivoted'; + protected const PARENT_1 = ['key1' => 1, 'key2' => 1, 'key3' => 101]; + protected const PARENT_2 = ['key1' => 1, 'key2' => 2, 'key3' => 102]; + protected const PARENT_3 = ['key1' => 2, 'key2' => 1, 'key3' => 201]; + protected const PARENT_4 = ['key1' => 2, 'key2' => 2, 'key3' => 202]; + protected const CHILD_1 = ['key1' => 1, 'key2' => 1, 'key3' => null]; + protected const CHILD_2 = ['key1' => 1, 'key2' => 2, 'key3' => 'foo1']; + protected const CHILD_3 = ['key1' => 2, 'key2' => 1, 'key3' => 'bar1']; + protected const CHILD_4 = ['key1' => 3, 'key2' => 3, 'key3' => 'fiz']; + protected const PIVOT_1_1 = [ + 'parent_key1' => self::PARENT_1['key1'], 'parent_key2' => self::PARENT_1['key2'], + 'child_key1' => self::CHILD_1['key1'], 'child_key2' => self::CHILD_1['key2'], + 'as' => 'foo1', + ]; + protected const PIVOT_1_2 = [ + 'parent_key1' => self::PARENT_1['key1'], 'parent_key2' => self::PARENT_1['key2'], + 'child_key1' => self::CHILD_2['key1'], 'child_key2' => self::CHILD_2['key2'], + 'as' => 'foo2', + ]; + protected const PIVOT_1_3 = [ + 'parent_key1' => self::PARENT_1['key1'], 'parent_key2' => self::PARENT_1['key2'], + 'child_key1' => self::CHILD_3['key1'], 'child_key2' => self::CHILD_3['key2'], + 'as' => 'foo3', + ]; + protected const PIVOT_2_2 = [ + 'parent_key1' => self::PARENT_2['key1'], 'parent_key2' => self::PARENT_2['key2'], + 'child_key1' => self::CHILD_2['key1'], 'child_key2' => self::CHILD_2['key2'], + 'as' => 'bar2', + ]; + protected const PIVOT_2_3 = [ + 'parent_key1' => self::PARENT_2['key1'], 'parent_key2' => self::PARENT_2['key2'], + 'child_key1' => self::CHILD_3['key1'], 'child_key2' => self::CHILD_3['key2'], + 'as' => 'bar2', + ]; + protected const PIVOT_3_3 = [ + 'parent_key1' => self::PARENT_3['key1'], 'parent_key2' => self::PARENT_3['key2'], + 'child_key1' => self::CHILD_3['key1'], 'child_key2' => self::CHILD_3['key2'], + 'as' => 'baz3', + ]; + protected const PARENT_1_FULL = self::PARENT_1 + [ + self::CHILDREN_CONTAINER => [ + ['key1' => 1] + self::PIVOT_1_1 + ['@' => self::CHILD_1], + ['key1' => 2] + self::PIVOT_1_2 + ['@' => self::CHILD_2], + ['key1' => 3] + self::PIVOT_1_3 + ['@' => self::CHILD_3], + ], + ]; + protected const PARENT_2_FULL = self::PARENT_2 + [ + self::CHILDREN_CONTAINER => [ + ['key1' => 4] + self::PIVOT_2_2 + ['@' => self::CHILD_2], + ['key1' => 5] + self::PIVOT_2_3 + ['@' => self::CHILD_3], + ], + ]; + protected const PARENT_3_FULL = self::PARENT_3 + [ + self::CHILDREN_CONTAINER => [ + ['key1' => 6] + self::PIVOT_3_3 + ['@' => self::CHILD_3], + ], + ]; + protected const PARENT_4_FULL = self::PARENT_4 + [self::CHILDREN_CONTAINER => []]; + protected const PARENTS_FULL = [ + self::PARENT_1_FULL, + self::PARENT_2_FULL, + self::PARENT_3_FULL, + self::PARENT_4_FULL, + ]; public function testInitRelation(): void { @@ -496,6 +397,84 @@ public function testReassign(): void $this->assertSame(self::CHILD_4['key3'], $u->pivoted[1]->key3); } + public function setUp(): void + { + parent::setUp(); + + $this->makeTable( + 'parent_entity', + [ + 'pField1' => 'bigInteger,primary', + 'pField2' => 'bigInteger,primary', + 'pField3' => 'integer,nullable', + ], + ); + $this->makeTable( + 'child_entity', + [ + 'field1' => 'bigInteger,primary', + 'field2' => 'bigInteger,primary', + 'field3' => 'string,nullable', + 'parent_field1' => 'bigInteger,null', + 'parent_field2' => 'bigInteger,null', + ], + ); + $this->makeTable('pivot_entity', [ + 'pivot_id' => 'primary', + 'parent_field_1' => 'bigInteger', + 'parent_field_2' => 'bigInteger', + 'child_field_1' => 'bigInteger', + 'child_field_2' => 'bigInteger', + 'as' => 'string,nullable', + ]); + + $this->makeCompositeFK( + 'pivot_entity', + ['parent_field_1', 'parent_field_2'], + 'parent_entity', + ['pField1', 'pField2'], + ); + $this->makeCompositeFK( + 'pivot_entity', + ['child_field_1', 'child_field_2'], + 'child_entity', + ['field1', 'field2'], + ); + $this->makeIndex('pivot_entity', ['parent_field_1', 'parent_field_2', 'child_field_1', 'child_field_2'], true); + + $this->getDatabase()->table('parent_entity')->insertMultiple( + ['pField1', 'pField2', 'pField3'], + [ + self::PARENT_1, + self::PARENT_2, + self::PARENT_3, + self::PARENT_4, + ], + ); + $this->getDatabase()->table('child_entity')->insertMultiple( + ['field1', 'field2', 'field3'], + [ + self::CHILD_1, + self::CHILD_2, + self::CHILD_3, + self::CHILD_4, + ], + ); + $this->getDatabase()->table('pivot_entity')->insertMultiple( + ['parent_field_1', 'parent_field_2', 'child_field_1', 'child_field_2', 'as'], + [ + self::PIVOT_1_1, + self::PIVOT_1_2, + self::PIVOT_1_3, + self::PIVOT_2_2, + self::PIVOT_2_3, + self::PIVOT_3_3, + ], + ); + + $this->orm = $this->withSchema(new Schema($this->getSchemaArray())); + } + private function getSchemaArray(): array { return [ diff --git a/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/ManyToManyDeepenedTest.php b/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/ManyToManyDeepenedTest.php index 706db1f8..41fee808 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/ManyToManyDeepenedTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/ManyToManyDeepenedTest.php @@ -29,74 +29,6 @@ abstract class ManyToManyDeepenedTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('user', [ - 'id' => 'primary', - 'email' => 'string', - 'balance' => 'float', - ]); - - $this->makeTable('tag', [ - 'id' => 'primary', - 'name' => 'string', - ]); - - $this->makeTable('tag_user_map', [ - 'id' => 'primary', - 'user_id' => 'integer', - 'tag_id' => 'integer', - 'as' => 'string,nullable', - ]); - - $this->makeTable('images', [ - 'id' => 'primary', - 'parent_id' => 'integer', - 'url' => 'string', - ]); - - $this->makeFK('tag_user_map', 'user_id', 'user', 'id'); - $this->makeFK('tag_user_map', 'tag_id', 'tag', 'id'); - - $this->getDatabase()->table('user')->insertMultiple( - ['email', 'balance'], - [ - ['hello@world.com', 100], - ['another@world.com', 200], - ] - ); - - $this->getDatabase()->table('tag')->insertMultiple( - ['name'], - [ - ['tag a'], - ['tag b'], - ['tag c'], - ] - ); - - $this->getDatabase()->table('tag_user_map')->insertMultiple( - ['user_id', 'tag_id', 'as'], - [ - [1, 1, 'primary'], - [1, 2, 'secondary'], - [2, 3, 'primary'], - ] - ); - - $this->getDatabase()->table('images')->insertMultiple( - ['parent_id', 'url'], - [ - [1, 'first.jpg'], - [3, 'second.png'], - ] - ); - - $this->orm = $this->withSchema(new Schema($this->getSchemaArray())); - } - public function testLoadRelation(): void { $selector = new Select($this->orm, User::class); @@ -403,6 +335,74 @@ public function testFilterByPivotedBranch(): void ], $selector->fetchData()); } + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('user', [ + 'id' => 'primary', + 'email' => 'string', + 'balance' => 'float', + ]); + + $this->makeTable('tag', [ + 'id' => 'primary', + 'name' => 'string', + ]); + + $this->makeTable('tag_user_map', [ + 'id' => 'primary', + 'user_id' => 'integer', + 'tag_id' => 'integer', + 'as' => 'string,nullable', + ]); + + $this->makeTable('images', [ + 'id' => 'primary', + 'parent_id' => 'integer', + 'url' => 'string', + ]); + + $this->makeFK('tag_user_map', 'user_id', 'user', 'id'); + $this->makeFK('tag_user_map', 'tag_id', 'tag', 'id'); + + $this->getDatabase()->table('user')->insertMultiple( + ['email', 'balance'], + [ + ['hello@world.com', 100], + ['another@world.com', 200], + ], + ); + + $this->getDatabase()->table('tag')->insertMultiple( + ['name'], + [ + ['tag a'], + ['tag b'], + ['tag c'], + ], + ); + + $this->getDatabase()->table('tag_user_map')->insertMultiple( + ['user_id', 'tag_id', 'as'], + [ + [1, 1, 'primary'], + [1, 2, 'secondary'], + [2, 3, 'primary'], + ], + ); + + $this->getDatabase()->table('images')->insertMultiple( + ['parent_id', 'url'], + [ + [1, 'first.jpg'], + [3, 'second.png'], + ], + ); + + $this->orm = $this->withSchema(new Schema($this->getSchemaArray())); + } + private function getSchemaArray(): array { return [ diff --git a/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/ManyToManyLoadingTest.php b/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/ManyToManyLoadingTest.php index fc6cf0a8..c0d2c82e 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/ManyToManyLoadingTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/ManyToManyLoadingTest.php @@ -24,6 +24,121 @@ abstract class ManyToManyLoadingTest extends BaseTest { use TableTrait; + public function testLoadSortedByPivot(): void + { + $selector = new Select($this->orm, User::class); + $selector->load('tags', [ + 'load' => function (Select\QueryBuilder $q): void { + $q->orderBy('@.@.as', 'DESC'); + }, + ])->orderBy('id', 'ASC'); + + $this->assertSame([ + [ + 'id' => 1, + 'email' => 'hello@world.com', + 'balance' => 100.0, + 'tags' => [ + [ + 'id' => 2, + 'user_id' => 1, + 'tag_id' => 2, + 'as' => 'secondary', + '@' => [ + 'id' => 2, + 'name' => 'tag b', + ], + ], + [ + 'id' => 1, + 'user_id' => 1, + 'tag_id' => 1, + 'as' => 'primary', + '@' => [ + 'id' => 1, + 'name' => 'tag a', + ], + ], + ], + ], + [ + 'id' => 2, + 'email' => 'another@world.com', + 'balance' => 200.0, + 'tags' => [ + [ + 'id' => 3, + 'user_id' => 2, + 'tag_id' => 3, + 'as' => 'primary', + '@' => [ + 'id' => 3, + 'name' => 'tag c', + ], + ], + ], + ], + ], $selector->fetchData()); + } + + public function testLoadSortedByPivotInload(): void + { + $selector = new Select($this->orm, User::class); + $selector->load('tags', [ + 'method' => Select::SINGLE_QUERY, + 'load' => function (Select\QueryBuilder $q): void { + $q->orderBy('@.@.as', 'DESC'); + }, + ])->orderBy('id', 'ASC'); + + $this->assertSame([ + [ + 'id' => 1, + 'email' => 'hello@world.com', + 'balance' => 100.0, + 'tags' => [ + [ + 'id' => 2, + 'user_id' => 1, + 'tag_id' => 2, + 'as' => 'secondary', + '@' => [ + 'id' => 2, + 'name' => 'tag b', + ], + ], + [ + 'id' => 1, + 'user_id' => 1, + 'tag_id' => 1, + 'as' => 'primary', + '@' => [ + 'id' => 1, + 'name' => 'tag a', + ], + ], + ], + ], + [ + 'id' => 2, + 'email' => 'another@world.com', + 'balance' => 200.0, + 'tags' => [ + [ + 'id' => 3, + 'user_id' => 2, + 'tag_id' => 3, + 'as' => 'primary', + '@' => [ + 'id' => 3, + 'name' => 'tag c', + ], + ], + ], + ], + ], $selector->fetchData()); + } + public function setUp(): void { parent::setUp(); @@ -60,7 +175,7 @@ public function setUp(): void [ ['hello@world.com', 100], ['another@world.com', 200], - ] + ], ); $this->getDatabase()->table('tag')->insertMultiple( @@ -69,7 +184,7 @@ public function setUp(): void ['tag a'], ['tag b'], ['tag c'], - ] + ], ); $this->getDatabase()->table('tag_user_map')->insertMultiple( @@ -78,7 +193,7 @@ public function setUp(): void [1, 1, 'primary'], [1, 2, 'secondary'], [2, 3, 'primary'], - ] + ], ); $this->getDatabase()->table('images')->insertMultiple( @@ -86,7 +201,7 @@ public function setUp(): void [ [1, 'first.jpg'], [3, 'second.png'], - ] + ], ); $this->orm = $this->withSchema(new Schema([ @@ -159,119 +274,4 @@ public function setUp(): void ], ])); } - - public function testLoadSortedByPivot(): void - { - $selector = new Select($this->orm, User::class); - $selector->load('tags', [ - 'load' => function (Select\QueryBuilder $q): void { - $q->orderBy('@.@.as', 'DESC'); - }, - ])->orderBy('id', 'ASC'); - - $this->assertSame([ - [ - 'id' => 1, - 'email' => 'hello@world.com', - 'balance' => 100.0, - 'tags' => [ - [ - 'id' => 2, - 'user_id' => 1, - 'tag_id' => 2, - 'as' => 'secondary', - '@' => [ - 'id' => 2, - 'name' => 'tag b', - ], - ], - [ - 'id' => 1, - 'user_id' => 1, - 'tag_id' => 1, - 'as' => 'primary', - '@' => [ - 'id' => 1, - 'name' => 'tag a', - ], - ], - ], - ], - [ - 'id' => 2, - 'email' => 'another@world.com', - 'balance' => 200.0, - 'tags' => [ - [ - 'id' => 3, - 'user_id' => 2, - 'tag_id' => 3, - 'as' => 'primary', - '@' => [ - 'id' => 3, - 'name' => 'tag c', - ], - ], - ], - ], - ], $selector->fetchData()); - } - - public function testLoadSortedByPivotInload(): void - { - $selector = new Select($this->orm, User::class); - $selector->load('tags', [ - 'method' => Select::SINGLE_QUERY, - 'load' => function (Select\QueryBuilder $q): void { - $q->orderBy('@.@.as', 'DESC'); - }, - ])->orderBy('id', 'ASC'); - - $this->assertSame([ - [ - 'id' => 1, - 'email' => 'hello@world.com', - 'balance' => 100.0, - 'tags' => [ - [ - 'id' => 2, - 'user_id' => 1, - 'tag_id' => 2, - 'as' => 'secondary', - '@' => [ - 'id' => 2, - 'name' => 'tag b', - ], - ], - [ - 'id' => 1, - 'user_id' => 1, - 'tag_id' => 1, - 'as' => 'primary', - '@' => [ - 'id' => 1, - 'name' => 'tag a', - ], - ], - ], - ], - [ - 'id' => 2, - 'email' => 'another@world.com', - 'balance' => 200.0, - 'tags' => [ - [ - 'id' => 3, - 'user_id' => 2, - 'tag_id' => 3, - 'as' => 'primary', - '@' => [ - 'id' => 3, - 'name' => 'tag c', - ], - ], - ], - ], - ], $selector->fetchData()); - } } diff --git a/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/ManyToManyLoophpPivotTest.php b/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/ManyToManyLoophpPivotTest.php index d60a6e78..a9fd6670 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/ManyToManyLoophpPivotTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/ManyToManyLoophpPivotTest.php @@ -23,6 +23,17 @@ abstract class ManyToManyLoophpPivotTest extends BaseTest { use TableTrait; + public function testPivotedCollection(): void + { + $data = (new Select($this->orm, User::class))->load('tags')->fetchAll(); + + $this->assertInstanceOf(LoophpPivotedCollection::class, $data[0]->tags); + $this->assertInstanceOf(LoophpPivotedCollection::class, $data[1]->tags); + + $this->assertSame(4, $data[0]->tags->count()); + $this->assertSame(3, $data[1]->tags->count()); + } + public function setUp(): void { parent::setUp(); @@ -55,7 +66,7 @@ public function setUp(): void [ ['hello@world.com', 100], ['another@world.com', 200], - ] + ], ); $this->getDatabase()->table('tag')->insertMultiple( @@ -67,7 +78,7 @@ public function setUp(): void ['tag d', 4], ['tag e', 5], ['tag f', 6], - ] + ], ); $this->getDatabase()->table('tag_user_map')->insertMultiple( @@ -82,7 +93,7 @@ public function setUp(): void [2, 4, 2], [2, 6, 3], - ] + ], ); $this->orm = new ORM( @@ -134,18 +145,7 @@ public function setUp(): void Schema::SCHEMA => [], Schema::RELATIONS => [], ], - ]) + ]), ); } - - public function testPivotedCollection(): void - { - $data = (new Select($this->orm, User::class))->load('tags')->fetchAll(); - - $this->assertInstanceOf(LoophpPivotedCollection::class, $data[0]->tags); - $this->assertInstanceOf(LoophpPivotedCollection::class, $data[1]->tags); - - $this->assertSame(4, $data[0]->tags->count()); - $this->assertSame(3, $data[1]->tags->count()); - } } diff --git a/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/ManyToManyNonPivotedCollectionTest.php b/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/ManyToManyNonPivotedCollectionTest.php index 79103f41..b6b595f1 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/ManyToManyNonPivotedCollectionTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/ManyToManyNonPivotedCollectionTest.php @@ -23,62 +23,6 @@ abstract class ManyToManyNonPivotedCollectionTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('user', [ - 'id' => 'primary', - 'email' => 'string', - 'balance' => 'float', - ]); - - $this->makeTable('tag', [ - 'id' => 'primary', - 'name' => 'string', - ]); - - $this->makeTable('tag_user_map', [ - 'id' => 'primary', - 'user_id' => 'integer', - 'tag_id' => 'integer', - 'as' => 'string,nullable', - ]); - - $this->makeFK('tag_user_map', 'user_id', 'user', 'id'); - $this->makeFK('tag_user_map', 'tag_id', 'tag', 'id'); - $this->makeIndex('tag_user_map', ['user_id', 'tag_id'], true); - - $this->getDatabase()->table('user')->insertMultiple( - ['email', 'balance'], - [ - ['hello@world.com', 100], - ['another@world.com', 200], - ] - ); - - $this->getDatabase()->table('tag')->insertMultiple( - ['name'], - [ - ['tag a'], - ['tag b'], - ['tag c'], - ] - ); - - $this->getDatabase()->table('tag_user_map')->insertMultiple( - ['user_id', 'tag_id', 'as'], - [ - [1, 1, 'primary'], - [1, 2, 'secondary'], - [2, 3, 'primary'], - ] - ); - - $this->orm = $this->createOrm() - ->withSchema(new Schema($this->getSchemaArray())); - } - public function testInitRelation(): void { $u = $this->orm->make(User::class); @@ -359,6 +303,62 @@ public function testReassign(): void $this->assertSame('tag c', $user->tags[1]->name); } + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('user', [ + 'id' => 'primary', + 'email' => 'string', + 'balance' => 'float', + ]); + + $this->makeTable('tag', [ + 'id' => 'primary', + 'name' => 'string', + ]); + + $this->makeTable('tag_user_map', [ + 'id' => 'primary', + 'user_id' => 'integer', + 'tag_id' => 'integer', + 'as' => 'string,nullable', + ]); + + $this->makeFK('tag_user_map', 'user_id', 'user', 'id'); + $this->makeFK('tag_user_map', 'tag_id', 'tag', 'id'); + $this->makeIndex('tag_user_map', ['user_id', 'tag_id'], true); + + $this->getDatabase()->table('user')->insertMultiple( + ['email', 'balance'], + [ + ['hello@world.com', 100], + ['another@world.com', 200], + ], + ); + + $this->getDatabase()->table('tag')->insertMultiple( + ['name'], + [ + ['tag a'], + ['tag b'], + ['tag c'], + ], + ); + + $this->getDatabase()->table('tag_user_map')->insertMultiple( + ['user_id', 'tag_id', 'as'], + [ + [1, 1, 'primary'], + [1, 2, 'secondary'], + [2, 3, 'primary'], + ], + ); + + $this->orm = $this->createOrm() + ->withSchema(new Schema($this->getSchemaArray())); + } + private function createOrm(): ORMInterface { return new ORM( @@ -366,9 +366,9 @@ private function createOrm(): ORMInterface $this->dbal, RelationConfig::getDefault(), null, - new \Cycle\ORM\Collection\ArrayCollectionFactory() + new \Cycle\ORM\Collection\ArrayCollectionFactory(), ), - new Schema([]) + new Schema([]), ); } diff --git a/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/ManyToManyPromiseEagerLoadTest.php b/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/ManyToManyPromiseEagerLoadTest.php index b817bd1e..d00fc3ec 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/ManyToManyPromiseEagerLoadTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/ManyToManyPromiseEagerLoadTest.php @@ -16,153 +16,6 @@ abstract class ManyToManyPromiseEagerLoadTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('distributions', [ - 'id' => 'primary', - 'name' => 'string', - ]); - - $this->makeTable('version_distribution', [ - 'id' => 'primary', - 'dist_id' => 'int', - 'version_id' => 'int', - ]); - - $this->makeTable('versions', [ - 'id' => 'primary', - 'version' => 'string', - 'module_id' => 'int', - ]); - - $this->makeTable('modules', [ - 'id' => 'primary', - 'name' => 'string', - ]); - - $this->makeFK('version_distribution', 'dist_id', 'distributions', 'id'); - $this->makeFK('version_distribution', 'version_id', 'versions', 'id'); - $this->makeFK('versions', 'module_id', 'modules', 'id'); - - - $this->getDatabase()->table('distributions')->insertMultiple( - ['name'], - [ - ['production'], // 1 - ['staging'], // 2 - ] - ); - - $this->getDatabase()->table('modules')->insertMultiple( - ['name'], - [ - ['Module A'], // 1 - ['Module B'], // 2 - ['Module C'], // 3 - ] - ); - - $this->getDatabase()->table('versions')->insertMultiple( - ['module_id', 'version'], - [ - [1, 'v1.0'], // 1 - [1, 'v2.0'], // 2 - [2, 'v1.0'], // 3 - [3, 'v1.0'], // 4 - [3, 'v2.0'], // 5 - ] - ); - - $this->getDatabase()->table('version_distribution')->insertMultiple( - ['dist_id', 'version_id'], - [ - [1, 1], - [1, 3], - [1, 4], - [2, 2], - [2, 3], - [2, 5], - ] - ); - - $this->orm = $this->withSchema(new Schema([ - 'distribution' => [ - Schema::ROLE => 'distribution', - Schema::MAPPER => StdMapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'distributions', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'name'], - Schema::TYPECAST => ['id' => 'int'], - Schema::SCHEMA => [], - Schema::RELATIONS => [ - 'versions' => [ - Relation::TYPE => Relation::MANY_TO_MANY, - Relation::TARGET => 'version', - Relation::LOAD => Relation::LOAD_PROMISE, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::THROUGH_ENTITY => 'version_distribution', - Relation::INNER_KEY => 'id', - Relation::OUTER_KEY => 'id', - Relation::THROUGH_INNER_KEY => 'dist_id', - Relation::THROUGH_OUTER_KEY => 'version_id', - ], - ], - ], - Schema::SCOPE => SortByIDScope::class, - ], - 'version_distribution' => [ - Schema::ROLE => 'version_context', - Schema::MAPPER => StdMapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'version_distribution', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'dist_id', 'version_id'], - Schema::TYPECAST => ['id' => 'int', 'dist_id' => 'int', 'version_id' => 'int'], - Schema::SCHEMA => [], - Schema::RELATIONS => [], - ], - 'version' => [ - Schema::ROLE => 'tag', - Schema::MAPPER => StdMapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'versions', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'version', 'module_id'], - Schema::TYPECAST => ['id' => 'int', 'module_id' => 'int'], - Schema::SCHEMA => [], - Schema::RELATIONS => [ - 'module' => [ - Relation::TYPE => Relation::BELONGS_TO, - Relation::TARGET => 'module', - Relation::LOAD => Relation::LOAD_EAGER, - Relation::SCHEMA => [ - Relation::CASCADE => false, - Relation::INNER_KEY => 'module_id', - Relation::OUTER_KEY => 'id', - ], - ], - ], - Schema::SCOPE => SortByIDScope::class, - ], - 'module' => [ - Schema::ROLE => 'module', - Schema::MAPPER => StdMapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'modules', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'name'], - Schema::TYPECAST => ['id' => 'int'], - Schema::SCHEMA => [], - Schema::RELATIONS => [], - Schema::SCOPE => SortByIDScope::class, - ], - ])); - } - public function testFetchData(): void { $selector = new Select($this->orm, 'distribution'); @@ -399,4 +252,151 @@ public function testLoadPromised(): void $this->assertNotNull($version->module); } } + + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('distributions', [ + 'id' => 'primary', + 'name' => 'string', + ]); + + $this->makeTable('version_distribution', [ + 'id' => 'primary', + 'dist_id' => 'int', + 'version_id' => 'int', + ]); + + $this->makeTable('versions', [ + 'id' => 'primary', + 'version' => 'string', + 'module_id' => 'int', + ]); + + $this->makeTable('modules', [ + 'id' => 'primary', + 'name' => 'string', + ]); + + $this->makeFK('version_distribution', 'dist_id', 'distributions', 'id'); + $this->makeFK('version_distribution', 'version_id', 'versions', 'id'); + $this->makeFK('versions', 'module_id', 'modules', 'id'); + + + $this->getDatabase()->table('distributions')->insertMultiple( + ['name'], + [ + ['production'], // 1 + ['staging'], // 2 + ], + ); + + $this->getDatabase()->table('modules')->insertMultiple( + ['name'], + [ + ['Module A'], // 1 + ['Module B'], // 2 + ['Module C'], // 3 + ], + ); + + $this->getDatabase()->table('versions')->insertMultiple( + ['module_id', 'version'], + [ + [1, 'v1.0'], // 1 + [1, 'v2.0'], // 2 + [2, 'v1.0'], // 3 + [3, 'v1.0'], // 4 + [3, 'v2.0'], // 5 + ], + ); + + $this->getDatabase()->table('version_distribution')->insertMultiple( + ['dist_id', 'version_id'], + [ + [1, 1], + [1, 3], + [1, 4], + [2, 2], + [2, 3], + [2, 5], + ], + ); + + $this->orm = $this->withSchema(new Schema([ + 'distribution' => [ + Schema::ROLE => 'distribution', + Schema::MAPPER => StdMapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'distributions', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'name'], + Schema::TYPECAST => ['id' => 'int'], + Schema::SCHEMA => [], + Schema::RELATIONS => [ + 'versions' => [ + Relation::TYPE => Relation::MANY_TO_MANY, + Relation::TARGET => 'version', + Relation::LOAD => Relation::LOAD_PROMISE, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::THROUGH_ENTITY => 'version_distribution', + Relation::INNER_KEY => 'id', + Relation::OUTER_KEY => 'id', + Relation::THROUGH_INNER_KEY => 'dist_id', + Relation::THROUGH_OUTER_KEY => 'version_id', + ], + ], + ], + Schema::SCOPE => SortByIDScope::class, + ], + 'version_distribution' => [ + Schema::ROLE => 'version_context', + Schema::MAPPER => StdMapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'version_distribution', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'dist_id', 'version_id'], + Schema::TYPECAST => ['id' => 'int', 'dist_id' => 'int', 'version_id' => 'int'], + Schema::SCHEMA => [], + Schema::RELATIONS => [], + ], + 'version' => [ + Schema::ROLE => 'tag', + Schema::MAPPER => StdMapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'versions', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'version', 'module_id'], + Schema::TYPECAST => ['id' => 'int', 'module_id' => 'int'], + Schema::SCHEMA => [], + Schema::RELATIONS => [ + 'module' => [ + Relation::TYPE => Relation::BELONGS_TO, + Relation::TARGET => 'module', + Relation::LOAD => Relation::LOAD_EAGER, + Relation::SCHEMA => [ + Relation::CASCADE => false, + Relation::INNER_KEY => 'module_id', + Relation::OUTER_KEY => 'id', + ], + ], + ], + Schema::SCOPE => SortByIDScope::class, + ], + 'module' => [ + Schema::ROLE => 'module', + Schema::MAPPER => StdMapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'modules', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'name'], + Schema::TYPECAST => ['id' => 'int'], + Schema::SCHEMA => [], + Schema::RELATIONS => [], + Schema::SCOPE => SortByIDScope::class, + ], + ])); + } } diff --git a/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/ManyToManyPromiseTest.php b/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/ManyToManyPromiseTest.php index 54b98898..695dde6f 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/ManyToManyPromiseTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/ManyToManyPromiseTest.php @@ -23,110 +23,6 @@ abstract class ManyToManyPromiseTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('user', [ - 'id' => 'primary', - 'email' => 'string', - 'balance' => 'float', - ]); - - $this->makeTable('tags', [ - 'id' => 'primary', - 'name' => 'string', - ]); - - $this->makeTable('tag_user_map', [ - 'id' => 'primary', - 'user_id' => 'integer', - 'tag_id' => 'integer', - 'as' => 'string,nullable', - ]); - - $this->makeFK('tag_user_map', 'user_id', 'user', 'id'); - $this->makeFK('tag_user_map', 'tag_id', 'tags', 'id'); - $this->makeIndex('tag_user_map', ['user_id', 'tag_id'], true); - - $this->getDatabase()->table('user')->insertMultiple( - ['email', 'balance'], - [ - ['hello@world.com', 100], - ['another@world.com', 200], - ] - ); - - $this->getDatabase()->table('tags')->insertMultiple( - ['name'], - [ - ['tag a'], - ['tag b'], - ['tag c'], - ] - ); - - $this->getDatabase()->table('tag_user_map')->insertMultiple( - ['user_id', 'tag_id', 'as'], - [ - [1, 1, 'primary'], - [1, 2, 'secondary'], - [2, 3, 'primary'], - ] - ); - - $this->orm = $this->withSchema(new Schema([ - User::class => [ - Schema::ROLE => 'user', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'user', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'email', 'balance'], - Schema::TYPECAST => ['id' => 'int', 'balance' => 'float'], - Schema::SCHEMA => [], - Schema::RELATIONS => [ - 'tags' => [ - Relation::TYPE => Relation::MANY_TO_MANY, - Relation::TARGET => Tag::class, - Relation::LOAD => Relation::LOAD_PROMISE, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::THROUGH_ENTITY => TagContext::class, - Relation::INNER_KEY => 'id', - Relation::OUTER_KEY => 'id', - Relation::THROUGH_INNER_KEY => 'user_id', - Relation::THROUGH_OUTER_KEY => 'tag_id', - ], - ], - ], - ], - Tag::class => [ - Schema::ROLE => 'tag', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'tags', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'name'], - Schema::TYPECAST => ['id' => 'int'], - Schema::SCHEMA => [], - Schema::RELATIONS => [], - Schema::SCOPE => SortByIDScope::class, - ], - TagContext::class => [ - Schema::ROLE => 'tag_context', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'tag_user_map', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'user_id', 'tag_id', 'as'], - Schema::TYPECAST => ['id' => 'int', 'user_id' => 'int', 'tag_id' => 'int'], - Schema::SCHEMA => [], - Schema::RELATIONS => [], - ], - ])); - } - public function testLoadRelation(): void { $selector = new Select($this->orm, User::class); @@ -342,4 +238,108 @@ public function testResolvePromise(): void $this->assertInstanceOf(ReferenceInterface::class, $uData['tags']); $this->assertCount(2, $u->tags); } + + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('user', [ + 'id' => 'primary', + 'email' => 'string', + 'balance' => 'float', + ]); + + $this->makeTable('tags', [ + 'id' => 'primary', + 'name' => 'string', + ]); + + $this->makeTable('tag_user_map', [ + 'id' => 'primary', + 'user_id' => 'integer', + 'tag_id' => 'integer', + 'as' => 'string,nullable', + ]); + + $this->makeFK('tag_user_map', 'user_id', 'user', 'id'); + $this->makeFK('tag_user_map', 'tag_id', 'tags', 'id'); + $this->makeIndex('tag_user_map', ['user_id', 'tag_id'], true); + + $this->getDatabase()->table('user')->insertMultiple( + ['email', 'balance'], + [ + ['hello@world.com', 100], + ['another@world.com', 200], + ], + ); + + $this->getDatabase()->table('tags')->insertMultiple( + ['name'], + [ + ['tag a'], + ['tag b'], + ['tag c'], + ], + ); + + $this->getDatabase()->table('tag_user_map')->insertMultiple( + ['user_id', 'tag_id', 'as'], + [ + [1, 1, 'primary'], + [1, 2, 'secondary'], + [2, 3, 'primary'], + ], + ); + + $this->orm = $this->withSchema(new Schema([ + User::class => [ + Schema::ROLE => 'user', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'user', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'email', 'balance'], + Schema::TYPECAST => ['id' => 'int', 'balance' => 'float'], + Schema::SCHEMA => [], + Schema::RELATIONS => [ + 'tags' => [ + Relation::TYPE => Relation::MANY_TO_MANY, + Relation::TARGET => Tag::class, + Relation::LOAD => Relation::LOAD_PROMISE, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::THROUGH_ENTITY => TagContext::class, + Relation::INNER_KEY => 'id', + Relation::OUTER_KEY => 'id', + Relation::THROUGH_INNER_KEY => 'user_id', + Relation::THROUGH_OUTER_KEY => 'tag_id', + ], + ], + ], + ], + Tag::class => [ + Schema::ROLE => 'tag', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'tags', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'name'], + Schema::TYPECAST => ['id' => 'int'], + Schema::SCHEMA => [], + Schema::RELATIONS => [], + Schema::SCOPE => SortByIDScope::class, + ], + TagContext::class => [ + Schema::ROLE => 'tag_context', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'tag_user_map', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'user_id', 'tag_id', 'as'], + Schema::TYPECAST => ['id' => 'int', 'user_id' => 'int', 'tag_id' => 'int'], + Schema::SCHEMA => [], + Schema::RELATIONS => [], + ], + ])); + } } diff --git a/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/ManyToManyRelationTest.php b/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/ManyToManyRelationTest.php index 14f8b370..7966c666 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/ManyToManyRelationTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/ManyToManyRelationTest.php @@ -21,61 +21,6 @@ abstract class ManyToManyRelationTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('user', [ - 'id' => 'primary', - 'email' => 'string', - 'balance' => 'float', - ]); - - $this->makeTable('tag', [ - 'id' => 'primary', - 'name' => 'string', - ]); - - $this->makeTable('tag_user_map', [ - 'id' => 'primary', - 'user_id' => 'integer', - 'tag_id' => 'integer', - 'as' => 'string,nullable', - ]); - - $this->makeFK('tag_user_map', 'user_id', 'user', 'id'); - $this->makeFK('tag_user_map', 'tag_id', 'tag', 'id'); - $this->makeIndex('tag_user_map', ['user_id', 'tag_id'], true); - - $this->getDatabase()->table('user')->insertMultiple( - ['email', 'balance'], - [ - ['hello@world.com', 100], - ['another@world.com', 200], - ] - ); - - $this->getDatabase()->table('tag')->insertMultiple( - ['name'], - [ - ['tag a'], - ['tag b'], - ['tag c'], - ] - ); - - $this->getDatabase()->table('tag_user_map')->insertMultiple( - ['user_id', 'tag_id', 'as'], - [ - [1, 1, 'primary'], - [1, 2, 'secondary'], - [2, 3, 'primary'], - ] - ); - - $this->orm = $this->withSchema(new Schema($this->getSchemaArray())); - } - public function testInitRelation(): void { $u = $this->orm->make(User::class); @@ -273,7 +218,7 @@ public function testCreateWithManyToMany2(): void [ $t1, $t2, - ] + ], ); $this->save($u); @@ -555,6 +500,61 @@ public function testRemoveRelatedUsingUnset(): void $this->assertCount(0, $user->tags); } + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('user', [ + 'id' => 'primary', + 'email' => 'string', + 'balance' => 'float', + ]); + + $this->makeTable('tag', [ + 'id' => 'primary', + 'name' => 'string', + ]); + + $this->makeTable('tag_user_map', [ + 'id' => 'primary', + 'user_id' => 'integer', + 'tag_id' => 'integer', + 'as' => 'string,nullable', + ]); + + $this->makeFK('tag_user_map', 'user_id', 'user', 'id'); + $this->makeFK('tag_user_map', 'tag_id', 'tag', 'id'); + $this->makeIndex('tag_user_map', ['user_id', 'tag_id'], true); + + $this->getDatabase()->table('user')->insertMultiple( + ['email', 'balance'], + [ + ['hello@world.com', 100], + ['another@world.com', 200], + ], + ); + + $this->getDatabase()->table('tag')->insertMultiple( + ['name'], + [ + ['tag a'], + ['tag b'], + ['tag c'], + ], + ); + + $this->getDatabase()->table('tag_user_map')->insertMultiple( + ['user_id', 'tag_id', 'as'], + [ + [1, 1, 'primary'], + [1, 2, 'secondary'], + [2, 3, 'primary'], + ], + ); + + $this->orm = $this->withSchema(new Schema($this->getSchemaArray())); + } + private function getSchemaArray(): array { return [ diff --git a/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/ManyToManyScopeTest.php b/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/ManyToManyScopeTest.php index 6e6c94d0..c59e374a 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/ManyToManyScopeTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/ManyToManyScopeTest.php @@ -20,68 +20,6 @@ abstract class ManyToManyScopeTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('user', [ - 'id' => 'primary', - 'email' => 'string', - 'balance' => 'float', - ]); - - $this->makeTable('tag', [ - 'id' => 'primary', - 'level' => 'integer', - 'name' => 'string', - ]); - - $this->makeTable('tag_user_map', [ - 'id' => 'primary', - 'user_id' => 'integer', - 'tag_id' => 'integer', - 'as' => 'string,nullable', - ]); - - $this->makeFK('tag_user_map', 'user_id', 'user', 'id'); - $this->makeFK('tag_user_map', 'tag_id', 'tag', 'id'); - - $this->getDatabase()->table('user')->insertMultiple( - ['email', 'balance'], - [ - ['hello@world.com', 100], - ['another@world.com', 200], - ] - ); - - $this->getDatabase()->table('tag')->insertMultiple( - ['name', 'level'], - [ - ['tag a', 1], - ['tag b', 2], - ['tag c', 3], - ['tag d', 4], - ['tag e', 5], - ['tag f', 6], - ] - ); - - $this->getDatabase()->table('tag_user_map')->insertMultiple( - ['user_id', 'tag_id'], - [ - [1, 1], - [1, 2], - [2, 3], - - [1, 4], - [1, 5], - - [2, 4], - [2, 6], - ] - ); - } - public function testScopeOrdered(): void { $this->orm = $this->withTagSchema([ @@ -762,6 +700,68 @@ public function testInvalidOrderBy(): void $res = $selector->with('tags')->orderBy('user.id')->fetchAll(); } + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('user', [ + 'id' => 'primary', + 'email' => 'string', + 'balance' => 'float', + ]); + + $this->makeTable('tag', [ + 'id' => 'primary', + 'level' => 'integer', + 'name' => 'string', + ]); + + $this->makeTable('tag_user_map', [ + 'id' => 'primary', + 'user_id' => 'integer', + 'tag_id' => 'integer', + 'as' => 'string,nullable', + ]); + + $this->makeFK('tag_user_map', 'user_id', 'user', 'id'); + $this->makeFK('tag_user_map', 'tag_id', 'tag', 'id'); + + $this->getDatabase()->table('user')->insertMultiple( + ['email', 'balance'], + [ + ['hello@world.com', 100], + ['another@world.com', 200], + ], + ); + + $this->getDatabase()->table('tag')->insertMultiple( + ['name', 'level'], + [ + ['tag a', 1], + ['tag b', 2], + ['tag c', 3], + ['tag d', 4], + ['tag e', 5], + ['tag f', 6], + ], + ); + + $this->getDatabase()->table('tag_user_map')->insertMultiple( + ['user_id', 'tag_id'], + [ + [1, 1], + [1, 2], + [2, 3], + + [1, 4], + [1, 5], + + [2, 4], + [2, 6], + ], + ); + } + protected function withTagSchema(array $relationSchema) { $eSchema = []; diff --git a/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/ManyToManyScopedPivotTest.php b/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/ManyToManyScopedPivotTest.php index f20e7748..8561da50 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/ManyToManyScopedPivotTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/ManyToManyScopedPivotTest.php @@ -19,69 +19,6 @@ abstract class ManyToManyScopedPivotTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('user', [ - 'id' => 'primary', - 'email' => 'string', - 'balance' => 'float', - ]); - - $this->makeTable('tag', [ - 'id' => 'primary', - 'level' => 'integer', - 'name' => 'string', - ]); - - $this->makeTable('tag_user_map', [ - 'id' => 'primary', - 'user_id' => 'integer', - 'tag_id' => 'integer', - 'as' => 'string,nullable', - 'level' => 'int', - ]); - - $this->makeFK('tag_user_map', 'user_id', 'user', 'id'); - $this->makeFK('tag_user_map', 'tag_id', 'tag', 'id'); - - $this->getDatabase()->table('user')->insertMultiple( - ['email', 'balance'], - [ - ['hello@world.com', 100], - ['another@world.com', 200], - ] - ); - - $this->getDatabase()->table('tag')->insertMultiple( - ['name', 'level'], - [ - ['tag a', 1], - ['tag b', 2], - ['tag c', 3], - ['tag d', 4], - ['tag e', 5], - ['tag f', 6], - ] - ); - - $this->getDatabase()->table('tag_user_map')->insertMultiple( - ['user_id', 'tag_id', 'level'], - [ - [1, 1, 1], - [1, 2, 2], - [2, 3, 1], - - [1, 4, 3], - [1, 5, 4], - - [2, 4, 2], - [2, 6, 3], - ] - ); - } - public function testLoadRelation(): void { $this->orm = $this->withPivotSchema([ @@ -89,8 +26,8 @@ public function testLoadRelation(): void $selector = new Select($this->orm, User::class); $selector->load('tags') - ->orderBy('id') - ->orderBy('tags.id'); + ->orderBy('id') + ->orderBy('tags.id'); $this->assertSame([ [ @@ -313,7 +250,7 @@ public function testLoaderRelationWithScope(): void $this->orm = $this->withPivotSchema([ Schema::SCOPE => new Select\QueryScope( ['@.level' => ['>' => 3]], - ['@.level' => 'DESC'] + ['@.level' => 'DESC'], ), ]); @@ -346,6 +283,69 @@ public function testLoaderRelationWithScope(): void ], $selector->fetchData()); } + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('user', [ + 'id' => 'primary', + 'email' => 'string', + 'balance' => 'float', + ]); + + $this->makeTable('tag', [ + 'id' => 'primary', + 'level' => 'integer', + 'name' => 'string', + ]); + + $this->makeTable('tag_user_map', [ + 'id' => 'primary', + 'user_id' => 'integer', + 'tag_id' => 'integer', + 'as' => 'string,nullable', + 'level' => 'int', + ]); + + $this->makeFK('tag_user_map', 'user_id', 'user', 'id'); + $this->makeFK('tag_user_map', 'tag_id', 'tag', 'id'); + + $this->getDatabase()->table('user')->insertMultiple( + ['email', 'balance'], + [ + ['hello@world.com', 100], + ['another@world.com', 200], + ], + ); + + $this->getDatabase()->table('tag')->insertMultiple( + ['name', 'level'], + [ + ['tag a', 1], + ['tag b', 2], + ['tag c', 3], + ['tag d', 4], + ['tag e', 5], + ['tag f', 6], + ], + ); + + $this->getDatabase()->table('tag_user_map')->insertMultiple( + ['user_id', 'tag_id', 'level'], + [ + [1, 1, 1], + [1, 2, 2], + [2, 3, 1], + + [1, 4, 3], + [1, 5, 4], + + [2, 4, 2], + [2, 6, 3], + ], + ); + } + protected function withPivotSchema(array $pivotSchema, array $relSchema = []) { return $this->withSchema(new Schema([ diff --git a/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/ManyToManyScopedTest.php b/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/ManyToManyScopedTest.php index fe872e7f..609ba39e 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/ManyToManyScopedTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/ManyToMany/ManyToManyScopedTest.php @@ -20,68 +20,6 @@ abstract class ManyToManyScopedTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('user', [ - 'id' => 'primary', - 'email' => 'string', - 'balance' => 'float', - ]); - - $this->makeTable('tag', [ - 'id' => 'primary', - 'level' => 'integer', - 'name' => 'string', - ]); - - $this->makeTable('tag_user_map', [ - 'id' => 'primary', - 'user_id' => 'integer', - 'tag_id' => 'integer', - 'as' => 'string,nullable', - ]); - - $this->makeFK('tag_user_map', 'user_id', 'user', 'id'); - $this->makeFK('tag_user_map', 'tag_id', 'tag', 'id'); - - $this->getDatabase()->table('user')->insertMultiple( - ['email', 'balance'], - [ - ['hello@world.com', 100], - ['another@world.com', 200], - ] - ); - - $this->getDatabase()->table('tag')->insertMultiple( - ['name', 'level'], - [ - ['tag a', 1], - ['tag b', 2], - ['tag c', 3], - ['tag d', 4], - ['tag e', 5], - ['tag f', 6], - ] - ); - - $this->getDatabase()->table('tag_user_map')->insertMultiple( - ['user_id', 'tag_id'], - [ - [1, 1], - [1, 2], - [2, 3], - - [1, 4], - [1, 5], - - [2, 4], - [2, 6], - ] - ); - } - public function testOrderedByScope(): void { $this->orm = $this->withTagSchema([ @@ -561,6 +499,68 @@ public function testGlobalScopeDESCPromised(): void $this->assertSame('tag f', $b->tags[0]->name); } + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('user', [ + 'id' => 'primary', + 'email' => 'string', + 'balance' => 'float', + ]); + + $this->makeTable('tag', [ + 'id' => 'primary', + 'level' => 'integer', + 'name' => 'string', + ]); + + $this->makeTable('tag_user_map', [ + 'id' => 'primary', + 'user_id' => 'integer', + 'tag_id' => 'integer', + 'as' => 'string,nullable', + ]); + + $this->makeFK('tag_user_map', 'user_id', 'user', 'id'); + $this->makeFK('tag_user_map', 'tag_id', 'tag', 'id'); + + $this->getDatabase()->table('user')->insertMultiple( + ['email', 'balance'], + [ + ['hello@world.com', 100], + ['another@world.com', 200], + ], + ); + + $this->getDatabase()->table('tag')->insertMultiple( + ['name', 'level'], + [ + ['tag a', 1], + ['tag b', 2], + ['tag c', 3], + ['tag d', 4], + ['tag e', 5], + ['tag f', 6], + ], + ); + + $this->getDatabase()->table('tag_user_map')->insertMultiple( + ['user_id', 'tag_id'], + [ + [1, 1], + [1, 2], + [2, 3], + + [1, 4], + [1, 5], + + [2, 4], + [2, 6], + ], + ); + } + protected function withTagSchema(array $tagSchema) { return $this->withSchema(new Schema([ diff --git a/tests/ORM/Functional/Driver/Common/Relation/Morphed/BelongsToMorphedRelationTest.php b/tests/ORM/Functional/Driver/Common/Relation/Morphed/BelongsToMorphedRelationTest.php index d062899b..5de855c3 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/Morphed/BelongsToMorphedRelationTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/Morphed/BelongsToMorphedRelationTest.php @@ -23,62 +23,6 @@ abstract class BelongsToMorphedRelationTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('user', [ - 'id' => 'primary', - 'email' => 'string', - 'balance' => 'float', - ]); - - $this->getDatabase()->table('user')->insertMultiple( - ['email', 'balance'], - [ - ['hello@world.com', 100], - ['another@world.com', 200], - ] - ); - - $this->makeTable('post', [ - 'id' => 'primary', - 'user_id' => 'integer,nullable', - 'title' => 'string', - 'content' => 'string', - ]); - - $this->getDatabase()->table('post')->insertMultiple( - ['title', 'user_id', 'content'], - [ - ['post 1', 1, 'post 1 body'], - ['post 2', 1, 'post 2 body'], - ['post 3', 2, 'post 3 body'], - ['post 4', 2, 'post 4 body'], - ] - ); - - $this->makeTable('image', [ - 'id' => 'primary', - 'parent_id' => 'integer,nullable', - 'parent_type' => 'string,nullable', - 'url' => 'string', - ]); - - $this->getDatabase()->table('image')->insertMultiple( - ['parent_id', 'parent_type', 'url'], - [ - [1, 'user', 'user-image.png'], - [1, 'post', 'post-image.png'], - [2, 'user', 'user-2-image.png'], - [2, 'post', 'post-2-image.png'], - [3, 'post', 'post-3-image.png'], - ] - ); - - $this->orm = $this->withSchema(new Schema($this->getSchemaArray())); - } - public function testGetParent(): void { $c = $this->orm->getRepository(Image::class)->findByPK(1); @@ -329,6 +273,62 @@ public function testSetNull(): void $this->assertNull($c->parent); } + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('user', [ + 'id' => 'primary', + 'email' => 'string', + 'balance' => 'float', + ]); + + $this->getDatabase()->table('user')->insertMultiple( + ['email', 'balance'], + [ + ['hello@world.com', 100], + ['another@world.com', 200], + ], + ); + + $this->makeTable('post', [ + 'id' => 'primary', + 'user_id' => 'integer,nullable', + 'title' => 'string', + 'content' => 'string', + ]); + + $this->getDatabase()->table('post')->insertMultiple( + ['title', 'user_id', 'content'], + [ + ['post 1', 1, 'post 1 body'], + ['post 2', 1, 'post 2 body'], + ['post 3', 2, 'post 3 body'], + ['post 4', 2, 'post 4 body'], + ], + ); + + $this->makeTable('image', [ + 'id' => 'primary', + 'parent_id' => 'integer,nullable', + 'parent_type' => 'string,nullable', + 'url' => 'string', + ]); + + $this->getDatabase()->table('image')->insertMultiple( + ['parent_id', 'parent_type', 'url'], + [ + [1, 'user', 'user-image.png'], + [1, 'post', 'post-image.png'], + [2, 'user', 'user-2-image.png'], + [2, 'post', 'post-2-image.png'], + [3, 'post', 'post-3-image.png'], + ], + ); + + $this->orm = $this->withSchema(new Schema($this->getSchemaArray())); + } + private function getNullableMorphedSchemaArray(): array { $schemaArray = $this->getSchemaArray(); diff --git a/tests/ORM/Functional/Driver/Common/Relation/Morphed/MorphedHasManyPromiseTest.php b/tests/ORM/Functional/Driver/Common/Relation/Morphed/MorphedHasManyPromiseTest.php index 54bb912c..5400d29f 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/Morphed/MorphedHasManyPromiseTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/Morphed/MorphedHasManyPromiseTest.php @@ -21,129 +21,6 @@ abstract class MorphedHasManyPromiseTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('user', [ - 'id' => 'primary', - 'email' => 'string', - 'balance' => 'float', - ]); - - $this->getDatabase()->table('user')->insertMultiple( - ['email', 'balance'], - [ - ['hello@world.com', 100], - ['another@world.com', 200], - ] - ); - - $this->makeTable('post', [ - 'id' => 'primary', - 'user_id' => 'integer,nullable', - 'title' => 'string', - 'content' => 'string', - ]); - - $this->getDatabase()->table('post')->insertMultiple( - ['title', 'user_id', 'content'], - [ - ['post 1', 1, 'post 1 body'], - ['post 2', 1, 'post 2 body'], - ['post 3', 2, 'post 3 body'], - ['post 4', 2, 'post 4 body'], - ] - ); - - $this->makeTable('comment', [ - 'id' => 'primary', - 'parent_id' => 'integer', - 'parent_type' => 'string', - 'message' => 'string', - ]); - - $this->getDatabase()->table('comment')->insertMultiple( - ['parent_id', 'parent_type', 'message'], - [ - [1, 'user', 'first comment'], - [1, 'user', 'second comment'], - [1, 'user', 'third comment'], - - [1, 'post', 'post 1 comment'], - [2, 'post', 'post 2 comment'], - [1, 'post', 'post 1.1 comment'], - [2, 'post', 'post 2.1 comment'], - ] - ); - - $this->orm = $this->withSchema(new Schema([ - User::class => [ - Schema::ROLE => 'user', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'user', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'email', 'balance'], - Schema::SCHEMA => [], - Schema::RELATIONS => [ - 'comments' => [ - Relation::TYPE => Relation::MORPHED_HAS_MANY, - Relation::TARGET => Comment::class, - Relation::LOAD => Relation::LOAD_PROMISE, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::INNER_KEY => 'id', - Relation::OUTER_KEY => 'parent_id', - Relation::MORPH_KEY => 'parent_type', - ], - ], - 'posts' => [ - Relation::TYPE => Relation::HAS_MANY, - Relation::TARGET => Post::class, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::INNER_KEY => 'id', - Relation::OUTER_KEY => 'user_id', - ], - ], - ], - ], - Post::class => [ - Schema::ROLE => 'post', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'post', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'user_id', 'title', 'content'], - Schema::SCHEMA => [], - Schema::RELATIONS => [ - 'comments' => [ - Relation::TYPE => Relation::MORPHED_HAS_MANY, - Relation::TARGET => Comment::class, - Relation::LOAD => Relation::LOAD_PROMISE, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::INNER_KEY => 'id', - Relation::OUTER_KEY => 'parent_id', - Relation::MORPH_KEY => 'parent_type', - ], - ], - ], - ], - Comment::class => [ - Schema::ROLE => 'comment', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'comment', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'parent_id', 'parent_type', 'message'], - Schema::SCHEMA => [], - Schema::RELATIONS => [], - ], - ])); - } - public function testAccessEntity(): void { $selector = new Select($this->orm, User::class); @@ -305,4 +182,127 @@ public function testMoveToAnother(): void return $c->message == 'post 1.1 comment'; })); } + + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('user', [ + 'id' => 'primary', + 'email' => 'string', + 'balance' => 'float', + ]); + + $this->getDatabase()->table('user')->insertMultiple( + ['email', 'balance'], + [ + ['hello@world.com', 100], + ['another@world.com', 200], + ], + ); + + $this->makeTable('post', [ + 'id' => 'primary', + 'user_id' => 'integer,nullable', + 'title' => 'string', + 'content' => 'string', + ]); + + $this->getDatabase()->table('post')->insertMultiple( + ['title', 'user_id', 'content'], + [ + ['post 1', 1, 'post 1 body'], + ['post 2', 1, 'post 2 body'], + ['post 3', 2, 'post 3 body'], + ['post 4', 2, 'post 4 body'], + ], + ); + + $this->makeTable('comment', [ + 'id' => 'primary', + 'parent_id' => 'integer', + 'parent_type' => 'string', + 'message' => 'string', + ]); + + $this->getDatabase()->table('comment')->insertMultiple( + ['parent_id', 'parent_type', 'message'], + [ + [1, 'user', 'first comment'], + [1, 'user', 'second comment'], + [1, 'user', 'third comment'], + + [1, 'post', 'post 1 comment'], + [2, 'post', 'post 2 comment'], + [1, 'post', 'post 1.1 comment'], + [2, 'post', 'post 2.1 comment'], + ], + ); + + $this->orm = $this->withSchema(new Schema([ + User::class => [ + Schema::ROLE => 'user', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'user', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'email', 'balance'], + Schema::SCHEMA => [], + Schema::RELATIONS => [ + 'comments' => [ + Relation::TYPE => Relation::MORPHED_HAS_MANY, + Relation::TARGET => Comment::class, + Relation::LOAD => Relation::LOAD_PROMISE, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::INNER_KEY => 'id', + Relation::OUTER_KEY => 'parent_id', + Relation::MORPH_KEY => 'parent_type', + ], + ], + 'posts' => [ + Relation::TYPE => Relation::HAS_MANY, + Relation::TARGET => Post::class, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::INNER_KEY => 'id', + Relation::OUTER_KEY => 'user_id', + ], + ], + ], + ], + Post::class => [ + Schema::ROLE => 'post', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'post', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'user_id', 'title', 'content'], + Schema::SCHEMA => [], + Schema::RELATIONS => [ + 'comments' => [ + Relation::TYPE => Relation::MORPHED_HAS_MANY, + Relation::TARGET => Comment::class, + Relation::LOAD => Relation::LOAD_PROMISE, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::INNER_KEY => 'id', + Relation::OUTER_KEY => 'parent_id', + Relation::MORPH_KEY => 'parent_type', + ], + ], + ], + ], + Comment::class => [ + Schema::ROLE => 'comment', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'comment', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'parent_id', 'parent_type', 'message'], + Schema::SCHEMA => [], + Schema::RELATIONS => [], + ], + ])); + } } diff --git a/tests/ORM/Functional/Driver/Common/Relation/Morphed/MorphedHasManyRelationTest.php b/tests/ORM/Functional/Driver/Common/Relation/Morphed/MorphedHasManyRelationTest.php index 7bc56ee0..c9735ade 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/Morphed/MorphedHasManyRelationTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/Morphed/MorphedHasManyRelationTest.php @@ -21,127 +21,6 @@ abstract class MorphedHasManyRelationTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('user', [ - 'id' => 'primary', - 'email' => 'string', - 'balance' => 'float', - ]); - - $this->getDatabase()->table('user')->insertMultiple( - ['email', 'balance'], - [ - ['hello@world.com', 100], - ['another@world.com', 200], - ] - ); - - $this->makeTable('post', [ - 'id' => 'primary', - 'user_id' => 'integer,nullable', - 'title' => 'string', - 'content' => 'string', - ]); - - $this->getDatabase()->table('post')->insertMultiple( - ['title', 'user_id', 'content'], - [ - ['post 1', 1, 'post 1 body'], - ['post 2', 1, 'post 2 body'], - ['post 3', 2, 'post 3 body'], - ['post 4', 2, 'post 4 body'], - ] - ); - - $this->makeTable('comment', [ - 'id' => 'primary', - 'parent_id' => 'integer', - 'parent_type' => 'string', - 'message' => 'string', - ]); - - $this->getDatabase()->table('comment')->insertMultiple( - ['parent_id', 'parent_type', 'message'], - [ - [1, 'user', 'first comment'], - [1, 'user', 'second comment'], - [1, 'user', 'third comment'], - - [1, 'post', 'post 1 comment'], - [2, 'post', 'post 2 comment'], - [1, 'post', 'post 1.1 comment'], - [2, 'post', 'post 2.1 comment'], - ] - ); - - $this->orm = $this->withSchema(new Schema([ - User::class => [ - Schema::ROLE => 'user', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'user', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'email', 'balance'], - Schema::SCHEMA => [], - Schema::RELATIONS => [ - 'comments' => [ - Relation::TYPE => Relation::MORPHED_HAS_MANY, - Relation::TARGET => Comment::class, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::INNER_KEY => 'id', - Relation::OUTER_KEY => 'parent_id', - Relation::MORPH_KEY => 'parent_type', - ], - ], - 'posts' => [ - Relation::TYPE => Relation::HAS_MANY, - Relation::TARGET => Post::class, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::INNER_KEY => 'id', - Relation::OUTER_KEY => 'user_id', - ], - ], - ], - ], - Post::class => [ - Schema::ROLE => 'post', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'post', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'user_id', 'title', 'content'], - Schema::SCHEMA => [], - Schema::RELATIONS => [ - 'comments' => [ - Relation::TYPE => Relation::MORPHED_HAS_MANY, - Relation::TARGET => Comment::class, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::INNER_KEY => 'id', - Relation::OUTER_KEY => 'parent_id', - Relation::MORPH_KEY => 'parent_type', - ], - ], - ], - ], - Comment::class => [ - Schema::ROLE => 'comment', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'comment', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'parent_id', 'parent_type', 'message'], - Schema::SCHEMA => [], - Schema::RELATIONS => [], - ], - ])); - } - public function testFetchRelation(): void { $selector = new Select($this->orm, User::class); @@ -508,4 +387,125 @@ public function testMoveToAnother(): void return $c->message == 'post 1.1 comment'; })); } + + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('user', [ + 'id' => 'primary', + 'email' => 'string', + 'balance' => 'float', + ]); + + $this->getDatabase()->table('user')->insertMultiple( + ['email', 'balance'], + [ + ['hello@world.com', 100], + ['another@world.com', 200], + ], + ); + + $this->makeTable('post', [ + 'id' => 'primary', + 'user_id' => 'integer,nullable', + 'title' => 'string', + 'content' => 'string', + ]); + + $this->getDatabase()->table('post')->insertMultiple( + ['title', 'user_id', 'content'], + [ + ['post 1', 1, 'post 1 body'], + ['post 2', 1, 'post 2 body'], + ['post 3', 2, 'post 3 body'], + ['post 4', 2, 'post 4 body'], + ], + ); + + $this->makeTable('comment', [ + 'id' => 'primary', + 'parent_id' => 'integer', + 'parent_type' => 'string', + 'message' => 'string', + ]); + + $this->getDatabase()->table('comment')->insertMultiple( + ['parent_id', 'parent_type', 'message'], + [ + [1, 'user', 'first comment'], + [1, 'user', 'second comment'], + [1, 'user', 'third comment'], + + [1, 'post', 'post 1 comment'], + [2, 'post', 'post 2 comment'], + [1, 'post', 'post 1.1 comment'], + [2, 'post', 'post 2.1 comment'], + ], + ); + + $this->orm = $this->withSchema(new Schema([ + User::class => [ + Schema::ROLE => 'user', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'user', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'email', 'balance'], + Schema::SCHEMA => [], + Schema::RELATIONS => [ + 'comments' => [ + Relation::TYPE => Relation::MORPHED_HAS_MANY, + Relation::TARGET => Comment::class, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::INNER_KEY => 'id', + Relation::OUTER_KEY => 'parent_id', + Relation::MORPH_KEY => 'parent_type', + ], + ], + 'posts' => [ + Relation::TYPE => Relation::HAS_MANY, + Relation::TARGET => Post::class, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::INNER_KEY => 'id', + Relation::OUTER_KEY => 'user_id', + ], + ], + ], + ], + Post::class => [ + Schema::ROLE => 'post', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'post', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'user_id', 'title', 'content'], + Schema::SCHEMA => [], + Schema::RELATIONS => [ + 'comments' => [ + Relation::TYPE => Relation::MORPHED_HAS_MANY, + Relation::TARGET => Comment::class, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::INNER_KEY => 'id', + Relation::OUTER_KEY => 'parent_id', + Relation::MORPH_KEY => 'parent_type', + ], + ], + ], + ], + Comment::class => [ + Schema::ROLE => 'comment', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'comment', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'parent_id', 'parent_type', 'message'], + Schema::SCHEMA => [], + Schema::RELATIONS => [], + ], + ])); + } } diff --git a/tests/ORM/Functional/Driver/Common/Relation/Morphed/MorphedHasManyScopeTest.php b/tests/ORM/Functional/Driver/Common/Relation/Morphed/MorphedHasManyScopeTest.php index 5bcffbeb..289963bb 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/Morphed/MorphedHasManyScopeTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/Morphed/MorphedHasManyScopeTest.php @@ -21,70 +21,6 @@ abstract class MorphedHasManyScopeTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('user', [ - 'id' => 'primary', - 'email' => 'string', - 'balance' => 'float', - ]); - - $this->getDatabase()->table('user')->insertMultiple( - ['email', 'balance'], - [ - ['hello@world.com', 100], - ['another@world.com', 200], - ] - ); - - $this->makeTable('post', [ - 'id' => 'primary', - 'user_id' => 'integer,nullable', - 'title' => 'string', - 'content' => 'string', - ]); - - $this->getDatabase()->table('post')->insertMultiple( - ['title', 'user_id', 'content'], - [ - ['post 1', 1, 'post 1 body'], - ['post 2', 1, 'post 2 body'], - ['post 3', 2, 'post 3 body'], - ['post 4', 2, 'post 4 body'], - ] - ); - - $this->makeTable('comment', [ - 'id' => 'primary', - 'parent_id' => 'integer', - 'parent_type' => 'string', - 'level' => 'int', - 'message' => 'string', - ]); - - $this->getDatabase()->table('comment')->insertMultiple( - ['parent_id', 'parent_type', 'level', 'message',], - [ - [1, 'user', 1, 'msg 1'], - [1, 'user', 2, 'msg 2'], - [1, 'user', 3, 'msg 3'], - [1, 'user', 4, 'msg 4'], - [2, 'user', 1, 'msg 2.1'], - [2, 'user', 2, 'msg 2.2'], - [2, 'user', 3, 'msg 2.3'], - [1, 'post', 1, 'p.msg 1'], - [1, 'post', 2, 'p.msg 2'], - [1, 'post', 3, 'p.msg 3'], - [1, 'post', 4, 'p.msg 4'], - [2, 'post', 1, 'p.msg 2.1'], - [2, 'post', 2, 'p.msg 2.2'], - [2, 'post', 3, 'p.msg 2.3'], - ] - ); - } - public function testOrdered(): void { $this->orm = $this->withCommentsSchema([ @@ -574,6 +510,70 @@ public function testInvalidOrderBy(): void ])->orderBy('user.id', 'DESC')->fetchAll(); } + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('user', [ + 'id' => 'primary', + 'email' => 'string', + 'balance' => 'float', + ]); + + $this->getDatabase()->table('user')->insertMultiple( + ['email', 'balance'], + [ + ['hello@world.com', 100], + ['another@world.com', 200], + ], + ); + + $this->makeTable('post', [ + 'id' => 'primary', + 'user_id' => 'integer,nullable', + 'title' => 'string', + 'content' => 'string', + ]); + + $this->getDatabase()->table('post')->insertMultiple( + ['title', 'user_id', 'content'], + [ + ['post 1', 1, 'post 1 body'], + ['post 2', 1, 'post 2 body'], + ['post 3', 2, 'post 3 body'], + ['post 4', 2, 'post 4 body'], + ], + ); + + $this->makeTable('comment', [ + 'id' => 'primary', + 'parent_id' => 'integer', + 'parent_type' => 'string', + 'level' => 'int', + 'message' => 'string', + ]); + + $this->getDatabase()->table('comment')->insertMultiple( + ['parent_id', 'parent_type', 'level', 'message',], + [ + [1, 'user', 1, 'msg 1'], + [1, 'user', 2, 'msg 2'], + [1, 'user', 3, 'msg 3'], + [1, 'user', 4, 'msg 4'], + [2, 'user', 1, 'msg 2.1'], + [2, 'user', 2, 'msg 2.2'], + [2, 'user', 3, 'msg 2.3'], + [1, 'post', 1, 'p.msg 1'], + [1, 'post', 2, 'p.msg 2'], + [1, 'post', 3, 'p.msg 3'], + [1, 'post', 4, 'p.msg 4'], + [2, 'post', 1, 'p.msg 2.1'], + [2, 'post', 2, 'p.msg 2.2'], + [2, 'post', 3, 'p.msg 2.3'], + ], + ); + } + protected function withCommentsSchema(array $relationSchema) { $eSchema = []; diff --git a/tests/ORM/Functional/Driver/Common/Relation/Morphed/MorphedHasOnePromiseTest.php b/tests/ORM/Functional/Driver/Common/Relation/Morphed/MorphedHasOnePromiseTest.php index a1377579..aa7a3c77 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/Morphed/MorphedHasOnePromiseTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/Morphed/MorphedHasOnePromiseTest.php @@ -20,62 +20,6 @@ abstract class MorphedHasOnePromiseTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('user', [ - 'id' => 'primary', - 'email' => 'string', - 'balance' => 'float', - ]); - - $this->getDatabase()->table('user')->insertMultiple( - ['email', 'balance'], - [ - ['hello@world.com', 100], - ['another@world.com', 200], - ] - ); - - $this->makeTable('post', [ - 'id' => 'primary', - 'user_id' => 'integer,nullable', - 'title' => 'string', - 'content' => 'string', - ]); - - $this->getDatabase()->table('post')->insertMultiple( - ['title', 'user_id', 'content'], - [ - ['post 1', 1, 'post 1 body'], - ['post 2', 1, 'post 2 body'], - ['post 3', 2, 'post 3 body'], - ['post 4', 2, 'post 4 body'], - ] - ); - - $this->makeTable('image', [ - 'id' => 'primary', - 'parent_id' => 'integer', - 'parent_type' => 'string', - 'url' => 'string', - ]); - - $this->getDatabase()->table('image')->insertMultiple( - ['parent_id', 'parent_type', 'url'], - [ - [1, 'user', 'user-image.png'], - [1, 'post', 'post-image.png'], - [2, 'user', 'user-2-image.png'], - [2, 'post', 'post-2-image.png'], - [3, 'post', 'post-3-image.png'], - ] - ); - - $this->orm = $this->withSchema(new Schema($this->getSchemaArray())); - } - public function testAccessEntity(): void { $selector = new Select($this->orm, User::class); @@ -347,6 +291,62 @@ public function testChangeParents(): void $this->assertSame('user-image.png', $p->image->url); } + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('user', [ + 'id' => 'primary', + 'email' => 'string', + 'balance' => 'float', + ]); + + $this->getDatabase()->table('user')->insertMultiple( + ['email', 'balance'], + [ + ['hello@world.com', 100], + ['another@world.com', 200], + ], + ); + + $this->makeTable('post', [ + 'id' => 'primary', + 'user_id' => 'integer,nullable', + 'title' => 'string', + 'content' => 'string', + ]); + + $this->getDatabase()->table('post')->insertMultiple( + ['title', 'user_id', 'content'], + [ + ['post 1', 1, 'post 1 body'], + ['post 2', 1, 'post 2 body'], + ['post 3', 2, 'post 3 body'], + ['post 4', 2, 'post 4 body'], + ], + ); + + $this->makeTable('image', [ + 'id' => 'primary', + 'parent_id' => 'integer', + 'parent_type' => 'string', + 'url' => 'string', + ]); + + $this->getDatabase()->table('image')->insertMultiple( + ['parent_id', 'parent_type', 'url'], + [ + [1, 'user', 'user-image.png'], + [1, 'post', 'post-image.png'], + [2, 'user', 'user-2-image.png'], + [2, 'post', 'post-2-image.png'], + [3, 'post', 'post-3-image.png'], + ], + ); + + $this->orm = $this->withSchema(new Schema($this->getSchemaArray())); + } + private function getSchemaArray(): array { return [ diff --git a/tests/ORM/Functional/Driver/Common/Relation/Morphed/MorphedHasOneRelationTest.php b/tests/ORM/Functional/Driver/Common/Relation/Morphed/MorphedHasOneRelationTest.php index d2d17453..a10e1b20 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/Morphed/MorphedHasOneRelationTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/Morphed/MorphedHasOneRelationTest.php @@ -20,62 +20,6 @@ abstract class MorphedHasOneRelationTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('user', [ - 'id' => 'primary', - 'email' => 'string', - 'balance' => 'float', - ]); - - $this->getDatabase()->table('user')->insertMultiple( - ['email', 'balance'], - [ - ['hello@world.com', 100], - ['another@world.com', 200], - ] - ); - - $this->makeTable('post', [ - 'id' => 'primary', - 'user_id' => 'integer,nullable', - 'title' => 'string', - 'content' => 'string', - ]); - - $this->getDatabase()->table('post')->insertMultiple( - ['title', 'user_id', 'content'], - [ - ['post 1', 1, 'post 1 body'], - ['post 2', 1, 'post 2 body'], - ['post 3', 2, 'post 3 body'], - ['post 4', 2, 'post 4 body'], - ] - ); - - $this->makeTable('image', [ - 'id' => 'primary', - 'parent_id' => 'integer', - 'parent_type' => 'string', - 'url' => 'string', - ]); - - $this->getDatabase()->table('image')->insertMultiple( - ['parent_id', 'parent_type', 'url'], - [ - [1, 'user', 'user-image.png'], - [1, 'post', 'post-image.png'], - [2, 'user', 'user-2-image.png'], - [2, 'post', 'post-2-image.png'], - [3, 'post', 'post-3-image.png'], - ] - ); - - $this->orm = $this->withSchema(new Schema($this->getSchemaArray())); - } - public function testFetchRelation(): void { $selector = new Select($this->orm, User::class); @@ -164,8 +108,8 @@ public function testFetchOverlapping(): void { $selector = new Select($this->orm, User::class); $selector->load('image') - ->load('posts.image') - ->orderBy('user.id'); + ->load('posts.image') + ->orderBy('user.id'); $this->assertEquals([ @@ -493,6 +437,62 @@ public function testChangeParents(): void $this->assertSame('user-image.png', $p->image->url); } + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('user', [ + 'id' => 'primary', + 'email' => 'string', + 'balance' => 'float', + ]); + + $this->getDatabase()->table('user')->insertMultiple( + ['email', 'balance'], + [ + ['hello@world.com', 100], + ['another@world.com', 200], + ], + ); + + $this->makeTable('post', [ + 'id' => 'primary', + 'user_id' => 'integer,nullable', + 'title' => 'string', + 'content' => 'string', + ]); + + $this->getDatabase()->table('post')->insertMultiple( + ['title', 'user_id', 'content'], + [ + ['post 1', 1, 'post 1 body'], + ['post 2', 1, 'post 2 body'], + ['post 3', 2, 'post 3 body'], + ['post 4', 2, 'post 4 body'], + ], + ); + + $this->makeTable('image', [ + 'id' => 'primary', + 'parent_id' => 'integer', + 'parent_type' => 'string', + 'url' => 'string', + ]); + + $this->getDatabase()->table('image')->insertMultiple( + ['parent_id', 'parent_type', 'url'], + [ + [1, 'user', 'user-image.png'], + [1, 'post', 'post-image.png'], + [2, 'user', 'user-2-image.png'], + [2, 'post', 'post-2-image.png'], + [3, 'post', 'post-3-image.png'], + ], + ); + + $this->orm = $this->withSchema(new Schema($this->getSchemaArray())); + } + private function getSchemaArray(): array { return [ diff --git a/tests/ORM/Functional/Driver/Common/Relation/NestedEagerTest.php b/tests/ORM/Functional/Driver/Common/Relation/NestedEagerTest.php index af272806..042dcf07 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/NestedEagerTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/NestedEagerTest.php @@ -18,6 +18,94 @@ abstract class NestedEagerTest extends BaseTest { use TableTrait; + public function testFetchEager(): void + { + $selector = new Select($this->orm, User::class); + $selector->orderBy('id', 'ASC'); + + $this->assertEquals( + [ + [ + 'id' => 1, + 'email' => 'hello@world.com', + 'balance' => 100.0, + 'profile' => [ + 'id' => 1, + 'user_id' => 1, + 'image' => 'image.png', + 'nested' => [ + 'label' => 'hello', + ], + ], + ], + [ + 'id' => 2, + 'email' => 'another@world.com', + 'balance' => 200.0, + 'profile' => null, + ], + [ + 'id' => 3, + 'email' => 'third@world.com', + 'balance' => 150.0, + 'profile' => [ + 'id' => 2, + 'user_id' => 3, + 'image' => 'third.png', + 'nested' => [ + 'label' => 'hello3', + ], + ], + ], + ], + $selector->fetchData(), + ); + } + + public function testFetchEagerReverse(): void + { + $selector = new Select($this->orm, User::class); + $selector->orderBy('user.id', 'DESC'); + + $this->assertEquals( + [ + [ + 'id' => 3, + 'email' => 'third@world.com', + 'balance' => 150.0, + 'profile' => [ + 'id' => 2, + 'user_id' => 3, + 'image' => 'third.png', + 'nested' => [ + 'label' => 'hello3', + ], + ], + ], + [ + 'id' => 2, + 'email' => 'another@world.com', + 'balance' => 200.0, + 'profile' => null, + ], + [ + 'id' => 1, + 'email' => 'hello@world.com', + 'balance' => 100.0, + 'profile' => [ + 'id' => 1, + 'user_id' => 1, + 'image' => 'image.png', + 'nested' => [ + 'label' => 'hello', + ], + ], + ], + ], + $selector->fetchData(), + ); + } + public function setUp(): void { parent::setUp(); @@ -28,7 +116,7 @@ public function setUp(): void 'id' => 'primary', 'email' => 'string', 'balance' => 'float', - ] + ], ); $this->makeTable( @@ -38,7 +126,7 @@ public function setUp(): void 'user_id' => 'integer,nullable', 'image' => 'string', 'label' => 'string', - ] + ], ); $this->makeFK('profile', 'user_id', 'user', 'id'); @@ -49,7 +137,7 @@ public function setUp(): void ['hello@world.com', 100], ['another@world.com', 200], ['third@world.com', 150], - ] + ], ); $this->getDatabase()->table('profile')->insertMultiple( @@ -57,7 +145,7 @@ public function setUp(): void [ [1, 'image.png', 'hello'], [3, 'third.png', 'hello3'], - ] + ], ); $this->orm = $this->withSchema( @@ -113,96 +201,8 @@ public function setUp(): void Schema::SCHEMA => [], Schema::RELATIONS => [], ], - ] - ) - ); - } - - public function testFetchEager(): void - { - $selector = new Select($this->orm, User::class); - $selector->orderBy('id', 'ASC'); - - $this->assertEquals( - [ - [ - 'id' => 1, - 'email' => 'hello@world.com', - 'balance' => 100.0, - 'profile' => [ - 'id' => 1, - 'user_id' => 1, - 'image' => 'image.png', - 'nested' => [ - 'label' => 'hello', - ], - ], - ], - [ - 'id' => 2, - 'email' => 'another@world.com', - 'balance' => 200.0, - 'profile' => null, - ], - [ - 'id' => 3, - 'email' => 'third@world.com', - 'balance' => 150.0, - 'profile' => [ - 'id' => 2, - 'user_id' => 3, - 'image' => 'third.png', - 'nested' => [ - 'label' => 'hello3', - ], - ], ], - ], - $selector->fetchData() - ); - } - - public function testFetchEagerReverse(): void - { - $selector = new Select($this->orm, User::class); - $selector->orderBy('user.id', 'DESC'); - - $this->assertEquals( - [ - [ - 'id' => 3, - 'email' => 'third@world.com', - 'balance' => 150.0, - 'profile' => [ - 'id' => 2, - 'user_id' => 3, - 'image' => 'third.png', - 'nested' => [ - 'label' => 'hello3', - ], - ], - ], - [ - 'id' => 2, - 'email' => 'another@world.com', - 'balance' => 200.0, - 'profile' => null, - ], - [ - 'id' => 1, - 'email' => 'hello@world.com', - 'balance' => 100.0, - 'profile' => [ - 'id' => 1, - 'user_id' => 1, - 'image' => 'image.png', - 'nested' => [ - 'label' => 'hello', - ], - ], - ], - ], - $selector->fetchData() + ), ); } } diff --git a/tests/ORM/Functional/Driver/Common/Relation/RefersTo/RefersToProxyMapperRenamedFieldTest.php b/tests/ORM/Functional/Driver/Common/Relation/RefersTo/RefersToProxyMapperRenamedFieldTest.php index 95522291..0a33da67 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/RefersTo/RefersToProxyMapperRenamedFieldTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/RefersTo/RefersToProxyMapperRenamedFieldTest.php @@ -41,7 +41,7 @@ public function setUp(): void ['email', 'balance'], [ ['hello@world.com', 100], - ] + ], ); $this->getDatabase()->table('profile')->insertMultiple( @@ -50,14 +50,14 @@ public function setUp(): void [1, 'image.png'], [2, 'second.png'], [null, 'third.png'], - ] + ], ); $this->getDatabase()->table('nested')->insertMultiple( ['profile_id', 'label'], [ [1, 'nested-label'], - ] + ], ); $this->orm = $this->withSchema(new Schema([ diff --git a/tests/ORM/Functional/Driver/Common/Relation/RefersTo/RefersToProxyMapperTest.php b/tests/ORM/Functional/Driver/Common/Relation/RefersTo/RefersToProxyMapperTest.php index b8e96e32..e564e4d8 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/RefersTo/RefersToProxyMapperTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/RefersTo/RefersToProxyMapperTest.php @@ -19,88 +19,6 @@ abstract class RefersToProxyMapperTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('user', [ - 'id' => 'primary', - 'email' => 'string', - 'balance' => 'float', - ]); - - $this->makeTable('profile', [ - 'id' => 'primary', - 'user_id' => 'integer,null', - 'image' => 'string', - ]); - - $this->makeTable('nested', [ - 'id' => 'primary', - 'profile_id' => 'integer', - 'label' => 'string', - ]); - - $this->makeFK('nested', 'profile_id', 'profile', 'id'); - - $this->getDatabase()->table('user')->insertMultiple( - ['email', 'balance'], - [ - ['hello@world.com', 100], - ] - ); - - $this->getDatabase()->table('profile')->insertMultiple( - ['user_id', 'image'], - [ - [1, 'image.png'], - [2, 'second.png'], - [null, 'third.png'], - ] - ); - - $this->getDatabase()->table('nested')->insertMultiple( - ['profile_id', 'label'], - [ - [1, 'nested-label'], - ] - ); - - $this->orm = $this->withSchema(new Schema([ - User::class => [ - Schema::ROLE => 'user', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'user', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'email', 'balance'], - Schema::SCHEMA => [], - Schema::RELATIONS => [], - ], - Profile::class => [ - Schema::ROLE => 'profile', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'profile', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'user_id', 'image'], - Schema::SCHEMA => [], - Schema::RELATIONS => [ - 'user' => [ - Relation::TYPE => Relation::REFERS_TO, - Relation::TARGET => User::class, - Relation::LOAD => Relation::LOAD_PROMISE, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::INNER_KEY => 'user_id', - Relation::OUTER_KEY => 'id', - ], - ], - ], - ], - ])); - } - public function testFetchRelation(): void { $selector = new Select($this->orm, Profile::class); @@ -212,4 +130,86 @@ public function testAssignPromiseAsRelation(): void $this->assertInstanceOf(User::class, $p->user); $this->assertEquals('hello@world.com', $p->user->email); } + + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('user', [ + 'id' => 'primary', + 'email' => 'string', + 'balance' => 'float', + ]); + + $this->makeTable('profile', [ + 'id' => 'primary', + 'user_id' => 'integer,null', + 'image' => 'string', + ]); + + $this->makeTable('nested', [ + 'id' => 'primary', + 'profile_id' => 'integer', + 'label' => 'string', + ]); + + $this->makeFK('nested', 'profile_id', 'profile', 'id'); + + $this->getDatabase()->table('user')->insertMultiple( + ['email', 'balance'], + [ + ['hello@world.com', 100], + ], + ); + + $this->getDatabase()->table('profile')->insertMultiple( + ['user_id', 'image'], + [ + [1, 'image.png'], + [2, 'second.png'], + [null, 'third.png'], + ], + ); + + $this->getDatabase()->table('nested')->insertMultiple( + ['profile_id', 'label'], + [ + [1, 'nested-label'], + ], + ); + + $this->orm = $this->withSchema(new Schema([ + User::class => [ + Schema::ROLE => 'user', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'user', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'email', 'balance'], + Schema::SCHEMA => [], + Schema::RELATIONS => [], + ], + Profile::class => [ + Schema::ROLE => 'profile', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'profile', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'user_id', 'image'], + Schema::SCHEMA => [], + Schema::RELATIONS => [ + 'user' => [ + Relation::TYPE => Relation::REFERS_TO, + Relation::TARGET => User::class, + Relation::LOAD => Relation::LOAD_PROMISE, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::INNER_KEY => 'user_id', + Relation::OUTER_KEY => 'id', + ], + ], + ], + ], + ])); + } } diff --git a/tests/ORM/Functional/Driver/Common/Relation/RefersTo/RefersToRelationCompositeKeyTest.php b/tests/ORM/Functional/Driver/Common/Relation/RefersTo/RefersToRelationCompositeKeyTest.php index 4bda3cc8..c9e03226 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/RefersTo/RefersToRelationCompositeKeyTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/RefersTo/RefersToRelationCompositeKeyTest.php @@ -20,46 +20,8 @@ abstract class RefersToRelationCompositeKeyTest extends BaseTest { use TableTrait; - protected const - CHILD_CONTAINER = 'child_entity'; - protected const - CHILDREN_CONTAINER = 'children'; - - public function setUp(): void - { - parent::setUp(); - - $this->dropDatabase(); - $this->makeTable( - 'parent_entity', - [ - 'pField1' => 'bigInteger,primary', - 'pField2' => 'bigInteger,primary', - 'pField3' => 'integer,nullable', - 'cField1' => 'bigInteger,nullable', - 'cField2' => 'bigInteger,nullable', - ] - ); - $this->makeTable( - 'child_entity', - [ - 'field1' => 'bigInteger,primary', - 'field2' => 'bigInteger,primary', - 'field3' => 'string,nullable', - 'parent_field1' => 'bigInteger,null', - 'parent_field2' => 'bigInteger,null', - ] - ); - - $this->makeCompositeFK( - 'child_entity', - ['parent_field1', 'parent_field2'], - 'parent_entity', - ['pField1', 'pField2'] - ); - - $this->orm = $this->withSchema(new Schema($this->getSchemaArray())); - } + protected const CHILD_CONTAINER = 'child_entity'; + protected const CHILDREN_CONTAINER = 'children'; public function testCreateParentWithDoubleReference(): void { @@ -328,6 +290,42 @@ public function testSetNull(): void $this->assertCount(1, $u->children); } + public function setUp(): void + { + parent::setUp(); + + $this->dropDatabase(); + $this->makeTable( + 'parent_entity', + [ + 'pField1' => 'bigInteger,primary', + 'pField2' => 'bigInteger,primary', + 'pField3' => 'integer,nullable', + 'cField1' => 'bigInteger,nullable', + 'cField2' => 'bigInteger,nullable', + ], + ); + $this->makeTable( + 'child_entity', + [ + 'field1' => 'bigInteger,primary', + 'field2' => 'bigInteger,primary', + 'field3' => 'string,nullable', + 'parent_field1' => 'bigInteger,null', + 'parent_field2' => 'bigInteger,null', + ], + ); + + $this->makeCompositeFK( + 'child_entity', + ['parent_field1', 'parent_field2'], + 'parent_entity', + ['pField1', 'pField2'], + ); + + $this->orm = $this->withSchema(new Schema($this->getSchemaArray())); + } + private function getSchemaArray(): array { return [ diff --git a/tests/ORM/Functional/Driver/Common/Relation/RefersTo/RefersToRelationMiniRowsetTest.php b/tests/ORM/Functional/Driver/Common/Relation/RefersTo/RefersToRelationMiniRowsetTest.php index 48fd3631..de64bea1 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/RefersTo/RefersToRelationMiniRowsetTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/RefersTo/RefersToRelationMiniRowsetTest.php @@ -19,54 +19,6 @@ abstract class RefersToRelationMiniRowsetTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('user', [ - 'id' => 'primary', - 'comment_id' => 'integer,nullable', - ]); - - $this->makeTable('comment', [ - 'id' => 'primary', - ]); - - $this->orm = $this->withSchema(new Schema([ - User::class => [ - Schema::ROLE => 'user', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'user', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'comment_id'], - Schema::TYPECAST => ['id' => 'int', 'comment_id' => 'int'], - Schema::RELATIONS => [ - 'lastComment' => [ - Relation::TYPE => Relation::REFERS_TO, - Relation::TARGET => Comment::class, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::NULLABLE => true, - Relation::INNER_KEY => 'comment_id', - Relation::OUTER_KEY => 'id', - ], - ], - ], - ], - Comment::class => [ - Schema::ROLE => 'comment', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'comment', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id'], - Schema::TYPECAST => ['id' => 'int'], - Schema::RELATIONS => [], - ], - ])); - } - public function testCreateEmptyComment(): void { $c = new Comment(); @@ -141,4 +93,52 @@ public function testCreateUserWithComment(): void $this->assertSame(['id' => 1, 'comment_id' => 1], $userData[0]); $this->assertSame(['id' => 1], $commentData[0]); } + + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('user', [ + 'id' => 'primary', + 'comment_id' => 'integer,nullable', + ]); + + $this->makeTable('comment', [ + 'id' => 'primary', + ]); + + $this->orm = $this->withSchema(new Schema([ + User::class => [ + Schema::ROLE => 'user', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'user', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'comment_id'], + Schema::TYPECAST => ['id' => 'int', 'comment_id' => 'int'], + Schema::RELATIONS => [ + 'lastComment' => [ + Relation::TYPE => Relation::REFERS_TO, + Relation::TARGET => Comment::class, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::NULLABLE => true, + Relation::INNER_KEY => 'comment_id', + Relation::OUTER_KEY => 'id', + ], + ], + ], + ], + Comment::class => [ + Schema::ROLE => 'comment', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'comment', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id'], + Schema::TYPECAST => ['id' => 'int'], + Schema::RELATIONS => [], + ], + ])); + } } diff --git a/tests/ORM/Functional/Driver/Common/Relation/RefersTo/RefersToRelationTest.php b/tests/ORM/Functional/Driver/Common/Relation/RefersTo/RefersToRelationTest.php index d396dc26..efdd0b1a 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/RefersTo/RefersToRelationTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/RefersTo/RefersToRelationTest.php @@ -20,28 +20,6 @@ abstract class RefersToRelationTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('user', [ - 'id' => 'primary', - 'email' => 'string', - 'balance' => 'float', - 'comment_id' => 'integer,nullable', - ]); - - $this->makeTable('comment', [ - 'id' => 'primary', - 'user_id' => 'integer', - 'message' => 'string', - ], [ - 'user_id' => ['table' => 'user', 'column' => 'id'], - ]); - - $this->orm = $this->withSchema(new Schema($this->getSchemaArray())); - } - public function testCreateUserWithDoubleReference(): void { $u = new User(); @@ -236,10 +214,32 @@ public function testSetNotNullable(): void $this->assertInstanceOf( Relation\BelongsTo::class, - $this->orm->getRelationMap(User::class)->getRelations()['lastComment'] + $this->orm->getRelationMap(User::class)->getRelations()['lastComment'], ); } + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('user', [ + 'id' => 'primary', + 'email' => 'string', + 'balance' => 'float', + 'comment_id' => 'integer,nullable', + ]); + + $this->makeTable('comment', [ + 'id' => 'primary', + 'user_id' => 'integer', + 'message' => 'string', + ], [ + 'user_id' => ['table' => 'user', 'column' => 'id'], + ]); + + $this->orm = $this->withSchema(new Schema($this->getSchemaArray())); + } + private function getSchemaArray(): array { return [ diff --git a/tests/ORM/Functional/Driver/Common/Relation/RelationWithColumnAliasTest.php b/tests/ORM/Functional/Driver/Common/Relation/RelationWithColumnAliasTest.php index 94131058..bf54f5b8 100644 --- a/tests/ORM/Functional/Driver/Common/Relation/RelationWithColumnAliasTest.php +++ b/tests/ORM/Functional/Driver/Common/Relation/RelationWithColumnAliasTest.php @@ -24,76 +24,6 @@ abstract class RelationWithColumnAliasTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('user', [ - 'id_int' => 'primary', - 'email_str' => 'string', - 'balance_float' => 'float', - ]); - - $this->makeTable('comment', [ - 'id_int' => 'primary', - 'user_id_int' => 'integer', - 'message_str' => 'string', - ]); - - $this->makeFK('comment', 'user_id_int', 'user', 'id_int'); - - $this->getDatabase()->table('user')->insertMultiple( - ['email_str', 'balance_float'], - [ - ['hello@world.com', 100], - ['another@world.com', 200], - ] - ); - - $this->getDatabase()->table('comment')->insertMultiple( - ['user_id_int', 'message_str'], - [ - [1, 'msg 1'], - [1, 'msg 2'], - [1, 'msg 3'], - ] - ); - - $this->orm = $this->withSchema(new Schema([ - User::class => [ - Schema::ROLE => 'user', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'user', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id' => 'id_int', 'email' => 'email_str', 'balance' => 'balance_float'], - Schema::SCHEMA => [], - Schema::RELATIONS => [ - 'comments' => [ - Relation::TYPE => Relation::HAS_MANY, - Relation::TARGET => Comment::class, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::INNER_KEY => 'id', - Relation::OUTER_KEY => 'user_id', - ], - ], - ], - ], - Comment::class => [ - Schema::ROLE => 'comment', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'comment', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id' => 'id_int', 'user_id' => 'user_id_int', 'message' => 'message_str'], - Schema::SCHEMA => [], - Schema::RELATIONS => [], - Schema::SCOPE => SortByIDScope::class, - ], - ])); - } - public function testFetchRelation(): void { $selector = new Select($this->orm, User::class); @@ -209,8 +139,8 @@ public function testFetchOneWhere(): void { $selector = new Select($this->orm, User::class); $selector->load('comments', ['method' => JoinableLoader::INLOAD]) - ->where('id', 1) - ->orderBy('user.id'); + ->where('id', 1) + ->orderBy('user.id'); $this->assertEquals([ [ @@ -242,8 +172,8 @@ public function testFetchOneWhereTargeted(): void { $selector = new Select($this->orm, User::class); $selector->load('comments', ['method' => JoinableLoader::INLOAD]) - ->where('@.id', 1) - ->orderBy('user.id'); + ->where('@.id', 1) + ->orderBy('user.id'); $this->assertEquals([ [ @@ -346,7 +276,7 @@ public function testFilterByRelatedExpression(): void ->with('comments') ->where( 'comments.id', - new Expression($selector->getBuilder()->resolve('user.id')) + new Expression($selector->getBuilder()->resolve('user.id')), )->fetchAll(); $this->assertCount(1, $all); @@ -554,4 +484,74 @@ public function testSliceAndSaveToAnotherParent(): void $this->assertEquals('new b', $b->comments[0]->message); } + + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('user', [ + 'id_int' => 'primary', + 'email_str' => 'string', + 'balance_float' => 'float', + ]); + + $this->makeTable('comment', [ + 'id_int' => 'primary', + 'user_id_int' => 'integer', + 'message_str' => 'string', + ]); + + $this->makeFK('comment', 'user_id_int', 'user', 'id_int'); + + $this->getDatabase()->table('user')->insertMultiple( + ['email_str', 'balance_float'], + [ + ['hello@world.com', 100], + ['another@world.com', 200], + ], + ); + + $this->getDatabase()->table('comment')->insertMultiple( + ['user_id_int', 'message_str'], + [ + [1, 'msg 1'], + [1, 'msg 2'], + [1, 'msg 3'], + ], + ); + + $this->orm = $this->withSchema(new Schema([ + User::class => [ + Schema::ROLE => 'user', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'user', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id' => 'id_int', 'email' => 'email_str', 'balance' => 'balance_float'], + Schema::SCHEMA => [], + Schema::RELATIONS => [ + 'comments' => [ + Relation::TYPE => Relation::HAS_MANY, + Relation::TARGET => Comment::class, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::INNER_KEY => 'id', + Relation::OUTER_KEY => 'user_id', + ], + ], + ], + ], + Comment::class => [ + Schema::ROLE => 'comment', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'comment', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id' => 'id_int', 'user_id' => 'user_id_int', 'message' => 'message_str'], + Schema::SCHEMA => [], + Schema::RELATIONS => [], + Schema::SCOPE => SortByIDScope::class, + ], + ])); + } } diff --git a/tests/ORM/Functional/Driver/Common/RenamedPKTest.php b/tests/ORM/Functional/Driver/Common/RenamedPKTest.php index 56d05bfa..84521883 100644 --- a/tests/ORM/Functional/Driver/Common/RenamedPKTest.php +++ b/tests/ORM/Functional/Driver/Common/RenamedPKTest.php @@ -82,7 +82,7 @@ private function createTable2(): void [ 'identity_id' => 'bigInteger', 'identity_key' => 'integer,nullable', - ] + ], ); } @@ -93,7 +93,7 @@ private function createTable1(): void [ 'identity_id' => 'primary', 'identity_key' => 'integer,nullable', - ] + ], ); } diff --git a/tests/ORM/Functional/Driver/Common/Schema/Column/ColumnAliasesTest.php b/tests/ORM/Functional/Driver/Common/Schema/Column/ColumnAliasesTest.php index 7cf86294..05ba7e6e 100644 --- a/tests/ORM/Functional/Driver/Common/Schema/Column/ColumnAliasesTest.php +++ b/tests/ORM/Functional/Driver/Common/Schema/Column/ColumnAliasesTest.php @@ -17,38 +17,6 @@ abstract class ColumnAliasesTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('user', [ - 'id_int' => 'primary', - 'email_str' => 'string', - 'balance_float' => 'float', - ]); - - $this->getDatabase()->table('user')->insertMultiple( - ['email_str', 'balance_float'], - [ - ['hello@world.com', 100], - ['another@world.com', 200], - ] - ); - - $this->orm = $this->withSchema(new Schema([ - User::class => [ - Schema::ROLE => 'user', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'user', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id' => 'id_int', 'email' => 'email_str', 'balance' => 'balance_float'], - Schema::SCHEMA => [], - Schema::RELATIONS => [], - ], - ])); - } - public function testStore(): void { $e = new User(); @@ -164,4 +132,36 @@ public function testFindDirectImmutable(): void $this->assertEquals('another@world.com', $result[1]->email); $this->assertEquals(200.0, $result[1]->balance); } + + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('user', [ + 'id_int' => 'primary', + 'email_str' => 'string', + 'balance_float' => 'float', + ]); + + $this->getDatabase()->table('user')->insertMultiple( + ['email_str', 'balance_float'], + [ + ['hello@world.com', 100], + ['another@world.com', 200], + ], + ); + + $this->orm = $this->withSchema(new Schema([ + User::class => [ + Schema::ROLE => 'user', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'user', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id' => 'id_int', 'email' => 'email_str', 'balance' => 'balance_float'], + Schema::SCHEMA => [], + Schema::RELATIONS => [], + ], + ])); + } } diff --git a/tests/ORM/Functional/Driver/Common/Schema/Column/UUIDTest.php b/tests/ORM/Functional/Driver/Common/Schema/Column/UUIDTest.php index 39e3e573..26d783ab 100644 --- a/tests/ORM/Functional/Driver/Common/Schema/Column/UUIDTest.php +++ b/tests/ORM/Functional/Driver/Common/Schema/Column/UUIDTest.php @@ -19,35 +19,6 @@ abstract class UUIDTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('user', [ - 'id' => 'primary', - 'uuid' => 'binary(16)', - 'email' => 'string', - 'balance' => 'float', - ], [], null, ['uuid' => null]); - - $this->orm = $this->withSchema(new Schema([ - User::class => [ - Schema::ROLE => 'user', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'user', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'uuid', 'email', 'balance'], - Schema::TYPECAST => [ - 'id' => 'int', - 'uuid' => [Uuid::class, 'parse'], - 'balance' => 'float', - ], - Schema::RELATIONS => [], - ], - ])); - } - public function testCreate(): void { $e = new User(); @@ -130,4 +101,33 @@ public function testUpdate(): void $this->assertInstanceOf(Uuid::class, $result2->uuid); $this->assertEquals($result->uuid->toString(), $result2->uuid->toString()); } + + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('user', [ + 'id' => 'primary', + 'uuid' => 'binary(16)', + 'email' => 'string', + 'balance' => 'float', + ], [], null, ['uuid' => null]); + + $this->orm = $this->withSchema(new Schema([ + User::class => [ + Schema::ROLE => 'user', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'user', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'uuid', 'email', 'balance'], + Schema::TYPECAST => [ + 'id' => 'int', + 'uuid' => [Uuid::class, 'parse'], + 'balance' => 'float', + ], + Schema::RELATIONS => [], + ], + ])); + } } diff --git a/tests/ORM/Functional/Driver/Common/Schema/CommonTest.php b/tests/ORM/Functional/Driver/Common/Schema/CommonTest.php index 817841e1..83db3496 100644 --- a/tests/ORM/Functional/Driver/Common/Schema/CommonTest.php +++ b/tests/ORM/Functional/Driver/Common/Schema/CommonTest.php @@ -23,67 +23,6 @@ abstract class CommonTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('user', [ - 'id' => 'primary', - 'active' => 'bool', - 'email' => 'string', - 'balance' => 'float', - ]); - - $this->makeTable( - 'user_with_uuid_primary_key', - [ - 'uuid' => 'string(36),primary', - 'email' => 'string', - 'balance' => 'float', - ] - ); - - $this->getDatabase()->table('user')->insertMultiple( - ['email', 'active', 'balance'], - [ - ['hello@world.com', true, 100], - ['another@world.com', false, 200], - ] - ); - - $this->orm = $this->withSchema(new Schema([ - User::class => [ - SchemaInterface::ROLE => 'user', - SchemaInterface::MAPPER => Mapper::class, - SchemaInterface::DATABASE => 'default', - SchemaInterface::TABLE => 'user', - SchemaInterface::PRIMARY_KEY => 'id', - SchemaInterface::COLUMNS => ['id', 'email', 'active', 'balance'], - SchemaInterface::TYPECAST => [ - 'id' => 'int', - 'active' => 'bool', - 'balance' => 'float', - ], - SchemaInterface::SCHEMA => [], - SchemaInterface::RELATIONS => [], - SchemaInterface::SCOPE => SortByIDScope::class, - ], - UserWithUUIDPrimaryKey::class => [ - SchemaInterface::ROLE => 'user_with_uuid_primary_key', - SchemaInterface::MAPPER => Mapper::class, - SchemaInterface::DATABASE => 'default', - SchemaInterface::TABLE => 'user_with_uuid_primary_key', - SchemaInterface::PRIMARY_KEY => 'uuid', - SchemaInterface::COLUMNS => ['uuid', 'email', 'balance'], - SchemaInterface::TYPECAST => [ - 'uuid' => [UuidPrimaryKey::class, 'typecast'], - ], - SchemaInterface::SCHEMA => [], - SchemaInterface::RELATIONS => [], - ], - ])); - } - public function testFetchAll(): void { $selector = new Select($this->orm, User::class); @@ -200,7 +139,7 @@ public function testHeap(): void 'active' => true, 'balance' => 100.0, ], - $this->orm->getHeap()->get($result)->getData() + $this->orm->getHeap()->get($result)->getData(), ); } @@ -295,4 +234,65 @@ public function testRepositoryFindOneWithWhere(): void $this->assertSame('another@world.com', $result->email); $this->assertSame(200.0, $result->balance); } + + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('user', [ + 'id' => 'primary', + 'active' => 'bool', + 'email' => 'string', + 'balance' => 'float', + ]); + + $this->makeTable( + 'user_with_uuid_primary_key', + [ + 'uuid' => 'string(36),primary', + 'email' => 'string', + 'balance' => 'float', + ], + ); + + $this->getDatabase()->table('user')->insertMultiple( + ['email', 'active', 'balance'], + [ + ['hello@world.com', true, 100], + ['another@world.com', false, 200], + ], + ); + + $this->orm = $this->withSchema(new Schema([ + User::class => [ + SchemaInterface::ROLE => 'user', + SchemaInterface::MAPPER => Mapper::class, + SchemaInterface::DATABASE => 'default', + SchemaInterface::TABLE => 'user', + SchemaInterface::PRIMARY_KEY => 'id', + SchemaInterface::COLUMNS => ['id', 'email', 'active', 'balance'], + SchemaInterface::TYPECAST => [ + 'id' => 'int', + 'active' => 'bool', + 'balance' => 'float', + ], + SchemaInterface::SCHEMA => [], + SchemaInterface::RELATIONS => [], + SchemaInterface::SCOPE => SortByIDScope::class, + ], + UserWithUUIDPrimaryKey::class => [ + SchemaInterface::ROLE => 'user_with_uuid_primary_key', + SchemaInterface::MAPPER => Mapper::class, + SchemaInterface::DATABASE => 'default', + SchemaInterface::TABLE => 'user_with_uuid_primary_key', + SchemaInterface::PRIMARY_KEY => 'uuid', + SchemaInterface::COLUMNS => ['uuid', 'email', 'balance'], + SchemaInterface::TYPECAST => [ + 'uuid' => [UuidPrimaryKey::class, 'typecast'], + ], + SchemaInterface::SCHEMA => [], + SchemaInterface::RELATIONS => [], + ], + ])); + } } diff --git a/tests/ORM/Functional/Driver/Common/Schema/CompositePKTest.php b/tests/ORM/Functional/Driver/Common/Schema/CompositePKTest.php index 4584daa5..ad5d8b39 100644 --- a/tests/ORM/Functional/Driver/Common/Schema/CompositePKTest.php +++ b/tests/ORM/Functional/Driver/Common/Schema/CompositePKTest.php @@ -243,7 +243,7 @@ protected function createTable1(): void 'field1' => 'bigInteger,primary', 'field2' => 'bigInteger,primary', 'field3' => 'integer,nullable', - ] + ], ); $this->orm = $this->withSchema(new Schema([ diff --git a/tests/ORM/Functional/Driver/Common/Schema/FollowupTest.php b/tests/ORM/Functional/Driver/Common/Schema/FollowupTest.php index 661b3c7e..1ee9d65d 100644 --- a/tests/ORM/Functional/Driver/Common/Schema/FollowupTest.php +++ b/tests/ORM/Functional/Driver/Common/Schema/FollowupTest.php @@ -14,39 +14,6 @@ abstract class FollowupTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('user', [ - 'id' => 'primary', - 'email' => 'string', - 'balance' => 'float', - ]); - - $this->makeTable('user_snapshots', [ - 'id' => 'primary', - 'user_id' => 'int', - 'at' => 'datetime', - 'action' => 'string', - 'email' => 'string', - 'balance' => 'float', - ]); - - $this->orm = $this->withSchema(new Schema([ - User::class => [ - Schema::ROLE => 'user', - Schema::MAPPER => UserSnapshotMapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'user', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'email', 'balance'], - Schema::SCHEMA => [], - Schema::RELATIONS => [], - ], - ])); - } - public function testSnapUser(): void { $u = new User(); @@ -87,14 +54,47 @@ public function testSnapAgain(): void $this->assertSame('new-email', $snap['email']); } + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('user', [ + 'id' => 'primary', + 'email' => 'string', + 'balance' => 'float', + ]); + + $this->makeTable('user_snapshots', [ + 'id' => 'primary', + 'user_id' => 'int', + 'at' => 'datetime', + 'action' => 'string', + 'email' => 'string', + 'balance' => 'float', + ]); + + $this->orm = $this->withSchema(new Schema([ + User::class => [ + Schema::ROLE => 'user', + Schema::MAPPER => UserSnapshotMapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'user', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'email', 'balance'], + Schema::SCHEMA => [], + Schema::RELATIONS => [], + ], + ])); + } + protected function getSnap(User $u): array { return $this->dbal->database() - ->table('user_snapshots') - ->select('*') - ->where('user_id', $u->id) - ->orderBy('id', 'DESC') - ->limit(1) - ->fetchAll()[0]; + ->table('user_snapshots') + ->select('*') + ->where('user_id', $u->id) + ->orderBy('id', 'DESC') + ->limit(1) + ->fetchAll()[0]; } } diff --git a/tests/ORM/Functional/Driver/Common/Schema/TableRendererTest.php b/tests/ORM/Functional/Driver/Common/Schema/TableRendererTest.php index 8a24670b..c60b24c7 100644 --- a/tests/ORM/Functional/Driver/Common/Schema/TableRendererTest.php +++ b/tests/ORM/Functional/Driver/Common/Schema/TableRendererTest.php @@ -24,7 +24,7 @@ public function testRenderString(): void ], [ 'name' => 'default', - ] + ], ); $table = $this->reload($table); @@ -50,7 +50,7 @@ public function testRenderStringNullDefault(): void ], [ 'name' => null, - ] + ], ); $table = $this->reload($table); @@ -74,7 +74,7 @@ public function testRenderStringNullDeclared(): void 'id' => 'primary', 'name' => 'string,null', ], - [] + [], ); $table = $this->reload($table); @@ -97,7 +97,7 @@ public function testRenderStringNullableDeclared(): void 'id' => 'primary', 'name' => 'string,nullable', ], - [] + [], ); $table = $this->reload($table); @@ -120,7 +120,7 @@ public function testRenderEnum(): void 'id' => 'primary', 'name' => 'enum(active,disabled)', ], - [] + [], ); $table = $this->reload($table); @@ -148,7 +148,7 @@ public function testRenderEnumNullDefault(): void ], [ 'name' => null, - ] + ], ); $table = $this->reload($table); @@ -176,7 +176,7 @@ public function testRenderEnumNullSecond(): void ], [ 'name' => 'disabled', - ] + ], ); $table = $this->reload($table); @@ -203,7 +203,7 @@ public function testRenderBadDeclaration(): void [ 'column' => '~', ], - [] + [], ); } @@ -219,7 +219,7 @@ public function testRenderBadDeclaration2(): void [ 'column' => 'enum(a', ], - [] + [], ); } @@ -235,15 +235,10 @@ public function testRenderBadDeclaration3(): void [ 'column' => 'master', ], - [] + [], ); } - /** - * @param AbstractTable $table - * - * @return AbstractTable - */ private function reload(AbstractTable $table): AbstractTable { $table->save(); diff --git a/tests/ORM/Functional/Driver/Common/Select/CustomRepositoryTest.php b/tests/ORM/Functional/Driver/Common/Select/CustomRepositoryTest.php index 5aba7b01..933db8f8 100644 --- a/tests/ORM/Functional/Driver/Common/Select/CustomRepositoryTest.php +++ b/tests/ORM/Functional/Driver/Common/Select/CustomRepositoryTest.php @@ -16,39 +16,6 @@ abstract class CustomRepositoryTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('user', [ - 'id' => 'primary', - 'email' => 'string', - 'balance' => 'float', - ]); - - $this->getDatabase()->table('user')->insertMultiple( - ['email', 'balance'], - [ - ['hello@world.com', 100], - ['another@world.com', 200], - ] - ); - - $this->orm = $this->withSchema(new Schema([ - User::class => [ - Schema::ROLE => 'user', - Schema::MAPPER => Mapper::class, - Schema::REPOSITORY => UserRepository::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'user', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'email', 'balance'], - Schema::SCHEMA => [], - Schema::RELATIONS => [], - ], - ])); - } - public function testFindAll(): void { $r = $this->orm->getRepository(User::class); @@ -157,4 +124,37 @@ public function testFindImmutable(): void $this->assertEquals('another@world.com', $result[1]->email); $this->assertEquals(200.0, $result[1]->balance); } + + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('user', [ + 'id' => 'primary', + 'email' => 'string', + 'balance' => 'float', + ]); + + $this->getDatabase()->table('user')->insertMultiple( + ['email', 'balance'], + [ + ['hello@world.com', 100], + ['another@world.com', 200], + ], + ); + + $this->orm = $this->withSchema(new Schema([ + User::class => [ + Schema::ROLE => 'user', + Schema::MAPPER => Mapper::class, + Schema::REPOSITORY => UserRepository::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'user', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'email', 'balance'], + Schema::SCHEMA => [], + Schema::RELATIONS => [], + ], + ])); + } } diff --git a/tests/ORM/Functional/Driver/Common/Select/JsonMethodsTest.php b/tests/ORM/Functional/Driver/Common/Select/JsonMethodsTest.php index 15a0a4d1..35f6473d 100644 --- a/tests/ORM/Functional/Driver/Common/Select/JsonMethodsTest.php +++ b/tests/ORM/Functional/Driver/Common/Select/JsonMethodsTest.php @@ -17,55 +17,6 @@ abstract class JsonMethodsTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('users', ['id' => 'primary', 'user_settings' => 'json,nullable']); - $this->makeTable('posts', ['id' => 'primary', 'title' => 'string', 'user_id' => 'integer']); - - $this->getDatabase()->table('users')->insertMultiple( - ['user_settings'], - [[\json_encode(['theme' => 'dark', 'foo' => ['bar', 'baz']])], [\json_encode(['theme' => 'light'])]] - ); - $this->getDatabase()->table('posts')->insertMultiple(['title', 'user_id'], [['Post 1', 1], ['Post 2', 2]]); - - $this->orm = $this->withSchema(new Schema([ - User::class => [ - Schema::ROLE => 'user', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'users', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id' => 'id', 'settings' => 'user_settings'], - Schema::SCHEMA => [], - Schema::TYPECAST => ['id' => 'int', 'settings' => 'json'], - Schema::RELATIONS => [], - ], - Post::class => [ - Schema::ROLE => 'post', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'posts', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'title', 'user_id'], - Schema::SCHEMA => [], - Schema::TYPECAST => ['id' => 'int'], - Schema::RELATIONS => [ - 'user' => [ - Relation::TYPE => Relation::BELONGS_TO, - Relation::TARGET => 'user', - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::INNER_KEY => 'user_id', - Relation::OUTER_KEY => 'id', - ], - ], - ], - ], - ])); - } - public function testWhereJson(): void { $selector = new Select($this->orm, User::class); @@ -317,4 +268,53 @@ public function testOrWhereJsonLengthWithRelation(): void $this->assertSame(1, $post->id); $this->assertEquals(['theme' => 'dark', 'foo' => ['bar', 'baz']], $post->user->settings); } + + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('users', ['id' => 'primary', 'user_settings' => 'json,nullable']); + $this->makeTable('posts', ['id' => 'primary', 'title' => 'string', 'user_id' => 'integer']); + + $this->getDatabase()->table('users')->insertMultiple( + ['user_settings'], + [[\json_encode(['theme' => 'dark', 'foo' => ['bar', 'baz']])], [\json_encode(['theme' => 'light'])]], + ); + $this->getDatabase()->table('posts')->insertMultiple(['title', 'user_id'], [['Post 1', 1], ['Post 2', 2]]); + + $this->orm = $this->withSchema(new Schema([ + User::class => [ + Schema::ROLE => 'user', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'users', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id' => 'id', 'settings' => 'user_settings'], + Schema::SCHEMA => [], + Schema::TYPECAST => ['id' => 'int', 'settings' => 'json'], + Schema::RELATIONS => [], + ], + Post::class => [ + Schema::ROLE => 'post', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'posts', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'title', 'user_id'], + Schema::SCHEMA => [], + Schema::TYPECAST => ['id' => 'int'], + Schema::RELATIONS => [ + 'user' => [ + Relation::TYPE => Relation::BELONGS_TO, + Relation::TARGET => 'user', + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::INNER_KEY => 'user_id', + Relation::OUTER_KEY => 'id', + ], + ], + ], + ], + ])); + } } diff --git a/tests/ORM/Functional/Driver/Common/Select/PaginateTest.php b/tests/ORM/Functional/Driver/Common/Select/PaginateTest.php index 6beb4c1d..3be6be53 100644 --- a/tests/ORM/Functional/Driver/Common/Select/PaginateTest.php +++ b/tests/ORM/Functional/Driver/Common/Select/PaginateTest.php @@ -16,6 +16,22 @@ abstract class PaginateTest extends BaseTest { use TableTrait; + public function testFetchData(): void + { + $selector = new Select($this->orm, User::class); + + $this->assertSame(100, $selector->count()); + } + + public function testPaginate(): void + { + $selector = new Select($this->orm, User::class); + + (new Paginator(10))->paginate($selector); + + $this->assertCount(10, $selector->fetchData()); + } + public function setUp(): void { parent::setUp(); @@ -45,20 +61,4 @@ public function setUp(): void ], ])); } - - public function testFetchData(): void - { - $selector = new Select($this->orm, User::class); - - $this->assertSame(100, $selector->count()); - } - - public function testPaginate(): void - { - $selector = new Select($this->orm, User::class); - - (new Paginator(10))->paginate($selector); - - $this->assertCount(10, $selector->fetchData()); - } } diff --git a/tests/ORM/Functional/Driver/Common/Select/PersistRepositoryTest.php b/tests/ORM/Functional/Driver/Common/Select/PersistRepositoryTest.php index d129b077..b196c271 100644 --- a/tests/ORM/Functional/Driver/Common/Select/PersistRepositoryTest.php +++ b/tests/ORM/Functional/Driver/Common/Select/PersistRepositoryTest.php @@ -15,6 +15,23 @@ abstract class PersistRepositoryTest extends BaseTest { use TableTrait; + public function testPersist(): void + { + /** @var UserPersistRepository $users */ + $users = $this->orm->getRepository(User::class); + + + $u = new User(); + $u->email = 'test@email.com'; + $u->balance = 1000; + + $this->assertNull($u->id); + + $users->save($u); + + $this->assertNotNull($u->id); + } + public function setUp(): void { parent::setUp(); @@ -30,7 +47,7 @@ public function setUp(): void [ ['hello@world.com', 100], ['another@world.com', 200], - ] + ], ); $this->orm = $this->withSchema(new Schema([ @@ -46,21 +63,4 @@ public function setUp(): void ], ])); } - - public function testPersist(): void - { - /** @var UserPersistRepository $users */ - $users = $this->orm->getRepository(User::class); - - - $u = new User(); - $u->email = 'test@email.com'; - $u->balance = 1000; - - $this->assertNull($u->id); - - $users->save($u); - - $this->assertNotNull($u->id); - } } diff --git a/tests/ORM/Functional/Driver/Common/Select/QueryBuilderTest.php b/tests/ORM/Functional/Driver/Common/Select/QueryBuilderTest.php index 07fc6921..ddc621be 100644 --- a/tests/ORM/Functional/Driver/Common/Select/QueryBuilderTest.php +++ b/tests/ORM/Functional/Driver/Common/Select/QueryBuilderTest.php @@ -19,85 +19,6 @@ abstract class QueryBuilderTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('user', [ - 'id_int' => 'primary', - 'email_str' => 'string', - 'balance_float' => 'float', - ]); - - $this->makeTable('comment', [ - 'id_int' => 'primary', - 'user_id_int' => 'integer', - 'message_str' => 'string', - ]); - - $this->makeFK('comment', 'user_id_int', 'user', 'id_int'); - - $this->getDatabase()->table('user')->insertMultiple( - ['email_str', 'balance_float'], - [ - ['hello@world.com', 100], - ['another@world.com', 200], - ] - ); - - $this->getDatabase()->table('comment')->insertMultiple( - ['user_id_int', 'message_str'], - [ - [1, 'msg 1'], - [1, 'msg 2'], - [2, 'msg 3'], - ] - ); - - $this->orm = $this->withSchema(new Schema([ - User::class => [ - Schema::ROLE => 'user', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'user', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id' => 'id_int', 'email' => 'email_str', 'balance' => 'balance_float'], - Schema::SCHEMA => [], - Schema::TYPECAST => [ - 'id' => 'int', - 'active' => 'bool', - 'balance' => 'float', - ], - Schema::RELATIONS => [ - 'comments' => [ - Relation::TYPE => Relation::HAS_MANY, - Relation::TARGET => Comment::class, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::INNER_KEY => 'id', - Relation::OUTER_KEY => 'user_id', - ], - ], - ], - ], - Comment::class => [ - Schema::ROLE => 'comment', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'comment', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id' => 'id_int', 'user_id' => 'user_id_int', 'message' => 'message_str'], - Schema::TYPECAST => [ - 'id' => 'int', - 'user_id' => 'int', - ], - Schema::SCHEMA => [], - Schema::RELATIONS => [], - Schema::SCOPE => SortByIDScope::class, - ], - ])); - } - public function testFetchRelation(): void { $selector = new Select($this->orm, User::class); @@ -569,4 +490,83 @@ public function testLoadRelationsBuilderMultipleInload(): void $this->assertCount(1, $b->comments); $this->assertSame('msg 3', $b->comments[0]->message); } + + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('user', [ + 'id_int' => 'primary', + 'email_str' => 'string', + 'balance_float' => 'float', + ]); + + $this->makeTable('comment', [ + 'id_int' => 'primary', + 'user_id_int' => 'integer', + 'message_str' => 'string', + ]); + + $this->makeFK('comment', 'user_id_int', 'user', 'id_int'); + + $this->getDatabase()->table('user')->insertMultiple( + ['email_str', 'balance_float'], + [ + ['hello@world.com', 100], + ['another@world.com', 200], + ], + ); + + $this->getDatabase()->table('comment')->insertMultiple( + ['user_id_int', 'message_str'], + [ + [1, 'msg 1'], + [1, 'msg 2'], + [2, 'msg 3'], + ], + ); + + $this->orm = $this->withSchema(new Schema([ + User::class => [ + Schema::ROLE => 'user', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'user', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id' => 'id_int', 'email' => 'email_str', 'balance' => 'balance_float'], + Schema::SCHEMA => [], + Schema::TYPECAST => [ + 'id' => 'int', + 'active' => 'bool', + 'balance' => 'float', + ], + Schema::RELATIONS => [ + 'comments' => [ + Relation::TYPE => Relation::HAS_MANY, + Relation::TARGET => Comment::class, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::INNER_KEY => 'id', + Relation::OUTER_KEY => 'user_id', + ], + ], + ], + ], + Comment::class => [ + Schema::ROLE => 'comment', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'comment', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id' => 'id_int', 'user_id' => 'user_id_int', 'message' => 'message_str'], + Schema::TYPECAST => [ + 'id' => 'int', + 'user_id' => 'int', + ], + Schema::SCHEMA => [], + Schema::RELATIONS => [], + Schema::SCOPE => SortByIDScope::class, + ], + ])); + } } diff --git a/tests/ORM/Functional/Driver/Common/Select/RepositoryTest.php b/tests/ORM/Functional/Driver/Common/Select/RepositoryTest.php index abe66b86..9b474f03 100644 --- a/tests/ORM/Functional/Driver/Common/Select/RepositoryTest.php +++ b/tests/ORM/Functional/Driver/Common/Select/RepositoryTest.php @@ -15,38 +15,6 @@ abstract class RepositoryTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('user', [ - 'id' => 'primary', - 'email' => 'string', - 'balance' => 'float', - ]); - - $this->getDatabase()->table('user')->insertMultiple( - ['email', 'balance'], - [ - ['hello@world.com', 100], - ['another@world.com', 200], - ] - ); - - $this->orm = $this->withSchema(new Schema([ - User::class => [ - Schema::ROLE => 'user', - Schema::MAPPER => Mapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'user', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'email', 'balance'], - Schema::SCHEMA => [], - Schema::RELATIONS => [], - ], - ])); - } - public function testFindAll(): void { $r = $this->orm->getRepository(User::class); @@ -144,4 +112,36 @@ public function testFindImmutable(): void $this->assertEquals('another@world.com', $result[1]->email); $this->assertEquals(200.0, $result[1]->balance); } + + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('user', [ + 'id' => 'primary', + 'email' => 'string', + 'balance' => 'float', + ]); + + $this->getDatabase()->table('user')->insertMultiple( + ['email', 'balance'], + [ + ['hello@world.com', 100], + ['another@world.com', 200], + ], + ); + + $this->orm = $this->withSchema(new Schema([ + User::class => [ + Schema::ROLE => 'user', + Schema::MAPPER => Mapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'user', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'email', 'balance'], + Schema::SCHEMA => [], + Schema::RELATIONS => [], + ], + ])); + } } diff --git a/tests/ORM/Functional/Driver/Common/SelectorTest.php b/tests/ORM/Functional/Driver/Common/SelectorTest.php index 479fd549..a1021f22 100644 --- a/tests/ORM/Functional/Driver/Common/SelectorTest.php +++ b/tests/ORM/Functional/Driver/Common/SelectorTest.php @@ -17,6 +17,44 @@ abstract class SelectorTest extends BaseTest { use TableTrait; + public function testStableStatement(): void + { + $s = new Select($this->orm, User::class); + $s->load('comments', ['method' => JoinableLoader::INLOAD]); + + $s2 = new Select($this->orm, User::class); + $s2->load('comments', ['method' => JoinableLoader::INLOAD]); + + $this->assertSQL($s->sqlStatement(), $s2->sqlStatement()); + } + + public function testSelectCustomSQL(): void + { + $s = new Select($this->orm, User::class); + $s->with('comments', ['method' => JoinableLoader::INLOAD]); + + $query = $s->buildQuery()->columns( + 'user.id', + 'SUM(user.balance) as balance', + 'COUNT(user_comments.id) as count_comments', + )->groupBy('user.id')->orderBy('user.id'); + + $result = $query->fetchAll(); + + $this->assertEquals([ + [ + 'id' => 1, + 'balance' => 400.0, + 'count_comments' => 4, + ], + [ + 'id' => 2, + 'balance' => 600.0, + 'count_comments' => 3, + ], + ], $result); + } + public function setUp(): void { parent::setUp(); @@ -32,7 +70,7 @@ public function setUp(): void [ ['hello@world.com', 100], ['another@world.com', 200], - ] + ], ); $this->makeTable('comment', [ @@ -52,7 +90,7 @@ public function setUp(): void [2, 1, 'msg 2.1'], [2, 2, 'msg 2.2'], [2, 3, 'msg 2.3'], - ] + ], ); $this->orm = $this->withSchema(new Schema([ @@ -88,42 +126,4 @@ public function setUp(): void ], ])); } - - public function testStableStatement(): void - { - $s = new Select($this->orm, User::class); - $s->load('comments', ['method' => JoinableLoader::INLOAD]); - - $s2 = new Select($this->orm, User::class); - $s2->load('comments', ['method' => JoinableLoader::INLOAD]); - - $this->assertSQL($s->sqlStatement(), $s2->sqlStatement()); - } - - public function testSelectCustomSQL(): void - { - $s = new Select($this->orm, User::class); - $s->with('comments', ['method' => JoinableLoader::INLOAD]); - - $query = $s->buildQuery()->columns( - 'user.id', - 'SUM(user.balance) as balance', - 'COUNT(user_comments.id) as count_comments' - )->groupBy('user.id')->orderBy('user.id'); - - $result = $query->fetchAll(); - - $this->assertEquals([ - [ - 'id' => 1, - 'balance' => 400.0, - 'count_comments' => 4, - ], - [ - 'id' => 2, - 'balance' => 600.0, - 'count_comments' => 3, - ], - ], $result); - } } diff --git a/tests/ORM/Functional/Driver/Common/Transaction/OptimisticLockTest.php b/tests/ORM/Functional/Driver/Common/Transaction/OptimisticLockTest.php index e898711d..b0677892 100644 --- a/tests/ORM/Functional/Driver/Common/Transaction/OptimisticLockTest.php +++ b/tests/ORM/Functional/Driver/Common/Transaction/OptimisticLockTest.php @@ -16,31 +16,6 @@ abstract class OptimisticLockTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('post', [ - 'id' => 'primary', - 'title' => 'string', - 'content' => 'string', - 'lock' => 'string', - ]); - - $this->orm = $this->withSchema(new Schema([ - Post::class => [ - SchemaInterface::ROLE => 'post', - SchemaInterface::MAPPER => OptimisticLockMapper::class, - SchemaInterface::DATABASE => 'default', - SchemaInterface::TABLE => 'post', - SchemaInterface::PRIMARY_KEY => 'id', - SchemaInterface::COLUMNS => ['id', 'title', 'content', 'lock'], - SchemaInterface::SCHEMA => [], - SchemaInterface::RELATIONS => [], - ], - ])); - } - /** * Check the mapper works fine in a normal create and update cases */ @@ -120,4 +95,29 @@ public function testCreateAndDeleteLocked(): void $this->orm->getHeap()->clean(); } } + + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('post', [ + 'id' => 'primary', + 'title' => 'string', + 'content' => 'string', + 'lock' => 'string', + ]); + + $this->orm = $this->withSchema(new Schema([ + Post::class => [ + SchemaInterface::ROLE => 'post', + SchemaInterface::MAPPER => OptimisticLockMapper::class, + SchemaInterface::DATABASE => 'default', + SchemaInterface::TABLE => 'post', + SchemaInterface::PRIMARY_KEY => 'id', + SchemaInterface::COLUMNS => ['id', 'title', 'content', 'lock'], + SchemaInterface::SCHEMA => [], + SchemaInterface::RELATIONS => [], + ], + ])); + } } diff --git a/tests/ORM/Functional/Driver/Common/Transaction/RunnerTest.php b/tests/ORM/Functional/Driver/Common/Transaction/RunnerTest.php index 7e60289e..90ba63a3 100644 --- a/tests/ORM/Functional/Driver/Common/Transaction/RunnerTest.php +++ b/tests/ORM/Functional/Driver/Common/Transaction/RunnerTest.php @@ -14,11 +14,6 @@ abstract class RunnerTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - } - // Mode OPEN_TRANSACTION public function testInnerTransactionRun(): void @@ -140,4 +135,9 @@ public function testIgnoreTransactionRollback(): void $this->assertSame(1, $this->getDriver()->getTransactionLevel()); } + + public function setUp(): void + { + parent::setUp(); + } } diff --git a/tests/ORM/Functional/Driver/Common/Transaction/UnitOfWorkTest.php b/tests/ORM/Functional/Driver/Common/Transaction/UnitOfWorkTest.php index 55774677..df657984 100644 --- a/tests/ORM/Functional/Driver/Common/Transaction/UnitOfWorkTest.php +++ b/tests/ORM/Functional/Driver/Common/Transaction/UnitOfWorkTest.php @@ -22,30 +22,6 @@ abstract class UnitOfWorkTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('post', [ - 'id' => 'primary', - 'title' => 'string', - 'content' => 'string', - ]); - - $this->orm = $this->withSchema(new Schema([ - Post::class => [ - SchemaInterface::ROLE => 'post', - SchemaInterface::MAPPER => Mapper::class, - SchemaInterface::DATABASE => 'default', - SchemaInterface::TABLE => 'post', - SchemaInterface::PRIMARY_KEY => 'id', - SchemaInterface::COLUMNS => ['id', 'title', 'content'], - SchemaInterface::SCHEMA => [], - SchemaInterface::RELATIONS => [], - ], - ])); - } - public function testSuccessRetry(): void { $eow = new UnitOfWork($this->orm, Runner::outerTransaction()); @@ -193,7 +169,7 @@ public function testWithoutTransactionNotChanged(): void // Node outside the transaction - the state not changed $this->assertSame( ['title' => 'Title2', 'content' => 'Test2'], - $this->orm->getHeap()->get($post2)->getState()->getData() + $this->orm->getHeap()->get($post2)->getState()->getData(), ); } @@ -222,4 +198,28 @@ public function testCallSuccessRetryException(): void $this->expectException(SuccessTransactionRetryException::class); $result->retry(); } + + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('post', [ + 'id' => 'primary', + 'title' => 'string', + 'content' => 'string', + ]); + + $this->orm = $this->withSchema(new Schema([ + Post::class => [ + SchemaInterface::ROLE => 'post', + SchemaInterface::MAPPER => Mapper::class, + SchemaInterface::DATABASE => 'default', + SchemaInterface::TABLE => 'post', + SchemaInterface::PRIMARY_KEY => 'id', + SchemaInterface::COLUMNS => ['id', 'title', 'content'], + SchemaInterface::SCHEMA => [], + SchemaInterface::RELATIONS => [], + ], + ])); + } } diff --git a/tests/ORM/Functional/Driver/Common/TransactionTest.php b/tests/ORM/Functional/Driver/Common/TransactionTest.php index d91b8323..e2d29d4e 100644 --- a/tests/ORM/Functional/Driver/Common/TransactionTest.php +++ b/tests/ORM/Functional/Driver/Common/TransactionTest.php @@ -16,37 +16,6 @@ abstract class TransactionTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('user', ['id' => 'primary', 'email' => 'string', 'balance' => 'float',]); - $this->getDatabase()->table('user')->insertMultiple( - ['email', 'balance'], - [ - ['hello@world.com', 100], - ['another@world.com', 200], - ['test@world.com', 300], - ] - ); - - $this->orm = $this->withSchema( - new Schema([ - User::class => [ - Schema::ROLE => 'user', - Schema::MAPPER => TransactionTestMapper::class, - Schema::DATABASE => 'default', - Schema::TABLE => 'user', - Schema::PRIMARY_KEY => 'id', - Schema::COLUMNS => ['id', 'email', 'balance'], - Schema::TYPECAST => ['id' => 'int', 'balance' => 'int'], - Schema::SCHEMA => [], - Schema::RELATIONS => [], - ], - ]) - ); - } - public function testTransactionRollbackShouldResetEntityState() { $t = new Transaction($this->orm); @@ -170,7 +139,7 @@ public function testRollbackDatabaseTransactionDuringRunORMTransaction() $this->assertSame( 150, - (new Select($this->orm->withHeap(new Heap()), User::class))->wherePK(1)->fetchOne()->balance + (new Select($this->orm->withHeap(new Heap()), User::class))->wherePK(1)->fetchOne()->balance, ); // For user with ID 3 Mapper should throw an exception @@ -234,4 +203,35 @@ public function testCommitDatabaseTransactionAfterORMTransaction() $this->assertNull((new Select($this->orm, User::class))->wherePK(2)->fetchOne()); $this->assertSame(350, (new Select($this->orm, User::class))->wherePK($newU->id)->fetchOne()->balance); } + + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('user', ['id' => 'primary', 'email' => 'string', 'balance' => 'float',]); + $this->getDatabase()->table('user')->insertMultiple( + ['email', 'balance'], + [ + ['hello@world.com', 100], + ['another@world.com', 200], + ['test@world.com', 300], + ], + ); + + $this->orm = $this->withSchema( + new Schema([ + User::class => [ + Schema::ROLE => 'user', + Schema::MAPPER => TransactionTestMapper::class, + Schema::DATABASE => 'default', + Schema::TABLE => 'user', + Schema::PRIMARY_KEY => 'id', + Schema::COLUMNS => ['id', 'email', 'balance'], + Schema::TYPECAST => ['id' => 'int', 'balance' => 'int'], + Schema::SCHEMA => [], + Schema::RELATIONS => [], + ], + ]), + ); + } } diff --git a/tests/ORM/Functional/Driver/Common/Typecast/DatetimeTest.php b/tests/ORM/Functional/Driver/Common/Typecast/DatetimeTest.php index 42833fa0..a717e251 100644 --- a/tests/ORM/Functional/Driver/Common/Typecast/DatetimeTest.php +++ b/tests/ORM/Functional/Driver/Common/Typecast/DatetimeTest.php @@ -34,46 +34,6 @@ abstract class DatetimeTest extends BaseTest */ protected $b; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('user', [ - 'id' => 'primary', - 'email' => 'string', - 'time_created' => 'datetime', - 'balance' => 'float', - ]); - - $this->now = new \DateTimeImmutable('now', new \DateTimeZone('Europe/Minsk')); - - $this->getDatabase()->table('user')->insertMultiple( - ['email', 'time_created', 'balance'], - [ - ['hello@world.com', $this->a = $this->now->add(new \DateInterval('PT1H')), 100], - ['another@world.com', $this->b = $this->now->add(new \DateInterval('PT2H')), 200], - ] - ); - - $this->orm = $this->withSchema(new Schema([ - User::class => [ - SchemaInterface::ROLE => 'user', - SchemaInterface::MAPPER => Mapper::class, - SchemaInterface::DATABASE => 'default', - SchemaInterface::TABLE => 'user', - SchemaInterface::PRIMARY_KEY => 'id', - SchemaInterface::COLUMNS => ['id', 'email', 'time_created', 'balance'], - SchemaInterface::TYPECAST => [ - 'id' => 'int', - 'balance' => 'float', - 'time_created' => 'datetime', - ], - SchemaInterface::SCHEMA => [], - SchemaInterface::RELATIONS => [], - ], - ])); - } - public function testFetchAll(): void { $selector = new Select($this->orm, User::class); @@ -167,11 +127,46 @@ public function testUpdate(): void $this->assertSameTimestamp($e->time_created, $result->time_created, 0); } - /** - * @param \DateTimeInterface $a - * @param \DateTimeInterface $b - * @param int $max - */ + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('user', [ + 'id' => 'primary', + 'email' => 'string', + 'time_created' => 'datetime', + 'balance' => 'float', + ]); + + $this->now = new \DateTimeImmutable('now', new \DateTimeZone('Europe/Minsk')); + + $this->getDatabase()->table('user')->insertMultiple( + ['email', 'time_created', 'balance'], + [ + ['hello@world.com', $this->a = $this->now->add(new \DateInterval('PT1H')), 100], + ['another@world.com', $this->b = $this->now->add(new \DateInterval('PT2H')), 200], + ], + ); + + $this->orm = $this->withSchema(new Schema([ + User::class => [ + SchemaInterface::ROLE => 'user', + SchemaInterface::MAPPER => Mapper::class, + SchemaInterface::DATABASE => 'default', + SchemaInterface::TABLE => 'user', + SchemaInterface::PRIMARY_KEY => 'id', + SchemaInterface::COLUMNS => ['id', 'email', 'time_created', 'balance'], + SchemaInterface::TYPECAST => [ + 'id' => 'int', + 'balance' => 'float', + 'time_created' => 'datetime', + ], + SchemaInterface::SCHEMA => [], + SchemaInterface::RELATIONS => [], + ], + ])); + } + protected function assertSameTimestamp(\DateTimeInterface $a, \DateTimeInterface $b, int $max): void { $diff = abs($a->getTimestamp() - $b->getTimestamp()); diff --git a/tests/ORM/Functional/Driver/Common/Typecast/Fixture/Book.php b/tests/ORM/Functional/Driver/Common/Typecast/Fixture/Book.php index a79abdb7..077e2343 100644 --- a/tests/ORM/Functional/Driver/Common/Typecast/Fixture/Book.php +++ b/tests/ORM/Functional/Driver/Common/Typecast/Fixture/Book.php @@ -4,24 +4,18 @@ namespace Cycle\ORM\Tests\Functional\Driver\Common\Typecast\Fixture; -use DateTimeImmutable; -use DateTimeInterface; - class Book { public ?int $id = null; public ?int $user_id = null; - public BookStates $states; - public BookNestedStates $nested_states; + public \DateTimeInterface $published_at; - public DateTimeInterface $published_at; - - public function __construct(?DateTimeInterface $publishedAt = null) + public function __construct(?\DateTimeInterface $publishedAt = null) { $this->states = new BookStates(); $this->nested_states = new BookNestedStates(); - $this->published_at = $publishedAt instanceof DateTimeInterface ? $publishedAt : new DateTimeImmutable(); + $this->published_at = $publishedAt instanceof \DateTimeInterface ? $publishedAt : new \DateTimeImmutable(); } } diff --git a/tests/ORM/Functional/Driver/Common/Typecast/Fixture/BookNestedStates.php b/tests/ORM/Functional/Driver/Common/Typecast/Fixture/BookNestedStates.php index cc3840b0..7fcd8617 100644 --- a/tests/ORM/Functional/Driver/Common/Typecast/Fixture/BookNestedStates.php +++ b/tests/ORM/Functional/Driver/Common/Typecast/Fixture/BookNestedStates.php @@ -14,14 +14,14 @@ public function __construct(array $states = []) $this->states = $this->create($states); } - public function __toString(): string + public static function cast(string $value): self { - return implode('|', array_column($this->states, 'title')); + return new self(explode('|', $value)); } - public static function cast(string $value): self + public function __toString(): string { - return new self(explode('|', $value)); + return implode('|', array_column($this->states, 'title')); } private function create(array $states): array diff --git a/tests/ORM/Functional/Driver/Common/Typecast/Fixture/BookStates.php b/tests/ORM/Functional/Driver/Common/Typecast/Fixture/BookStates.php index 405881b9..9b99db62 100644 --- a/tests/ORM/Functional/Driver/Common/Typecast/Fixture/BookStates.php +++ b/tests/ORM/Functional/Driver/Common/Typecast/Fixture/BookStates.php @@ -13,13 +13,13 @@ public function __construct(array $states = []) $this->states = $states; } - public function __toString(): string + public static function cast(string $value): self { - return implode('|', $this->states); + return new self(explode('|', $value)); } - public static function cast(string $value): self + public function __toString(): string { - return new self(explode('|', $value)); + return implode('|', $this->states); } } diff --git a/tests/ORM/Functional/Driver/Common/Typecast/Fixture/InvalidTypecaster.php b/tests/ORM/Functional/Driver/Common/Typecast/Fixture/InvalidTypecaster.php index 97f71135..f36e881b 100644 --- a/tests/ORM/Functional/Driver/Common/Typecast/Fixture/InvalidTypecaster.php +++ b/tests/ORM/Functional/Driver/Common/Typecast/Fixture/InvalidTypecaster.php @@ -4,6 +4,4 @@ namespace Cycle\ORM\Tests\Functional\Driver\Common\Typecast\Fixture; -final class InvalidTypecaster -{ -} +final class InvalidTypecaster {} diff --git a/tests/ORM/Functional/Driver/Common/Typecast/Fixture/JsonTypecast.php b/tests/ORM/Functional/Driver/Common/Typecast/Fixture/JsonTypecast.php index 217e0b77..18d933fd 100644 --- a/tests/ORM/Functional/Driver/Common/Typecast/Fixture/JsonTypecast.php +++ b/tests/ORM/Functional/Driver/Common/Typecast/Fixture/JsonTypecast.php @@ -45,7 +45,7 @@ public function uncast(array $data): array $data[$column] = match ($rule) { 'json' => 'uncast-json', - default => (string) $data[$column] + default => (string) $data[$column], }; } diff --git a/tests/ORM/Functional/Driver/Common/Typecast/Fixture/Typecaster.php b/tests/ORM/Functional/Driver/Common/Typecast/Fixture/Typecaster.php index 51ca5d37..efc4bd94 100644 --- a/tests/ORM/Functional/Driver/Common/Typecast/Fixture/Typecaster.php +++ b/tests/ORM/Functional/Driver/Common/Typecast/Fixture/Typecaster.php @@ -16,7 +16,7 @@ final class Typecaster implements TypecastInterface public function __construct( SchemaInterface $schema, - public string $role + public string $role, ) { // $class = $schema->define($role, SchemaInterface::ENTITY); // Some magic with reflection to prepare callables diff --git a/tests/ORM/Functional/Driver/Common/Typecast/Fixture/User.php b/tests/ORM/Functional/Driver/Common/Typecast/Fixture/User.php index 654bcff8..e935d570 100644 --- a/tests/ORM/Functional/Driver/Common/Typecast/Fixture/User.php +++ b/tests/ORM/Functional/Driver/Common/Typecast/Fixture/User.php @@ -4,13 +4,11 @@ namespace Cycle\ORM\Tests\Functional\Driver\Common\Typecast\Fixture; -use DateTimeInterface; - class User { public ?Wrapper $id = null; public string $email; public Wrapper $balance; public iterable $books = []; - public ?DateTimeInterface $created_at = null; + public ?\DateTimeInterface $created_at = null; } diff --git a/tests/ORM/Functional/Driver/Common/Typecast/Fixture/Wrapper.php b/tests/ORM/Functional/Driver/Common/Typecast/Fixture/Wrapper.php index f884e133..9a3df9a8 100644 --- a/tests/ORM/Functional/Driver/Common/Typecast/Fixture/Wrapper.php +++ b/tests/ORM/Functional/Driver/Common/Typecast/Fixture/Wrapper.php @@ -7,12 +7,11 @@ class Wrapper { public function __construct( - public mixed $value - ) { - } + public mixed $value, + ) {} public function __toString(): string { - return (string)$this->value; + return (string) $this->value; } } diff --git a/tests/ORM/Functional/Driver/Common/Typecast/JsonTest.php b/tests/ORM/Functional/Driver/Common/Typecast/JsonTest.php index d3941bff..5683965e 100644 --- a/tests/ORM/Functional/Driver/Common/Typecast/JsonTest.php +++ b/tests/ORM/Functional/Driver/Common/Typecast/JsonTest.php @@ -16,76 +16,11 @@ use Cycle\ORM\Tests\Fixtures\User; use Cycle\ORM\Tests\Functional\Driver\Common\Typecast\Fixture\JsonTypecast; use Cycle\ORM\Tests\Traits\TableTrait; -use Throwable; abstract class JsonTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable(table: 'users', columns: [ - 'id' => 'primary', - 'email' => 'string', - 'settings' => 'text', - 'settings_nullable' => 'text,nullable', - 'json_serializable' => 'text,nullable', - ], defaults: ['settings' => null, 'settings_nullable' => null, 'json_serializable' => null]); - - $this->getDatabase()->table('users')->insertOne( - [ - 'email' => 'hello@world.com', - 'settings' => \json_encode(['theme' => 'dark']), - 'settings_nullable' => null, - 'json_serializable' => null, - ], - ); - $this->getDatabase()->table('users')->insertOne( - [ - 'email' => 'another@world.com', - 'settings' => \json_encode(['grids' => ['products' => ['columns' => ['id', 'title']]]]), - 'settings_nullable' => \json_encode(['theme' => 'dark']), - 'json_serializable' => null, - ], - ); - - $mapping = [ - SchemaInterface::ROLE => 'user', - SchemaInterface::MAPPER => Mapper::class, - SchemaInterface::DATABASE => 'default', - SchemaInterface::TABLE => 'users', - SchemaInterface::PRIMARY_KEY => 'id', - SchemaInterface::COLUMNS => [ - 'id' => 'id', - 'email' => 'email', - 'settings' => 'settings', - 'settingsNullable' => 'settings_nullable', - 'jsonSerializable' => 'json_serializable', - ], - SchemaInterface::TYPECAST => [ - 'id' => 'int', - 'settings' => 'json', - 'settingsNullable' => 'json', - 'jsonSerializable' => 'json', - ], - SchemaInterface::SCHEMA => [], - SchemaInterface::RELATIONS => [], - ]; - - $this->orm = $this->withSchema(new Schema([ - User::class => $mapping, - Admin::class => [ - SchemaInterface::ROLE => 'admin', - SchemaInterface::TYPECAST_HANDLER => [ - JsonTypecast::class, - Typecast::class, - ], - ] + $mapping, - ])); - } - public function testFetchAll(): void { $selector = new Select($this->orm, User::class); @@ -144,7 +79,7 @@ public function testStore(): void } /** - * @throws Throwable + * @throws \Throwable */ public function testStoresEmptyArraySettings(): void { @@ -226,7 +161,7 @@ public function testStoreJsonSerializable(): void $result = $this->getDatabase()->table('users')->select()->where('id', $e->id)->fetchAll(); $this->assertEquals( (new JsonSerializableClass())->jsonSerialize(), - \json_decode($result[0]['json_serializable'], true) + \json_decode($result[0]['json_serializable'], true), ); } @@ -270,4 +205,68 @@ public function testOverrideTypecast(): void $result = $this->getDatabase()->table('users')->select()->where('id', $e->id)->fetchAll(); $this->assertSame('uncast-json', $result[0]['settings']); } + + public function setUp(): void + { + parent::setUp(); + + $this->makeTable(table: 'users', columns: [ + 'id' => 'primary', + 'email' => 'string', + 'settings' => 'text', + 'settings_nullable' => 'text,nullable', + 'json_serializable' => 'text,nullable', + ], defaults: ['settings' => null, 'settings_nullable' => null, 'json_serializable' => null]); + + $this->getDatabase()->table('users')->insertOne( + [ + 'email' => 'hello@world.com', + 'settings' => \json_encode(['theme' => 'dark']), + 'settings_nullable' => null, + 'json_serializable' => null, + ], + ); + $this->getDatabase()->table('users')->insertOne( + [ + 'email' => 'another@world.com', + 'settings' => \json_encode(['grids' => ['products' => ['columns' => ['id', 'title']]]]), + 'settings_nullable' => \json_encode(['theme' => 'dark']), + 'json_serializable' => null, + ], + ); + + $mapping = [ + SchemaInterface::ROLE => 'user', + SchemaInterface::MAPPER => Mapper::class, + SchemaInterface::DATABASE => 'default', + SchemaInterface::TABLE => 'users', + SchemaInterface::PRIMARY_KEY => 'id', + SchemaInterface::COLUMNS => [ + 'id' => 'id', + 'email' => 'email', + 'settings' => 'settings', + 'settingsNullable' => 'settings_nullable', + 'jsonSerializable' => 'json_serializable', + ], + SchemaInterface::TYPECAST => [ + 'id' => 'int', + 'settings' => 'json', + 'settingsNullable' => 'json', + 'jsonSerializable' => 'json', + ], + SchemaInterface::SCHEMA => [], + SchemaInterface::RELATIONS => [], + ]; + + $this->orm = $this->withSchema(new Schema([ + User::class => $mapping, + Admin::class => [ + SchemaInterface::ROLE => 'admin', + SchemaInterface::TYPECAST_HANDLER => [ + JsonTypecast::class, + Typecast::class, + ], + ] + $mapping, + ])); + } } diff --git a/tests/ORM/Functional/Driver/Common/Typecast/ObjectsCompareTest.php b/tests/ORM/Functional/Driver/Common/Typecast/ObjectsCompareTest.php index 169c66a4..a7364e2f 100644 --- a/tests/ORM/Functional/Driver/Common/Typecast/ObjectsCompareTest.php +++ b/tests/ORM/Functional/Driver/Common/Typecast/ObjectsCompareTest.php @@ -14,45 +14,12 @@ use Cycle\ORM\Tests\Functional\Driver\Common\Typecast\Fixture\BookStates; use Cycle\ORM\Tests\Functional\Driver\Common\BaseTest; use Cycle\ORM\Tests\Traits\TableTrait; -use DateInterval; -use DateTime; final class ObjectsCompareTest extends BaseTest { - public const DRIVER = 'sqlite'; - use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('book', [ - 'id' => 'primary', - 'states' => 'string', - 'nested_states' => 'string', - 'published_at' => 'datetime', - ]); - - $this->orm = $this->withSchema(new Schema([ - Book::class => [ - SchemaInterface::ROLE => 'book', - SchemaInterface::MAPPER => Mapper::class, - SchemaInterface::DATABASE => 'default', - SchemaInterface::TABLE => 'book', - SchemaInterface::PRIMARY_KEY => 'id', - SchemaInterface::COLUMNS => ['id', 'states', 'nested_states', 'published_at'], - SchemaInterface::SCHEMA => [], - SchemaInterface::TYPECAST => [ - 'id' => 'int', - 'states' => [BookStates::class, 'cast'], - 'nested_states' => [BookNestedStates::class, 'cast'], - 'published_at' => 'datetime', - ], - SchemaInterface::RELATIONS => [], - ], - ])); - } + public const DRIVER = 'sqlite'; public function testCompare(): void { @@ -110,7 +77,7 @@ public function testCompareDateTime(): void $this->orm->getHeap()->clean(); $data = (new Select($this->orm, Book::class))->fetchData(); - $data[0]['published_at'] = new DateTime(); + $data[0]['published_at'] = new \DateTime(); $fetched = $this->orm->make('book', $data[0], Node::MANAGED, typecast: false); $fetched->published_at->setDate(2010, 1, 1); @@ -129,9 +96,40 @@ public function testCompareDateTime(): void $interval = $changed->published_at->diff($fetched->published_at); - $this->assertInstanceOf(DateInterval::class, $interval); + $this->assertInstanceOf(\DateInterval::class, $interval); $this->assertSame(0, $interval->y); $this->assertSame(0, $interval->m); $this->assertSame(0, $interval->d); } + + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('book', [ + 'id' => 'primary', + 'states' => 'string', + 'nested_states' => 'string', + 'published_at' => 'datetime', + ]); + + $this->orm = $this->withSchema(new Schema([ + Book::class => [ + SchemaInterface::ROLE => 'book', + SchemaInterface::MAPPER => Mapper::class, + SchemaInterface::DATABASE => 'default', + SchemaInterface::TABLE => 'book', + SchemaInterface::PRIMARY_KEY => 'id', + SchemaInterface::COLUMNS => ['id', 'states', 'nested_states', 'published_at'], + SchemaInterface::SCHEMA => [], + SchemaInterface::TYPECAST => [ + 'id' => 'int', + 'states' => [BookStates::class, 'cast'], + 'nested_states' => [BookNestedStates::class, 'cast'], + 'published_at' => 'datetime', + ], + SchemaInterface::RELATIONS => [], + ], + ])); + } } diff --git a/tests/ORM/Functional/Driver/Common/Typecast/SchemaTest.php b/tests/ORM/Functional/Driver/Common/Typecast/SchemaTest.php index 7a5a6651..65062831 100644 --- a/tests/ORM/Functional/Driver/Common/Typecast/SchemaTest.php +++ b/tests/ORM/Functional/Driver/Common/Typecast/SchemaTest.php @@ -27,8 +27,8 @@ final class SchemaTest extends BaseTest { public const DRIVER = 'sqlite'; - private const PRIMARY_ROLE = 'book'; + private ?Container $container; public function setUpOrm(array $bookSchema = [], array $factoryDefinitions = []): void @@ -41,10 +41,10 @@ public function setUpOrm(array $bookSchema = [], array $factoryDefinitions = []) RelationConfig::getDefault(), new SimpleFactory( $factoryDefinitions, - static fn (string|object $alias, array $parameters = []): mixed => \is_string($alias) - ? $container->make($alias, $parameters) : $alias + static fn(string|object $alias, array $parameters = []): mixed => \is_string($alias) + ? $container->make($alias, $parameters) : $alias, ), - new ArrayCollectionFactory() + new ArrayCollectionFactory(), ), new Schema([ Book::class => $bookSchema + [ @@ -81,7 +81,7 @@ public function setUpOrm(array $bookSchema = [], array $factoryDefinitions = []) SchemaInterface::COLUMNS => ['id', 'baz'], SchemaInterface::TYPECAST => ['baz' => 'int'], ], - ]) + ]), ); } @@ -89,7 +89,7 @@ public function testEmptyStringShouldThrowAnException(): void { $this->expectException(FactoryTypecastException::class); $this->expectExceptionMessageMatches( - '/Bad typecast handler declaration for the `book` role./' + '/Bad typecast handler declaration for the `book` role./', ); $this->setUpOrm([ @@ -107,7 +107,7 @@ public function testHandlerWithWrongInterfaceShouldThrowAnException(): void $this->expectException(FactoryTypecastException::class); $this->expectExceptionMessage( - 'Bad typecast handler declaration for the `book` role. Cycle\ORM\Factory::makeTypecastHandler(): Return value must be of type Cycle\ORM\Parser\TypecastInterface, Cycle\ORM\Tests\Functional\Driver\Common\Typecast\Fixture\InvalidTypecaster returned' + 'Bad typecast handler declaration for the `book` role. Cycle\ORM\Factory::makeTypecastHandler(): Return value must be of type Cycle\ORM\Parser\TypecastInterface, Cycle\ORM\Tests\Functional\Driver\Common\Typecast\Fixture\InvalidTypecaster returned', ); $this->orm->getService(TypecastProviderInterface::class)->getTypecast(self::PRIMARY_ROLE); @@ -126,7 +126,7 @@ public function testHandlerWithWrongInterfaceAmongArrayShouldThrowAnException(): $this->expectException(FactoryTypecastException::class); $this->expectExceptionMessage( - 'Bad typecast handler declaration for the `book` role. Cycle\ORM\Factory::makeTypecastHandler(): Return value must be of type Cycle\ORM\Parser\TypecastInterface, Cycle\ORM\Tests\Functional\Driver\Common\Typecast\Fixture\InvalidTypecaster returned' + 'Bad typecast handler declaration for the `book` role. Cycle\ORM\Factory::makeTypecastHandler(): Return value must be of type Cycle\ORM\Parser\TypecastInterface, Cycle\ORM\Tests\Functional\Driver\Common\Typecast\Fixture\InvalidTypecaster returned', ); $this->orm->getService(TypecastProviderInterface::class)->getTypecast(self::PRIMARY_ROLE); @@ -224,7 +224,7 @@ public function testUseCompositeTypecast(): void ->willReturn(['foo' => 'bar2']); // passes to Composite typecast $this->container = new Container(); - $this->container->bindSingleton('bar-foo', fn () => $containerTypecast); + $this->container->bindSingleton('bar-foo', fn() => $containerTypecast); $this->setUpOrm([ SchemaInterface::TYPECAST_HANDLER => [ diff --git a/tests/ORM/Functional/Driver/Common/Typecast/TypecastEnumTest.php b/tests/ORM/Functional/Driver/Common/Typecast/TypecastEnumTest.php index 87cc8ad9..7b8e35fb 100644 --- a/tests/ORM/Functional/Driver/Common/Typecast/TypecastEnumTest.php +++ b/tests/ORM/Functional/Driver/Common/Typecast/TypecastEnumTest.php @@ -21,62 +21,17 @@ abstract class TypecastEnumTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable( - 'user', - [ - 'id' => 'primary', - 'balance' => 'int', - 'enum_string' => 'string', - 'enum_int' => 'int', - ] - ); - $this->getDatabase()->table('user')->insertMultiple( - ['balance', 'enum_string', 'enum_int'], - [ - [100, TypeStringEnum::Admin->value, TypeIntEnum::Admin->value], - [200, TypeStringEnum::Guest->value, TypeIntEnum::Guest->value], - ] - ); - - $this->orm = $this->withSchema( - new Schema( - [ - User::class => [ - SchemaInterface::ROLE => 'user', - SchemaInterface::MAPPER => Mapper::class, - SchemaInterface::DATABASE => 'default', - SchemaInterface::TABLE => 'user', - SchemaInterface::PRIMARY_KEY => 'id', - SchemaInterface::COLUMNS => ['id', 'balance', 'enum_string', 'enum_int'], - SchemaInterface::TYPECAST => [ - 'id' => 'int', - 'balance' => 'int', - 'enum_string' => TypeStringEnum::class, - 'enum_int' => TypeIntEnum::class, - ], - SchemaInterface::SCHEMA => [], - SchemaInterface::RELATIONS => [], - ], - ] - ) - ); - } - public function testFetchData(): void { $result = (new Select($this->orm, User::class))->fetchData(); $this->assertSame( [TypeStringEnum::Admin, TypeStringEnum::Guest], - \array_column($result, 'enum_string') + \array_column($result, 'enum_string'), ); $this->assertSame( [TypeIntEnum::Admin, TypeIntEnum::Guest], - \array_column($result, 'enum_int') + \array_column($result, 'enum_int'), ); } @@ -142,4 +97,49 @@ public function testUpdate(): void $this->assertSame(TypeStringEnum::Guest, $result2->enum_string); $this->assertSame(TypeIntEnum::Guest, $result2->enum_int); } + + public function setUp(): void + { + parent::setUp(); + + $this->makeTable( + 'user', + [ + 'id' => 'primary', + 'balance' => 'int', + 'enum_string' => 'string', + 'enum_int' => 'int', + ], + ); + $this->getDatabase()->table('user')->insertMultiple( + ['balance', 'enum_string', 'enum_int'], + [ + [100, TypeStringEnum::Admin->value, TypeIntEnum::Admin->value], + [200, TypeStringEnum::Guest->value, TypeIntEnum::Guest->value], + ], + ); + + $this->orm = $this->withSchema( + new Schema( + [ + User::class => [ + SchemaInterface::ROLE => 'user', + SchemaInterface::MAPPER => Mapper::class, + SchemaInterface::DATABASE => 'default', + SchemaInterface::TABLE => 'user', + SchemaInterface::PRIMARY_KEY => 'id', + SchemaInterface::COLUMNS => ['id', 'balance', 'enum_string', 'enum_int'], + SchemaInterface::TYPECAST => [ + 'id' => 'int', + 'balance' => 'int', + 'enum_string' => TypeStringEnum::class, + 'enum_int' => TypeIntEnum::class, + ], + SchemaInterface::SCHEMA => [], + SchemaInterface::RELATIONS => [], + ], + ], + ), + ); + } } diff --git a/tests/ORM/Functional/Driver/Common/Typecast/TypecastTest.php b/tests/ORM/Functional/Driver/Common/Typecast/TypecastTest.php index f2f2184c..ace14f31 100644 --- a/tests/ORM/Functional/Driver/Common/Typecast/TypecastTest.php +++ b/tests/ORM/Functional/Driver/Common/Typecast/TypecastTest.php @@ -28,110 +28,6 @@ abstract class TypecastTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable('user', [ - 'id' => 'primary', - 'email' => 'string', - 'balance' => 'float', - ]); - - $this->makeTable('book', [ - 'id' => 'primary', - 'user_id' => 'int', - 'states' => 'string', - 'nested_states' => 'string', - 'published_at' => 'datetime', - ]); - - $this->getDatabase()->table('user')->insertMultiple( - ['email', 'balance'], - [ - ['hello@world.com', 100], - ['another@world.com', 200], - ] - ); - - $this->orm = $this->withSchema(new Schema([ - 'user' => [ - SchemaInterface::ENTITY => User::class, - SchemaInterface::MAPPER => Mapper::class, - SchemaInterface::DATABASE => 'default', - SchemaInterface::TABLE => 'user', - SchemaInterface::PRIMARY_KEY => 'id', - SchemaInterface::COLUMNS => ['id', 'email', 'balance'], - SchemaInterface::TYPECAST => [ - 'id' => [IDCaster::class, 'wrap'], - 'balance' => [IDCaster::class, 'wrap'], - ], - SchemaInterface::RELATIONS => [ - 'books' => [ - Relation::TYPE => Relation::HAS_MANY, - Relation::TARGET => Book::class, - Relation::LOAD => Relation::LOAD_EAGER, - Relation::SCHEMA => [ - Relation::CASCADE => true, - Relation::NULLABLE => false, - Relation::INNER_KEY => 'id', - Relation::OUTER_KEY => 'user_id', - ], - ], - ], - ], - 'book' => [ - SchemaInterface::ENTITY => Book::class, - SchemaInterface::MAPPER => Mapper::class, - SchemaInterface::DATABASE => 'default', - SchemaInterface::TABLE => 'book', - SchemaInterface::PRIMARY_KEY => 'id', - SchemaInterface::COLUMNS => ['id', 'user_id', 'states', 'nested_states', 'published_at'], - SchemaInterface::TYPECAST => [ - 'id' => 'int', - 'user_id' => 'int', - 'states' => [BookStates::class, 'cast'], - 'nested_states' => [BookNestedStates::class, 'cast'], - 'published_at' => 'datetime', - ], - SchemaInterface::RELATIONS => [], - ], - 'book2' => [ - SchemaInterface::ENTITY => Book2::class, - SchemaInterface::MAPPER => Mapper::class, - SchemaInterface::DATABASE => 'default', - SchemaInterface::TABLE => 'book', - SchemaInterface::PRIMARY_KEY => 'id', - SchemaInterface::COLUMNS => ['id', 'title', 'description'], - SchemaInterface::TYPECAST_HANDLER => [ - ParentTypecast::class, - Typecast::class, - ], - SchemaInterface::TYPECAST => [ - 'id' => 'uuid', - 'title' => ['foo' => 'bar'], - 'description' => fn () => 'wrong description', - ], - SchemaInterface::RELATIONS => [], - ], - 'book3' => [ - SchemaInterface::ENTITY => Book2::class, - SchemaInterface::MAPPER => Mapper::class, - SchemaInterface::DATABASE => 'default', - SchemaInterface::PARENT => 'book2', - SchemaInterface::TABLE => 'book', - SchemaInterface::PRIMARY_KEY => 'id', - SchemaInterface::COLUMNS => ['id', 'title'], - SchemaInterface::TYPECAST_HANDLER => [JsonTypecast::class, UuidTypecast::class], - SchemaInterface::TYPECAST => [ - 'id' => 'uuid', - 'title' => 'json', - ], - SchemaInterface::RELATIONS => [], - ], - ])); - } - // Insert command public function testAIIdTypecastingOnInsert(): void @@ -270,4 +166,108 @@ public function testSelectMultiple(): void $this->assertIsNotObject($users[0]->id->value); $this->assertEquals(1, $users[0]->id->value); } + + public function setUp(): void + { + parent::setUp(); + + $this->makeTable('user', [ + 'id' => 'primary', + 'email' => 'string', + 'balance' => 'float', + ]); + + $this->makeTable('book', [ + 'id' => 'primary', + 'user_id' => 'int', + 'states' => 'string', + 'nested_states' => 'string', + 'published_at' => 'datetime', + ]); + + $this->getDatabase()->table('user')->insertMultiple( + ['email', 'balance'], + [ + ['hello@world.com', 100], + ['another@world.com', 200], + ], + ); + + $this->orm = $this->withSchema(new Schema([ + 'user' => [ + SchemaInterface::ENTITY => User::class, + SchemaInterface::MAPPER => Mapper::class, + SchemaInterface::DATABASE => 'default', + SchemaInterface::TABLE => 'user', + SchemaInterface::PRIMARY_KEY => 'id', + SchemaInterface::COLUMNS => ['id', 'email', 'balance'], + SchemaInterface::TYPECAST => [ + 'id' => [IDCaster::class, 'wrap'], + 'balance' => [IDCaster::class, 'wrap'], + ], + SchemaInterface::RELATIONS => [ + 'books' => [ + Relation::TYPE => Relation::HAS_MANY, + Relation::TARGET => Book::class, + Relation::LOAD => Relation::LOAD_EAGER, + Relation::SCHEMA => [ + Relation::CASCADE => true, + Relation::NULLABLE => false, + Relation::INNER_KEY => 'id', + Relation::OUTER_KEY => 'user_id', + ], + ], + ], + ], + 'book' => [ + SchemaInterface::ENTITY => Book::class, + SchemaInterface::MAPPER => Mapper::class, + SchemaInterface::DATABASE => 'default', + SchemaInterface::TABLE => 'book', + SchemaInterface::PRIMARY_KEY => 'id', + SchemaInterface::COLUMNS => ['id', 'user_id', 'states', 'nested_states', 'published_at'], + SchemaInterface::TYPECAST => [ + 'id' => 'int', + 'user_id' => 'int', + 'states' => [BookStates::class, 'cast'], + 'nested_states' => [BookNestedStates::class, 'cast'], + 'published_at' => 'datetime', + ], + SchemaInterface::RELATIONS => [], + ], + 'book2' => [ + SchemaInterface::ENTITY => Book2::class, + SchemaInterface::MAPPER => Mapper::class, + SchemaInterface::DATABASE => 'default', + SchemaInterface::TABLE => 'book', + SchemaInterface::PRIMARY_KEY => 'id', + SchemaInterface::COLUMNS => ['id', 'title', 'description'], + SchemaInterface::TYPECAST_HANDLER => [ + ParentTypecast::class, + Typecast::class, + ], + SchemaInterface::TYPECAST => [ + 'id' => 'uuid', + 'title' => ['foo' => 'bar'], + 'description' => fn() => 'wrong description', + ], + SchemaInterface::RELATIONS => [], + ], + 'book3' => [ + SchemaInterface::ENTITY => Book2::class, + SchemaInterface::MAPPER => Mapper::class, + SchemaInterface::DATABASE => 'default', + SchemaInterface::PARENT => 'book2', + SchemaInterface::TABLE => 'book', + SchemaInterface::PRIMARY_KEY => 'id', + SchemaInterface::COLUMNS => ['id', 'title'], + SchemaInterface::TYPECAST_HANDLER => [JsonTypecast::class, UuidTypecast::class], + SchemaInterface::TYPECAST => [ + 'id' => 'uuid', + 'title' => 'json', + ], + SchemaInterface::RELATIONS => [], + ], + ])); + } } diff --git a/tests/ORM/Functional/Driver/Common/Typecast/TypecastWithLinkedDataTest.php b/tests/ORM/Functional/Driver/Common/Typecast/TypecastWithLinkedDataTest.php index 269b77d1..40d1ee6a 100644 --- a/tests/ORM/Functional/Driver/Common/Typecast/TypecastWithLinkedDataTest.php +++ b/tests/ORM/Functional/Driver/Common/Typecast/TypecastWithLinkedDataTest.php @@ -23,6 +23,63 @@ abstract class TypecastWithLinkedDataTest extends BaseTest { use TableTrait; + // Select + + public function testSelectOne(): void + { + $user = (new Select($this->orm, User::class))->wherePK(1)->fetchOne(); + + $this->assertNotNull($user->id); + $this->assertIsNotObject($user->id->value); + $this->assertEquals(1, $user->id->value); + } + + /** + * Test the Typecaster doesn't type casting twice when data passed via links + */ + public function testSelectMultiple(): void + { + $users = (new Select($this->orm, User::class))->orderBy('id', 'asc')->fetchAll(); + + $this->assertNotNull($users[0]->id); + $this->assertIsNotObject($users[0]->id->value); + $this->assertEquals(1, $users[0]->id->value); + } + + /** + * Test the Typecaster doesn't type casting twice when data passed via links + */ + public function testCustomArrayInIterator(): void + { + $bookData = [ + 'id' => '1', + 'states' => 'foo|bar', + 'nested_states' => 'foo|bar', + 'published_at' => '2020-12-07', + ]; + $pivotData = [ + 'book_id' => '1', + 'user_id' => '1', + 'created_at' => '2020-12-09', + '@' => &$bookData, + ]; + $userData = [ + 'email' => 'foo@bar', + 'balance' => '42', + 'created_at' => '2020-12-09', + 'books' => [&$pivotData, &$pivotData, &$pivotData], + 'book' => &$bookData, + ]; + + $data = [&$userData, &$userData, &$userData]; + + $iterator = Iterator::createWithOrm($this->orm, User::class, $data, typecast: true); + /** @var User $user */ + $users = \iterator_to_array($iterator); + + $this->assertCount(3, $users); + } + public function setUp(): void { parent::setUp(); @@ -53,7 +110,7 @@ public function setUp(): void [ ['hello@world.com', 100, new \DatetimeImmutable('2020-12-20')], ['another@world.com', 200, new \DatetimeImmutable('2021-12-21')], - ] + ], ); $this->getDatabase()->table('book')->insertMultiple( @@ -61,7 +118,7 @@ public function setUp(): void [ ['a|b|c', 'a|b|c', new \DatetimeImmutable('2020-11-22')], ['x|y|z', 'x|y|z', new \DatetimeImmutable('2021-11-24')], - ] + ], ); $this->getDatabase()->table('pivot')->insertMultiple( @@ -73,7 +130,7 @@ public function setUp(): void [1, 2, new \DatetimeImmutable('2020-12-25')], [2, 2, new \DatetimeImmutable('2021-12-26')], [3, 2, new \DatetimeImmutable('2021-12-27')], - ] + ], ); $this->orm = $this->withSchema(new Schema([ @@ -148,61 +205,4 @@ public function setUp(): void ], ])); } - - // Select - - public function testSelectOne(): void - { - $user = (new Select($this->orm, User::class))->wherePK(1)->fetchOne(); - - $this->assertNotNull($user->id); - $this->assertIsNotObject($user->id->value); - $this->assertEquals(1, $user->id->value); - } - - /** - * Test the Typecaster doesn't type casting twice when data passed via links - */ - public function testSelectMultiple(): void - { - $users = (new Select($this->orm, User::class))->orderBy('id', 'asc')->fetchAll(); - - $this->assertNotNull($users[0]->id); - $this->assertIsNotObject($users[0]->id->value); - $this->assertEquals(1, $users[0]->id->value); - } - - /** - * Test the Typecaster doesn't type casting twice when data passed via links - */ - public function testCustomArrayInIterator(): void - { - $bookData = [ - 'id' => '1', - 'states' => 'foo|bar', - 'nested_states' => 'foo|bar', - 'published_at' => '2020-12-07', - ]; - $pivotData = [ - 'book_id' => '1', - 'user_id' => '1', - 'created_at' => '2020-12-09', - '@' => &$bookData, - ]; - $userData = [ - 'email' => 'foo@bar', - 'balance' => '42', - 'created_at' => '2020-12-09', - 'books' => [&$pivotData, &$pivotData, &$pivotData], - 'book' => &$bookData, - ]; - - $data = [&$userData, &$userData, &$userData]; - - $iterator = Iterator::createWithOrm($this->orm, User::class, $data, typecast: true); - /** @var User $user */ - $users = \iterator_to_array($iterator); - - $this->assertCount(3, $users); - } } diff --git a/tests/ORM/Functional/Driver/Common/Typecast/UUIDTest.php b/tests/ORM/Functional/Driver/Common/Typecast/UUIDTest.php index 87df9ed4..a10143f1 100644 --- a/tests/ORM/Functional/Driver/Common/Typecast/UUIDTest.php +++ b/tests/ORM/Functional/Driver/Common/Typecast/UUIDTest.php @@ -19,40 +19,6 @@ abstract class UUIDTest extends BaseTest { use TableTrait; - public function setUp(): void - { - parent::setUp(); - - $this->makeTable( - 'user_with_uuid_primary_key', - [ - 'uuid' => 'string(36),primary', - 'email' => 'string', - 'balance' => 'float', - ] - ); - - $this->orm = $this->withSchema( - new Schema( - [ - UserWithUUIDPrimaryKey::class => [ - SchemaInterface::ROLE => 'user_with_uuid_primary_key', - SchemaInterface::MAPPER => Mapper::class, - SchemaInterface::DATABASE => 'default', - SchemaInterface::TABLE => 'user_with_uuid_primary_key', - SchemaInterface::PRIMARY_KEY => 'uuid', - SchemaInterface::COLUMNS => ['uuid', 'email', 'balance'], - SchemaInterface::TYPECAST => [ - 'uuid' => [UuidPrimaryKey::class, 'typecast'], - ], - SchemaInterface::SCHEMA => [], - SchemaInterface::RELATIONS => [], - ], - ] - ) - ); - } - public function testCreate(): void { $e = new UserWithUUIDPrimaryKey(new UuidPrimaryKey(Uuid::uuid4()->toString()), 'hello@world.com', 500); @@ -73,13 +39,13 @@ public function testFetchData(): void $this->save($e); - $this->assertEquals($uuid, (string)$e->getID()); + $this->assertEquals($uuid, (string) $e->getID()); $this->orm = $this->orm->withHeap(new Heap()); $result = (new Select($this->orm, UserWithUUIDPrimaryKey::class))->fetchData(); $this->assertInstanceOf(UuidPrimaryKey::class, $result[0]['uuid']); - $this->assertEquals((string)$e->getID(), (string)$result[0]['uuid']); + $this->assertEquals((string) $e->getID(), (string) $result[0]['uuid']); } public function testUpdate(): void @@ -89,13 +55,13 @@ public function testUpdate(): void $this->save($e); - $this->assertEquals($uuid, (string)$e->getID()); + $this->assertEquals($uuid, (string) $e->getID()); $this->orm = $this->orm->withHeap(new Heap()); $result = (new Select($this->orm, UserWithUUIDPrimaryKey::class))->fetchOne(); $this->assertInstanceOf(UuidPrimaryKey::class, $result->getID()); - $this->assertEquals((string)$e->getID(), (string)$result->getID()); + $this->assertEquals((string) $e->getID(), (string) $result->getID()); $result->setEmail('new-mail@test.loc'); @@ -107,4 +73,38 @@ public function testUpdate(): void $this->assertInstanceOf(UuidPrimaryKey::class, $result2->getID()); $this->assertEquals($result->getEmail(), $result2->getEmail()); } + + public function setUp(): void + { + parent::setUp(); + + $this->makeTable( + 'user_with_uuid_primary_key', + [ + 'uuid' => 'string(36),primary', + 'email' => 'string', + 'balance' => 'float', + ], + ); + + $this->orm = $this->withSchema( + new Schema( + [ + UserWithUUIDPrimaryKey::class => [ + SchemaInterface::ROLE => 'user_with_uuid_primary_key', + SchemaInterface::MAPPER => Mapper::class, + SchemaInterface::DATABASE => 'default', + SchemaInterface::TABLE => 'user_with_uuid_primary_key', + SchemaInterface::PRIMARY_KEY => 'uuid', + SchemaInterface::COLUMNS => ['uuid', 'email', 'balance'], + SchemaInterface::TYPECAST => [ + 'uuid' => [UuidPrimaryKey::class, 'typecast'], + ], + SchemaInterface::SCHEMA => [], + SchemaInterface::RELATIONS => [], + ], + ], + ), + ); + } } diff --git a/tests/ORM/Functional/Driver/Postgres/GeneratedColumnTest.php b/tests/ORM/Functional/Driver/Postgres/GeneratedColumnTest.php index 770264b5..79c15b9b 100644 --- a/tests/ORM/Functional/Driver/Postgres/GeneratedColumnTest.php +++ b/tests/ORM/Functional/Driver/Postgres/GeneratedColumnTest.php @@ -30,7 +30,7 @@ public function createTables(): void [Uuid::uuid4()->toString()], [Uuid::uuid4()->toString()], [Uuid::uuid4()->toString()], - ] + ], ); $schema = $this->getDatabase()->table('document')->getSchema(); diff --git a/tests/ORM/Functional/Driver/SQLServer/GeneratedColumnTest.php b/tests/ORM/Functional/Driver/SQLServer/GeneratedColumnTest.php index 30e6f092..10c44816 100644 --- a/tests/ORM/Functional/Driver/SQLServer/GeneratedColumnTest.php +++ b/tests/ORM/Functional/Driver/SQLServer/GeneratedColumnTest.php @@ -37,7 +37,7 @@ public function createTables(): void [Uuid::uuid4()->toString()], [Uuid::uuid4()->toString()], [Uuid::uuid4()->toString()], - ] + ], ); $schema = $this->getDatabase()->table('document')->getSchema(); diff --git a/tests/ORM/Traits/TableTrait.php b/tests/ORM/Traits/TableTrait.php index 82713c6b..be9aca02 100644 --- a/tests/ORM/Traits/TableTrait.php +++ b/tests/ORM/Traits/TableTrait.php @@ -14,8 +14,8 @@ public function makeTable( string $table, array $columns, array $fk = [], - array $pk = null, - array $defaults = [] + ?array $pk = null, + array $defaults = [], ): void { $schema = $this->getDatabase()->table($table)->getSchema(); $renderer = new TableRenderer(); @@ -25,7 +25,7 @@ public function makeTable( if (isset($options['from'])) { $column = $options['from']; } - $fkState = $schema->foreignKey((array)$column)->references($options['table'], (array)$options['column']); + $fkState = $schema->foreignKey((array) $column)->references($options['table'], (array) $options['column']); $fkState->onUpdate($options['onUpdate'] ?? ForeignKeyInterface::CASCADE); $fkState->onDelete($options['onDelete'] ?? ForeignKeyInterface::CASCADE); } @@ -43,11 +43,11 @@ public function makeFK( string $to, string|array $toColumn, string $onDelete = ForeignKeyInterface::CASCADE, - string $onUpdate = ForeignKeyInterface::CASCADE + string $onUpdate = ForeignKeyInterface::CASCADE, ): void { $schema = $this->getDatabase()->table($from)->getSchema(); - $schema->foreignKey((array)$fromKey) - ->references($to, (array)$toColumn) + $schema->foreignKey((array) $fromKey) + ->references($to, (array) $toColumn) ->onDelete($onDelete) ->onUpdate($onUpdate); $schema->save(); @@ -59,7 +59,7 @@ public function makeCompositeFK( string $to, array $toColumns, string $onDelete = ForeignKeyInterface::CASCADE, - string $onUpdate = ForeignKeyInterface::CASCADE + string $onUpdate = ForeignKeyInterface::CASCADE, ): void { $schema = $this->getDatabase()->table($from)->getSchema(); $schema->foreignKey($fromKeys)->references($to, $toColumns)->onDelete($onDelete)->onUpdate($onUpdate); @@ -69,7 +69,7 @@ public function makeCompositeFK( public function makeIndex( string $table, array $columns, - bool $unique + bool $unique, ): void { $schema = $this->getDatabase()->table($table)->getSchema(); $schema->index($columns)->unique($unique); diff --git a/tests/ORM/Unit/Collection/ArrayCollectionFactoryTest.php b/tests/ORM/Unit/Collection/ArrayCollectionFactoryTest.php index d88659fd..2b006284 100644 --- a/tests/ORM/Unit/Collection/ArrayCollectionFactoryTest.php +++ b/tests/ORM/Unit/Collection/ArrayCollectionFactoryTest.php @@ -16,6 +16,7 @@ public function testGetInterface(): void /** * @dataProvider collectionDataProvider + * @param mixed $data */ public function testCollectShouldReturnArray($data): void { diff --git a/tests/ORM/Unit/Collection/BaseTest.php b/tests/ORM/Unit/Collection/BaseTest.php index c74b7ad9..9f56f773 100644 --- a/tests/ORM/Unit/Collection/BaseTest.php +++ b/tests/ORM/Unit/Collection/BaseTest.php @@ -11,20 +11,6 @@ abstract class BaseTest extends TestCase { private CollectionFactoryInterface $factory; - abstract protected function getFactory(): CollectionFactoryInterface; - - protected function setUp(): void - { - parent::setUp(); - $this->factory = $this->getFactory(); - } - - private function generatorArray() - { - yield 'foo' => 'bar'; - yield 'baz' => 'bar'; - } - public function collectionDataProvider() { return [ @@ -45,4 +31,18 @@ public function collectionDataProvider() ], ]; } + + protected function setUp(): void + { + parent::setUp(); + $this->factory = $this->getFactory(); + } + + abstract protected function getFactory(): CollectionFactoryInterface; + + private function generatorArray() + { + yield 'foo' => 'bar'; + yield 'baz' => 'bar'; + } } diff --git a/tests/ORM/Unit/Collection/DoctrineCollectionFactoryTest.php b/tests/ORM/Unit/Collection/DoctrineCollectionFactoryTest.php index fdfbf3b4..69984adc 100644 --- a/tests/ORM/Unit/Collection/DoctrineCollectionFactoryTest.php +++ b/tests/ORM/Unit/Collection/DoctrineCollectionFactoryTest.php @@ -20,6 +20,7 @@ public function testGetInterface(): void /** * @dataProvider collectionDataProvider + * @param mixed $data */ public function testCollectShouldReturnArray($data): void { @@ -38,7 +39,7 @@ public function testCollectPivotStorageWithArrayCollection(): void new PivotedStorage($array = [ 'foo' => 'bar', 'baz' => 'bar', - ]) + ]), ); $this->assertInstanceOf(PivotedCollection::class, $collection); @@ -53,7 +54,7 @@ public function testCollectPivotStorageWithPivotedCollection(): void new PivotedStorage($array = [ 'foo' => 'bar', 'baz' => 'bar', - ]) + ]), ); $this->assertInstanceOf(CustomPivotedCollection::class, $collection); @@ -66,6 +67,4 @@ protected function getFactory(): CollectionFactoryInterface } } -class CustomPivotedCollection extends PivotedCollection -{ -} +class CustomPivotedCollection extends PivotedCollection {} diff --git a/tests/ORM/Unit/Collection/IlluminateCollectionFactoryTest.php b/tests/ORM/Unit/Collection/IlluminateCollectionFactoryTest.php index 16d48d25..ae888799 100644 --- a/tests/ORM/Unit/Collection/IlluminateCollectionFactoryTest.php +++ b/tests/ORM/Unit/Collection/IlluminateCollectionFactoryTest.php @@ -17,6 +17,7 @@ public function testGetInterface(): void /** * @dataProvider collectionDataProvider + * @param mixed $data */ public function testCollectShouldReturnArray($data): void { @@ -31,6 +32,7 @@ public function testCollectShouldReturnArray($data): void /** * @dataProvider collectionDataProvider + * @param mixed $data */ public function testCollectShouldReturnArrayForCustomCollection($data): void { @@ -51,6 +53,4 @@ protected function getFactory(): CollectionFactoryInterface } } -class CustomCollection extends Collection -{ -} +class CustomCollection extends Collection {} diff --git a/tests/ORM/Unit/Collection/LoophpCollectionFactoryTest.php b/tests/ORM/Unit/Collection/LoophpCollectionFactoryTest.php index 6cc2baf0..360442f9 100644 --- a/tests/ORM/Unit/Collection/LoophpCollectionFactoryTest.php +++ b/tests/ORM/Unit/Collection/LoophpCollectionFactoryTest.php @@ -9,7 +9,6 @@ use Cycle\ORM\Collection\Pivoted\LoophpPivotedCollection; use Cycle\ORM\Collection\Pivoted\PivotedStorage; use Cycle\ORM\Exception\CollectionFactoryException; -use IteratorIterator; use loophp\collection\CollectionDecorator; use loophp\collection\Contract\Collection as CollectionInterface; use loophp\collection\Collection; @@ -23,6 +22,7 @@ public function testGetInterface(): void /** * @dataProvider collectionDataProvider + * @param mixed $data */ public function testCollectShouldReturnArray($data): void { @@ -49,7 +49,7 @@ public function testWithCollectionClassNotCollection(): void $this->expectException(CollectionFactoryException::class); $this->expectExceptionMessage('Unsupported collection class `IteratorIterator`.'); - $this->getFactory()->withCollectionClass(IteratorIterator::class); + $this->getFactory()->withCollectionClass(\IteratorIterator::class); } /** @@ -68,7 +68,7 @@ public function testWithCollectionClassInterface(mixed $data): void */ public function testWithCollectionClassCustomClass(mixed $data): void { - $customClass = new class (Collection::empty()) extends CollectionDecorator {}; + $customClass = new class(Collection::empty()) extends CollectionDecorator {}; $collection = $this->getFactory()->withCollectionClass($customClass::class)->collect($data); @@ -140,6 +140,4 @@ protected function getFactory(): CollectionFactoryInterface } } -class CustomLoophpPivotedCollection extends LoophpPivotedCollection -{ -} +class CustomLoophpPivotedCollection extends LoophpPivotedCollection {} diff --git a/tests/ORM/Unit/Command/DeleteCommandTest.php b/tests/ORM/Unit/Command/DeleteCommandTest.php index 66b2ca2d..8b90ae83 100644 --- a/tests/ORM/Unit/Command/DeleteCommandTest.php +++ b/tests/ORM/Unit/Command/DeleteCommandTest.php @@ -27,7 +27,7 @@ public function testNoScope(): void m::mock(DatabaseInterface::class), 'table', $state, - $this->mapper + $this->mapper, ); $cmd->execute(); diff --git a/tests/ORM/Unit/Command/Helper/TestInsert.php b/tests/ORM/Unit/Command/Helper/TestInsert.php index e40d7a56..37382218 100644 --- a/tests/ORM/Unit/Command/Helper/TestInsert.php +++ b/tests/ORM/Unit/Command/Helper/TestInsert.php @@ -18,20 +18,12 @@ class TestInsert extends DatabaseCommand /** @var array */ protected $data; - /** - * @param DatabaseInterface $db - * @param string $table - * @param array $data - */ - public function __construct(DatabaseInterface $db, string $table, array $data = [], callable $generateID = null) + public function __construct(DatabaseInterface $db, string $table, array $data = [], ?callable $generateID = null) { parent::__construct($db, $table); $this->data = $data; } - /** - * @inheritdoc - */ public function isReady(): bool { return true; @@ -40,7 +32,6 @@ public function isReady(): bool /** * Insert values, context not included. * - * @return array */ public function getData(): array { diff --git a/tests/ORM/Unit/Command/InsertCommandTest.php b/tests/ORM/Unit/Command/InsertCommandTest.php index a29ffc1d..144cbfb4 100644 --- a/tests/ORM/Unit/Command/InsertCommandTest.php +++ b/tests/ORM/Unit/Command/InsertCommandTest.php @@ -25,22 +25,6 @@ class InsertCommandTest extends TestCase private m\LegacyMockInterface|m\MockInterface|MapperInterface $mapper; private State $state; - protected function setUp(): void - { - parent::setUp(); - - $this->mapper = m::mock(MapperInterface::class); - - $this->cmd = new Insert( - $this->db = m::mock(DatabaseInterface::class), - 'table', - $this->state = new State(Node::SCHEDULED_INSERT, ['foo' => 'bar']), - $this->mapper, - ['id'], - 'foo_id' - ); - } - public function testDatabase(): void { $this->assertSame($this->db, $this->cmd->getDatabase()); @@ -68,7 +52,7 @@ public function testCommandWithoutReturningInterfaceShouldNotUseIt(): void $compiler->shouldReceive('compile')->once()->withArgs( function (QueryParameters $params, string $prefix, FragmentInterface $fragment) { return true; - } + }, ); $this->mapper->shouldReceive('uncast') @@ -165,4 +149,20 @@ public function testCommandWithReturningInterfaceShouldUseIt() $this->assertSame(324, $this->state->getValue('id')); } + + protected function setUp(): void + { + parent::setUp(); + + $this->mapper = m::mock(MapperInterface::class); + + $this->cmd = new Insert( + $this->db = m::mock(DatabaseInterface::class), + 'table', + $this->state = new State(Node::SCHEDULED_INSERT, ['foo' => 'bar']), + $this->mapper, + ['id'], + 'foo_id', + ); + } } diff --git a/tests/ORM/Unit/Command/UpdateCommandTest.php b/tests/ORM/Unit/Command/UpdateCommandTest.php index 7b7fbeea..582bbfb5 100644 --- a/tests/ORM/Unit/Command/UpdateCommandTest.php +++ b/tests/ORM/Unit/Command/UpdateCommandTest.php @@ -21,22 +21,6 @@ class UpdateCommandTest extends TestCase private DatabaseInterface $db; private State $state; - protected function setUp(): void - { - parent::setUp(); - - $this->mapper = m::mock(MapperInterface::class); - $this->state = new State(Node::SCHEDULED_UPDATE, ['foo' => 'bar']); - - $this->cmd = new Update( - $this->db = m::mock(DatabaseInterface::class), - 'table', - $this->state, - $this->mapper, - [] - ); - } - public function testIsEmpty(): void { $this->assertTrue($this->cmd->isReady()); @@ -134,4 +118,20 @@ public function testExecuteWithEmptyDataShouldNotRunQuery() $this->assertSame(['foo' => 'bar', 'name' => 'new value'], $this->state->getData()); $this->assertSame(0, $this->cmd->getAffectedRows()); } + + protected function setUp(): void + { + parent::setUp(); + + $this->mapper = m::mock(MapperInterface::class); + $this->state = new State(Node::SCHEDULED_UPDATE, ['foo' => 'bar']); + + $this->cmd = new Update( + $this->db = m::mock(DatabaseInterface::class), + 'table', + $this->state, + $this->mapper, + [], + ); + } } diff --git a/tests/ORM/Unit/Heap/HeapCompositeKeysTest.php b/tests/ORM/Unit/Heap/HeapCompositeKeysTest.php index 65384b4a..d48371df 100644 --- a/tests/ORM/Unit/Heap/HeapCompositeKeysTest.php +++ b/tests/ORM/Unit/Heap/HeapCompositeKeysTest.php @@ -12,53 +12,38 @@ final class HeapCompositeKeysTest extends HeapTest { - protected const - INDEX_FIELDS_1 = ['id', 'user_code']; - protected const - INDEX_VALUES_1_1 = [42, 'ytrewq']; - protected const - INDEX_VALUES_1_2 = [24, 'qwerty']; - protected const - INDEX_FIND_1_1 = [ - self::INDEX_FIELDS_1[0] => self::INDEX_VALUES_1_1[0], - self::INDEX_FIELDS_1[1] => self::INDEX_VALUES_1_1[1], - ]; - protected const - INDEX_FIND_1_2 = [ - self::INDEX_FIELDS_1[0] => self::INDEX_VALUES_1_2[0], - self::INDEX_FIELDS_1[1] => self::INDEX_VALUES_1_2[1], - ]; - protected const - INDEX_FIND_1_BAD = [ - self::INDEX_FIELDS_1[0] => 404, - self::INDEX_FIELDS_1[1] => 'none', - ]; - protected const - INDEX_FIELDS_2 = 'email'; - protected const - INDEX_VALUES_2_1 = 'mail1@spiral'; - protected const - INDEX_VALUES_2_2 = 'mail2@spiral'; - protected const - INDEX_FIND_2_1 = [self::INDEX_FIELDS_2 => self::INDEX_VALUES_2_1]; - protected const - INDEX_FIND_2_2 = [self::INDEX_FIELDS_2 => self::INDEX_VALUES_2_2]; - protected const - INDEX_FIELDS_BAD = [self::INDEX_FIELDS_1[0], self::INDEX_FIELDS_1[1], 'foo']; - protected const - INDEX_FIND_BAD = self::INDEX_FIND_1_1 + [self::INDEX_FIELDS_BAD[2] => null]; - protected const - ENTITY_SET_1 = [ - self::INDEX_FIELDS_1[0] => self::INDEX_VALUES_1_1[0], - self::INDEX_FIELDS_1[1] => self::INDEX_VALUES_1_1[1], - self::INDEX_FIELDS_2 => self::INDEX_VALUES_2_1, - ]; - protected const - ENTITY_SET_2 = [ - self::INDEX_FIELDS_1[0] => self::INDEX_VALUES_1_2[0], - self::INDEX_FIELDS_1[1] => self::INDEX_VALUES_1_2[1], - self::INDEX_FIELDS_2 => self::INDEX_VALUES_2_2, - ]; + protected const INDEX_FIELDS_1 = ['id', 'user_code']; + protected const INDEX_VALUES_1_1 = [42, 'ytrewq']; + protected const INDEX_VALUES_1_2 = [24, 'qwerty']; + protected const INDEX_FIND_1_1 = [ + self::INDEX_FIELDS_1[0] => self::INDEX_VALUES_1_1[0], + self::INDEX_FIELDS_1[1] => self::INDEX_VALUES_1_1[1], + ]; + protected const INDEX_FIND_1_2 = [ + self::INDEX_FIELDS_1[0] => self::INDEX_VALUES_1_2[0], + self::INDEX_FIELDS_1[1] => self::INDEX_VALUES_1_2[1], + ]; + protected const INDEX_FIND_1_BAD = [ + self::INDEX_FIELDS_1[0] => 404, + self::INDEX_FIELDS_1[1] => 'none', + ]; + protected const INDEX_FIELDS_2 = 'email'; + protected const INDEX_VALUES_2_1 = 'mail1@spiral'; + protected const INDEX_VALUES_2_2 = 'mail2@spiral'; + protected const INDEX_FIND_2_1 = [self::INDEX_FIELDS_2 => self::INDEX_VALUES_2_1]; + protected const INDEX_FIND_2_2 = [self::INDEX_FIELDS_2 => self::INDEX_VALUES_2_2]; + protected const INDEX_FIELDS_BAD = [self::INDEX_FIELDS_1[0], self::INDEX_FIELDS_1[1], 'foo']; + protected const INDEX_FIND_BAD = self::INDEX_FIND_1_1 + [self::INDEX_FIELDS_BAD[2] => null]; + protected const ENTITY_SET_1 = [ + self::INDEX_FIELDS_1[0] => self::INDEX_VALUES_1_1[0], + self::INDEX_FIELDS_1[1] => self::INDEX_VALUES_1_1[1], + self::INDEX_FIELDS_2 => self::INDEX_VALUES_2_1, + ]; + protected const ENTITY_SET_2 = [ + self::INDEX_FIELDS_1[0] => self::INDEX_VALUES_1_2[0], + self::INDEX_FIELDS_1[1] => self::INDEX_VALUES_1_2[1], + self::INDEX_FIELDS_2 => self::INDEX_VALUES_2_2, + ]; public function testFindByShuffledCriteria(): void { diff --git a/tests/ORM/Unit/Heap/HeapTest.php b/tests/ORM/Unit/Heap/HeapTest.php index b8fc5d00..3736cc14 100644 --- a/tests/ORM/Unit/Heap/HeapTest.php +++ b/tests/ORM/Unit/Heap/HeapTest.php @@ -55,7 +55,7 @@ public function testIndexAsArray(): void $heap = $this->createHeap(); $node = new Node(Node::NEW, static::ENTITY_SET_1, 'user'); $entity = new User(); - $heap->attach($entity, $node, [(array)static::INDEX_FIELDS_1]); + $heap->attach($entity, $node, [(array) static::INDEX_FIELDS_1]); $this->assertSame($entity, $heap->find('user', static::INDEX_FIND_1_1), 'Found'); } diff --git a/tests/ORM/Unit/Heap/NodeComparisonTest.php b/tests/ORM/Unit/Heap/NodeComparisonTest.php index f24189ef..8469b342 100644 --- a/tests/ORM/Unit/Heap/NodeComparisonTest.php +++ b/tests/ORM/Unit/Heap/NodeComparisonTest.php @@ -7,9 +7,7 @@ use Cycle\Database\Injection\ValueInterface; use Cycle\ORM\Heap\Node; use DateTime; -use DateTimeImmutable; use PHPUnit\Framework\TestCase; -use Stringable; class NodeComparisonTest extends TestCase { @@ -39,12 +37,12 @@ public function equalValuesProvider(): iterable ]; // Datetime - $t = new DateTime(); + $t = new \DateTime(); yield 'same datetime object' => [$t, $t]; - yield 'same mutable and immutable' => [$t, DateTimeImmutable::createFromInterface($t)]; + yield 'same mutable and immutable' => [$t, \DateTimeImmutable::createFromInterface($t)]; yield 'different objects from same mutable' => [ - DateTimeImmutable::createFromInterface($t), - DateTimeImmutable::createFromInterface($t), + \DateTimeImmutable::createFromInterface($t), + \DateTimeImmutable::createFromInterface($t), ]; // Custom object $obj = $this->createStringableObject('obj'); @@ -58,7 +56,7 @@ public function equalValuesProvider(): iterable $obj1 = $this->createStringableObject('obj'); $obj2 = $this->createStringableObject('o', 'b', 'j'); \assert($obj1->__toString() === $obj2->__toString()); - \assert((array)$obj1 !== (array)$obj2); + \assert((array) $obj1 !== (array) $obj2); yield 'different custom objects with same result from __toString()' => [$obj1, $obj2]; yield 'Stringable and string' => [$obj1, 'obj']; @@ -103,7 +101,7 @@ public function notEqualValuesProvider(): iterable [true, 0], ]; // Datetime - yield 'different Datetime same second' => [new DateTimeImmutable(), new DateTimeImmutable()]; + yield 'different Datetime same second' => [new \DateTimeImmutable(), new \DateTimeImmutable()]; // Custom object yield 'different objects' => [$this->createStringableObject('foo'), $this->createStringableObject('bar')]; yield 'Different objects with ValueInterface' => [ @@ -120,7 +118,7 @@ public function notEqualValuesProvider(): iterable $this->createNotStringableObject2(null, 'foo'), ]; yield 'Datetime and not Stringable' => [ - new DateTimeImmutable(), + new \DateTimeImmutable(), $this->createNotStringableObject(null, 'foo'), ]; } @@ -148,16 +146,14 @@ private function exportVars(mixed $a, mixed $b): string \get_debug_type($a), \var_export($a, true), \get_debug_type($b), - \var_export($b, true) + \var_export($b, true), ); } private function createObjectWithValueInterface(string ...$toConcat): object { - return new class ($toConcat) implements ValueInterface { - public function __construct(private array $toConcat) - { - } + return new class($toConcat) implements ValueInterface { + public function __construct(private array $toConcat) {} public function rawValue(): string { @@ -173,10 +169,8 @@ public function rawType(): int private function createStringableObject(string ...$toConcat): object { - return new class ($toConcat) implements Stringable { - public function __construct(private array $toConcat) - { - } + return new class($toConcat) implements \Stringable { + public function __construct(private array $toConcat) {} public function __toString(): string { @@ -187,23 +181,21 @@ public function __toString(): string private function createNotStringableObject(mixed $a = null, mixed $b = null): object { - return new class ($a, $b) { + return new class($a, $b) { public function __construct( private mixed $a, private mixed $b, - ) { - } + ) {} }; } private function createNotStringableObject2(mixed $a = null, mixed $b = null): object { - return new class ($a, $b) { + return new class($a, $b) { public function __construct( private mixed $a, private mixed $b, - ) { - } + ) {} }; } } diff --git a/tests/ORM/Unit/Heap/NullHeapTest.php b/tests/ORM/Unit/Heap/NullHeapTest.php index c06e6fc6..a85279c1 100644 --- a/tests/ORM/Unit/Heap/NullHeapTest.php +++ b/tests/ORM/Unit/Heap/NullHeapTest.php @@ -53,7 +53,7 @@ public function testIndexAsArray(): void $heap = $this->createHeap(); $node = new Node(Node::NEW, self::ENTITY_SET_1, 'user'); $entity = new User(); - $heap->attach($entity, $node, [(array)self::INDEX_FIELDS_1]); + $heap->attach($entity, $node, [(array) self::INDEX_FIELDS_1]); $this->assertNull($heap->find('user', self::INDEX_FIND_1_1)); } diff --git a/tests/ORM/Unit/Mapper/Proxy/ProxyEntityFactoryTest.php b/tests/ORM/Unit/Mapper/Proxy/ProxyEntityFactoryTest.php index 249ce473..cce91c44 100644 --- a/tests/ORM/Unit/Mapper/Proxy/ProxyEntityFactoryTest.php +++ b/tests/ORM/Unit/Mapper/Proxy/ProxyEntityFactoryTest.php @@ -22,13 +22,30 @@ class ProxyEntityFactoryTest extends TestCase private ProxyEntityFactory $factory; private ORM $orm; + public function testCreatesObject() + { + $user = $this->factory->create(RelationMap::build($this->orm, 'user'), User::class); + + $this->assertInstanceOf(EntityProxyInterface::class, $user); + } + + public function testCreatesNonExistingObjectShouldThrowException() + { + $this->expectException(\RuntimeException::class); + $this->expectExceptionMessage( + 'The entity `hello-world` class does not exist. Proxy factory can not create classless entities.', + ); + + $this->factory->create(RelationMap::build($this->orm, 'user'), 'hello-world'); + } + protected function setUp(): void { parent::setUp(); $this->factory = new ProxyEntityFactory( new ClosureHydrator(), - new ClassPropertiesExtractor() + new ClassPropertiesExtractor(), ); $factory = $this->createMock(FactoryInterface::class); @@ -46,24 +63,7 @@ protected function setUp(): void SchemaInterface::SCHEMA => [], SchemaInterface::RELATIONS => [], ], - ]) + ]), ); } - - public function testCreatesObject() - { - $user = $this->factory->create(RelationMap::build($this->orm, 'user'), User::class); - - $this->assertInstanceOf(EntityProxyInterface::class, $user); - } - - public function testCreatesNonExistingObjectShouldThrowException() - { - $this->expectException(\RuntimeException::class); - $this->expectExceptionMessage( - 'The entity `hello-world` class does not exist. Proxy factory can not create classless entities.' - ); - - $this->factory->create(RelationMap::build($this->orm, 'user'), 'hello-world'); - } } diff --git a/tests/ORM/Unit/OrmTest.php b/tests/ORM/Unit/OrmTest.php index 6a513488..c836e5b5 100644 --- a/tests/ORM/Unit/OrmTest.php +++ b/tests/ORM/Unit/OrmTest.php @@ -64,9 +64,9 @@ private function createOrm(): ORM factory: new Factory( new DatabaseManager(new DatabaseConfig([])), RelationConfig::getDefault(), - new SimpleFactory() + new SimpleFactory(), ), - schema: new Schema([]) + schema: new Schema([]), ); } } diff --git a/tests/ORM/Unit/Parser/CompositeTypecastTest.php b/tests/ORM/Unit/Parser/CompositeTypecastTest.php index 8e0d9096..38fbd618 100644 --- a/tests/ORM/Unit/Parser/CompositeTypecastTest.php +++ b/tests/ORM/Unit/Parser/CompositeTypecastTest.php @@ -24,7 +24,6 @@ class CompositeTypecastTest extends TestCase private const RULES_RESULT = [ 'baz' => 'bar', ]; - private const CAST_INITIAL = [ 'foo' => 'foo', 'bar' => 'bar', @@ -33,7 +32,6 @@ class CompositeTypecastTest extends TestCase 'foo' => 'bar_final', 'bar' => 'bar_final', ]; - private const UNCAST_INITIAL = [ 'foo' => 'unfoo', 'bar' => 'unbar', @@ -42,7 +40,6 @@ class CompositeTypecastTest extends TestCase 'foo' => 'unbar_final', 'bar' => 'unbar_final', ]; - private const OPT_TYPECAST = 0; private const OPT_RULES_RETURNS = 1; private const OPT_CAST_RETURNS = 2; @@ -108,7 +105,7 @@ public function testSetRules(array $casters): void } $typecast = new CompositeTypecast( - ...array_map(static fn (array $data) => $data[self::OPT_TYPECAST], $casters) + ...array_map(static fn(array $data) => $data[self::OPT_TYPECAST], $casters), ); $this->assertSame(self::RULES_RESULT, $typecast->setRules(self::RULES_INITIAL)); @@ -135,7 +132,7 @@ public function testCast(array $casters): void } $typecast = new CompositeTypecast( - ...array_map(static fn (array $data) => $data[self::OPT_TYPECAST], $casters) + ...array_map(static fn(array $data) => $data[self::OPT_TYPECAST], $casters), ); $this->assertSame(self::CAST_RESULT, $typecast->cast(self::CAST_INITIAL)); @@ -163,7 +160,7 @@ public function testUncast(array $casters): void } $typecast = new CompositeTypecast( - ...array_map(static fn (array $data) => $data[self::OPT_TYPECAST], $casters) + ...array_map(static fn(array $data) => $data[self::OPT_TYPECAST], $casters), ); $this->assertSame(self::UNCAST_RESULT, $typecast->uncast(self::UNCAST_INITIAL)); diff --git a/tests/ORM/Unit/Parser/TypecastTest.php b/tests/ORM/Unit/Parser/TypecastTest.php index 9c2aaf72..3ca0eeae 100644 --- a/tests/ORM/Unit/Parser/TypecastTest.php +++ b/tests/ORM/Unit/Parser/TypecastTest.php @@ -13,22 +13,12 @@ use Cycle\ORM\Tests\Fixtures\Uuid; use Mockery as m; use PHPUnit\Framework\TestCase; -use ReflectionEnum; class TypecastTest extends TestCase { private Typecast $typecast; private m\LegacyMockInterface|m\MockInterface|DatabaseInterface $db; - protected function setUp(): void - { - parent::setUp(); - - $this->typecast = new Typecast( - $this->db = m::mock(DatabaseInterface::class) - ); - } - public function testSetRules(): void { $rules = [ @@ -36,7 +26,7 @@ public function testSetRules(): void 'guest' => 'bool', 'bonus' => 'float', 'date' => 'datetime', - 'slug' => fn (string $value) => strtolower($value), + 'slug' => fn(string $value) => strtolower($value), 'title' => 'strtoupper', 'test' => [Uuid::class, 'create'], 'uuid' => 'uuid', @@ -61,7 +51,7 @@ public function enumCastDataProvider(): iterable if (\PHP_VERSION_ID < 80100) { return; } - $getCase = static fn (string $enum, string $case) => (new ReflectionEnum($enum)) + $getCase = static fn(string $enum, string $case) => (new \ReflectionEnum($enum)) ->getCase($case) ->getValue(); @@ -190,4 +180,13 @@ public function testUncast(): void $this->assertSame(['bar' => 'baz'], $data['bar']); $this->assertNull($data['baz']); } + + protected function setUp(): void + { + parent::setUp(); + + $this->typecast = new Typecast( + $this->db = m::mock(DatabaseInterface::class), + ); + } } diff --git a/tests/ORM/Unit/Select/Traits/ColumnsTrait.php b/tests/ORM/Unit/Select/Traits/ColumnsTrait.php index ee4ca6f4..fa2c0142 100644 --- a/tests/ORM/Unit/Select/Traits/ColumnsTrait.php +++ b/tests/ORM/Unit/Select/Traits/ColumnsTrait.php @@ -36,7 +36,7 @@ public function testGetColumns(string $input, ?string $expected): void private function prepareClass(): object { - return new class (self::FIELDS) { + return new class(self::FIELDS) { use \Cycle\ORM\Select\Traits\ColumnsTrait { fieldAlias as public; diff --git a/tests/ORM/Unit/Transaction/PoolTest.php b/tests/ORM/Unit/Transaction/PoolTest.php index 4b31a802..c8f642d9 100644 --- a/tests/ORM/Unit/Transaction/PoolTest.php +++ b/tests/ORM/Unit/Transaction/PoolTest.php @@ -9,7 +9,6 @@ use Cycle\ORM\Transaction\Tuple; use Mockery as m; use PHPUnit\Framework\TestCase; -use stdClass; class PoolTest extends TestCase { @@ -17,7 +16,7 @@ public function testDoubleAttachSameEntityWithNullNode(): void { $orm = m::mock(ORMInterface::class); $pool = new Pool($orm); - $entity = new stdClass(); + $entity = new \stdClass(); $pool->attach($entity, Tuple::TASK_DELETE, false); $pool->attach($entity, Tuple::TASK_DELETE, false); diff --git a/tests/ORM/Unit/Transaction/TupleStorageTest.php b/tests/ORM/Unit/Transaction/TupleStorageTest.php index 9b5fa177..af80ebe7 100644 --- a/tests/ORM/Unit/Transaction/TupleStorageTest.php +++ b/tests/ORM/Unit/Transaction/TupleStorageTest.php @@ -93,7 +93,7 @@ public function testAddItemsWhenIterating(): void } /** @see TupleStorage::$iterators */ - self::assertCount(0, (fn (): array => $this->iterators)->call($storage)); + self::assertCount(0, (fn(): array => $this->iterators)->call($storage)); $iterator = $storage->getIterator(); // Start generator @@ -101,12 +101,12 @@ public function testAddItemsWhenIterating(): void break; } /** @see TupleStorage::$iterators */ - self::assertCount(1, (fn (): array => $this->iterators)->call($storage)); + self::assertCount(1, (fn(): array => $this->iterators)->call($storage)); // Cleanup on iterator destruction unset($iterator); /** @see TupleStorage::$iterators */ - self::assertCount(0, (fn (): array => $this->iterators)->call($storage)); + self::assertCount(0, (fn(): array => $this->iterators)->call($storage)); // Cleanup on end of iteration $iterator = $storage->getIterator(); @@ -115,16 +115,16 @@ public function testAddItemsWhenIterating(): void // do nothing } /** @see TupleStorage::$iterators */ - self::assertCount(0, (fn (): array => $this->iterators)->call($storage)); + self::assertCount(0, (fn(): array => $this->iterators)->call($storage)); } public function testDetachWhenIterating(): void { $storage = new TupleStorage(); - $tuple1 = $this->createTuple((object)['value' => 1]); - $tuple2 = $this->createTuple((object)['value' => 2]); - $tuple3 = $this->createTuple((object)['value' => 3]); - $tuple4 = $this->createTuple((object)['value' => 4]); + $tuple1 = $this->createTuple((object) ['value' => 1]); + $tuple2 = $this->createTuple((object) ['value' => 2]); + $tuple3 = $this->createTuple((object) ['value' => 3]); + $tuple4 = $this->createTuple((object) ['value' => 4]); $storage->attach($tuple1); $storage->attach($tuple2); @@ -148,10 +148,10 @@ public function testDetachWhenIterating(): void public function testCleanupIteratorState(): void { $storage = new TupleStorage(); - $tuple1 = $this->createTuple((object)['value' => 1]); - $tuple2 = $this->createTuple((object)['value' => 2]); - $tuple3 = $this->createTuple((object)['value' => 3]); - $tuple4 = $this->createTuple((object)['value' => 4]); + $tuple1 = $this->createTuple((object) ['value' => 1]); + $tuple2 = $this->createTuple((object) ['value' => 2]); + $tuple3 = $this->createTuple((object) ['value' => 3]); + $tuple4 = $this->createTuple((object) ['value' => 4]); $storage->attach($tuple1); $storage->attach($tuple2); diff --git a/tests/ORM/Util/DontGenerateAttribute.php b/tests/ORM/Util/DontGenerateAttribute.php index b9d1c5aa..aa2625ab 100644 --- a/tests/ORM/Util/DontGenerateAttribute.php +++ b/tests/ORM/Util/DontGenerateAttribute.php @@ -4,9 +4,5 @@ namespace Cycle\ORM\Tests\Util; -use Attribute; - -#[Attribute(Attribute::TARGET_CLASS)] -final class DontGenerateAttribute -{ -} +#[\Attribute(\Attribute::TARGET_CLASS)] +final class DontGenerateAttribute {} diff --git a/tests/ORM/Util/SimpleFactory.php b/tests/ORM/Util/SimpleFactory.php index 06084313..910fc24c 100644 --- a/tests/ORM/Util/SimpleFactory.php +++ b/tests/ORM/Util/SimpleFactory.php @@ -11,14 +11,14 @@ final class SimpleFactory implements FactoryInterface { private array $definitions; - private Closure $factory; + private \Closure $factory; /** * @param array $definitions List of items that will be cloned - * @param Closure|null $factory Should be closure that works + * @param \Closure|null $factory Should be closure that works * like FactoryInterface::make(string $alias, array $parameters): mixed */ - public function __construct(array $definitions = [], Closure $factory = null) + public function __construct(array $definitions = [], ?\Closure $factory = null) { $this->definitions = $definitions; $this->factory = $factory ?? static function (string $alias, array $parameters = []): void { diff --git a/tests/ORM/Util/TableRenderer.php b/tests/ORM/Util/TableRenderer.php index c2e1197c..b2fda645 100644 --- a/tests/ORM/Util/TableRenderer.php +++ b/tests/ORM/Util/TableRenderer.php @@ -34,10 +34,6 @@ final class TableRenderer * ] * ); * - * @param AbstractTable $table - * @param array $columns - * @param array $defaults - * * @throws SchemaException */ public function renderColumns(AbstractTable $table, array $columns, array $defaults): void @@ -54,7 +50,7 @@ public function renderColumns(AbstractTable $table, array $columns, array $defau $table->column($name), $type, array_key_exists($name, $defaults), - $defaults[$name] ?? null + $defaults[$name] ?? null, ); } @@ -82,8 +78,6 @@ public function renderColumns(AbstractTable $table, array $columns, array $defau * * Attention, column state will be affected! * - * @param AbstractColumn $column - * @param array $type * @param bool $hasDefault Must be set to true if default value was set by user. * @param mixed $default Default value declared by record schema. * @@ -108,7 +102,7 @@ protected function renderColumn(AbstractColumn $column, array $type, bool $hasDe throw new SchemaException( "Invalid column type definition in '{$column->getTable()}'.'{$column->getName()}'", $e->getCode(), - $e + $e, ); } @@ -126,7 +120,7 @@ protected function renderColumn(AbstractColumn $column, array $type, bool $hasDe return; } - if (null === $default) { + if ($default === null) { // default value is stated and NULL, clear what to do $column->nullable(true); } @@ -134,20 +128,13 @@ protected function renderColumn(AbstractColumn $column, array $type, bool $hasDe $column->defaultValue($default); } - /** - * @param string $table - * @param string $column - * @param string $definition - * - * @return array - */ protected function parse(string $table, string $column, string $definition): array { if ( !preg_match( '/(?P[a-z]+)(?: *\((?P[^\)]+)\))?(?: *, *(?P.+))?/i', $definition, - $type + $type, ) ) { throw new SchemaException("Invalid column type definition in '{$table}'.'{$column}'"); @@ -170,12 +157,6 @@ protected function parse(string $table, string $column, string $definition): arr return $type; } - /** - * @param array $type - * @param string $flag - * - * @return bool - */ protected function hasFlag(array $type, string $flag): bool { return in_array($flag, $type['flags'], true); @@ -185,8 +166,6 @@ protected function hasFlag(array $type, string $flag): bool * Cast default value based on column type. Required to prevent conflicts when not nullable * column added to existed table with data in. * - * @param AbstractColumn $column - * * @return mixed */ protected function castDefault(AbstractColumn $column) diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 82810de5..5a9e9977 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -13,7 +13,7 @@ $drivers = [ 'sqlite' => new Config\SQLiteDriverConfig( queryCache: true, - options:[ + options: [ 'logQueryParameters' => true, ], ), @@ -49,7 +49,7 @@ connection: new Config\SQLServer\DsnConnectionConfig( 'sqlsrv:Server=127.0.0.1,11433;Database=tempdb;TrustServerCertificate=true', user: 'SA', - password: 'YourStrong!Passw0rd' + password: 'YourStrong!Passw0rd', ), queryCache: true, options: [ @@ -66,5 +66,5 @@ ] + ( $db === null ? $drivers - : array_intersect_key($drivers, array_flip((array)$db)) + : array_intersect_key($drivers, array_flip((array) $db)) ); diff --git a/tests/generate-case.php b/tests/generate-case.php index 8fb36d1e..43e6a836 100644 --- a/tests/generate-case.php +++ b/tests/generate-case.php @@ -33,7 +33,7 @@ function defaultCaseName(string $integrationDir): string function copyTemplateFiles(string $copyDir, string $caseTemplateDirName): void { $caseTemplateDir = __DIR__ . '/ORM/Functional/Driver/Common/Integration/' . $caseTemplateDirName; - if (!file_exists($caseTemplateDir) || !is_dir($caseTemplateDir)) { + if (!\file_exists($caseTemplateDir) || !\is_dir($caseTemplateDir)) { echo "Error. template folder '$caseTemplateDir' does not exists\n"; exit(1); } @@ -41,24 +41,24 @@ function copyTemplateFiles(string $copyDir, string $caseTemplateDirName): void echo \sprintf("Using template files from '%s'...\n", $caseTemplateDir); $rii = new RecursiveIteratorIterator( - new RecursiveDirectoryIterator($caseTemplateDir, FilesystemIterator::SKIP_DOTS) + new RecursiveDirectoryIterator($caseTemplateDir, FilesystemIterator::SKIP_DOTS), ); foreach ($rii as $file) { $filePath = $file->getRealPath(); $target = \substr($filePath, \strlen($caseTemplateDir)); // creating directory... - $dirName = dirname($copyDir . $target); + $dirName = \dirname($copyDir . $target); if (!\is_dir($dirName)) { \mkdir($dirName, recursive: true); } - $contents = \str_replace($caseTemplateDirName, basename($copyDir), \file_get_contents($filePath)); + $contents = \str_replace($caseTemplateDirName, \basename($copyDir), \file_get_contents($filePath)); \file_put_contents($copyDir . $target, $contents); } } -$options = getopt('', [ +$options = \getopt('', [ 'case-name:', 'template:', ]); @@ -67,12 +67,12 @@ function copyTemplateFiles(string $copyDir, string $caseTemplateDirName): void ? $integrationDir . DIRECTORY_SEPARATOR . $options['case-name'] : defaultCaseName($integrationDir); -if (file_exists($copyDir)) { +if (\file_exists($copyDir)) { echo "Error. Tests folder `$copyDir` already exists\n"; exit(1); } -echo \sprintf("Generating new test case '%s'... \n", basename($copyDir)); +echo \sprintf("Generating new test case '%s'... \n", \basename($copyDir)); \mkdir($copyDir); $copyDir = \realpath($copyDir); diff --git a/tests/generate.php b/tests/generate.php index 3a6eaaff..630f03d3 100644 --- a/tests/generate.php +++ b/tests/generate.php @@ -65,7 +65,7 @@ $path = str_replace( [\str_replace('\\', '/', __DIR__), 'ORM/Functional/Driver/Common/'], '', - \str_replace('\\', '/', $class->getFileName()) + \str_replace('\\', '/', $class->getFileName()), ); $path = ltrim($path, '/'); @@ -82,7 +82,7 @@ $namespace = str_replace( 'Cycle\\ORM\\Tests\\Functional\\Driver\\Common', $details['namespace'], - $class->getNamespaceName() + $class->getNamespaceName(), ); if (!is_dir($dir)) { @@ -116,8 +116,8 @@ class %s extends CommonClass $class->getName(), $driver, $class->getShortName(), - $driver - ) + $driver, + ), ); } }