diff --git a/README.md b/README.md index c0542cb..fabc2b0 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ console app or you can also do this programmatically through the `PSX\Sql\Genera use PSX\Sql\Generator\Generator; -$connection = null; // a doctrine DBAL connection +$connection = null; // a doctrine DBAL connection $target = __DIR__; $generator = new Generator($connection, 'Acme\\Table'); @@ -44,12 +44,15 @@ The following are basic examples how you can work with a generated table class. use PSX\Sql\Condition; use PSX\Sql\OrderBy; use PSX\Sql\TableManager; +use PSX\Sql\Tests\Generator\SqlTableTestTable; +use PSX\Sql\Tests\Generator\SqlTableTestColumn; +use PSX\Sql\Tests\Generator\SqlTableTestRow; $connection = null; // a doctrine DBAL connection $tableManager = new TableManager($connection); -/** @var \PSX\Sql\Tests\Generator\SqlTableTestTable $table */ -$table = $tableManager->getTable(\PSX\Sql\Tests\Generator\SqlTableTestTable::class); +/** @var SqlTableTestTable $table */ +$table = $tableManager->getTable(SqlTableTestTable::class); // returns by default 16 entries from the table ordered by the primary column descending $table->findAll(); @@ -58,7 +61,7 @@ $table->findAll(); $table->findAll(startIndex: 0, count: 12); // orders the entries after the column "id" descending -$table->findAll(startIndex: 0, count: 12, sortBy: 'id', sortOrder: OrderBy::DESC); +$table->findAll(startIndex: 0, count: 12, sortBy: SqlTableTestColumn::ID, sortOrder: OrderBy::DESC); // returns all rows which match the specified title $table->findByTitle('foo%'); @@ -70,7 +73,7 @@ $table->find(1); $table->getCount(); // creates a new row -$row = new \PSX\Sql\Tests\Generator\SqlTableTestRow(); +$row = new SqlTableTestRow(); $row->setTitle('foo'); $table->create($row); @@ -103,19 +106,19 @@ class SqlTableTestTable extends \PSX\Sql\TableAbstract public const COLUMN_ID = 'id'; public const COLUMN_TITLE = 'title'; public const COLUMN_DATE = 'date'; - public function getName() : string + public function getName(): string { return self::NAME; } - public function getColumns() : array + public function getColumns(): array { - return array(self::COLUMN_ID => 0x3020000a, self::COLUMN_TITLE => 0xa00020, self::COLUMN_DATE => 0x800000); + return [self::COLUMN_ID => 0x3020000a, self::COLUMN_TITLE => 0xa00020, self::COLUMN_DATE => 0x800000]; } /** * @return array<\PSX\Sql\Tests\Generator\SqlTableTestRow> * @throws \PSX\Sql\Exception\QueryException */ - public function findAll(?\PSX\Sql\Condition $condition = null, ?int $startIndex = null, ?int $count = null, ?string $sortBy = null, ?\PSX\Sql\OrderBy $sortOrder = null) : array + public function findAll(?\PSX\Sql\Condition $condition = null, ?int $startIndex = null, ?int $count = null, ?\PSX\Sql\Tests\Generator\SqlTableTestColumn $sortBy = null, ?\PSX\Sql\OrderBy $sortOrder = null): array { return $this->doFindAll($condition, $startIndex, $count, $sortBy, $sortOrder); } @@ -123,21 +126,21 @@ class SqlTableTestTable extends \PSX\Sql\TableAbstract * @return array<\PSX\Sql\Tests\Generator\SqlTableTestRow> * @throws \PSX\Sql\Exception\QueryException */ - public function findBy(\PSX\Sql\Condition $condition, ?int $startIndex = null, ?int $count = null, ?string $sortBy = null, ?\PSX\Sql\OrderBy $sortOrder = null) : array + public function findBy(\PSX\Sql\Condition $condition, ?int $startIndex = null, ?int $count = null, ?\PSX\Sql\Tests\Generator\SqlTableTestColumn $sortBy = null, ?\PSX\Sql\OrderBy $sortOrder = null): array { return $this->doFindBy($condition, $startIndex, $count, $sortBy, $sortOrder); } /** * @throws \PSX\Sql\Exception\QueryException */ - public function findOneBy(\PSX\Sql\Condition $condition) : ?\PSX\Sql\Tests\Generator\SqlTableTestRow + public function findOneBy(\PSX\Sql\Condition $condition): ?\PSX\Sql\Tests\Generator\SqlTableTestRow { return $this->doFindOneBy($condition); } /** * @throws \PSX\Sql\Exception\QueryException */ - public function find(int $id) : ?\PSX\Sql\Tests\Generator\SqlTableTestRow + public function find(int $id): ?\PSX\Sql\Tests\Generator\SqlTableTestRow { $condition = \PSX\Sql\Condition::withAnd(); $condition->equals('id', $id); @@ -147,7 +150,7 @@ class SqlTableTestTable extends \PSX\Sql\TableAbstract * @return array<\PSX\Sql\Tests\Generator\SqlTableTestRow> * @throws \PSX\Sql\Exception\QueryException */ - public function findById(int $value, ?int $startIndex = null, ?int $count = null, ?string $sortBy = null, ?\PSX\Sql\OrderBy $sortOrder = null) : array + public function findById(int $value, ?int $startIndex = null, ?int $count = null, ?\PSX\Sql\Tests\Generator\SqlTableTestColumn $sortBy = null, ?\PSX\Sql\OrderBy $sortOrder = null): array { $condition = \PSX\Sql\Condition::withAnd(); $condition->equals('id', $value); @@ -156,7 +159,7 @@ class SqlTableTestTable extends \PSX\Sql\TableAbstract /** * @throws \PSX\Sql\Exception\QueryException */ - public function findOneById(int $value) : ?\PSX\Sql\Tests\Generator\SqlTableTestRow + public function findOneById(int $value): ?\PSX\Sql\Tests\Generator\SqlTableTestRow { $condition = \PSX\Sql\Condition::withAnd(); $condition->equals('id', $value); @@ -165,7 +168,7 @@ class SqlTableTestTable extends \PSX\Sql\TableAbstract /** * @throws \PSX\Sql\Exception\ManipulationException */ - public function updateById(int $value, \PSX\Sql\Tests\Generator\SqlTableTestRow $record) : int + public function updateById(int $value, \PSX\Sql\Tests\Generator\SqlTableTestRow $record): int { $condition = \PSX\Sql\Condition::withAnd(); $condition->equals('id', $value); @@ -174,7 +177,7 @@ class SqlTableTestTable extends \PSX\Sql\TableAbstract /** * @throws \PSX\Sql\Exception\ManipulationException */ - public function deleteById(int $value) : int + public function deleteById(int $value): int { $condition = \PSX\Sql\Condition::withAnd(); $condition->equals('id', $value); @@ -184,7 +187,7 @@ class SqlTableTestTable extends \PSX\Sql\TableAbstract * @return array<\PSX\Sql\Tests\Generator\SqlTableTestRow> * @throws \PSX\Sql\Exception\QueryException */ - public function findByTitle(string $value, ?int $startIndex = null, ?int $count = null, ?string $sortBy = null, ?\PSX\Sql\OrderBy $sortOrder = null) : array + public function findByTitle(string $value, ?int $startIndex = null, ?int $count = null, ?\PSX\Sql\Tests\Generator\SqlTableTestColumn $sortBy = null, ?\PSX\Sql\OrderBy $sortOrder = null): array { $condition = \PSX\Sql\Condition::withAnd(); $condition->like('title', $value); @@ -193,7 +196,7 @@ class SqlTableTestTable extends \PSX\Sql\TableAbstract /** * @throws \PSX\Sql\Exception\QueryException */ - public function findOneByTitle(string $value) : ?\PSX\Sql\Tests\Generator\SqlTableTestRow + public function findOneByTitle(string $value): ?\PSX\Sql\Tests\Generator\SqlTableTestRow { $condition = \PSX\Sql\Condition::withAnd(); $condition->like('title', $value); @@ -202,7 +205,7 @@ class SqlTableTestTable extends \PSX\Sql\TableAbstract /** * @throws \PSX\Sql\Exception\ManipulationException */ - public function updateByTitle(string $value, \PSX\Sql\Tests\Generator\SqlTableTestRow $record) : int + public function updateByTitle(string $value, \PSX\Sql\Tests\Generator\SqlTableTestRow $record): int { $condition = \PSX\Sql\Condition::withAnd(); $condition->like('title', $value); @@ -211,7 +214,7 @@ class SqlTableTestTable extends \PSX\Sql\TableAbstract /** * @throws \PSX\Sql\Exception\ManipulationException */ - public function deleteByTitle(string $value) : int + public function deleteByTitle(string $value): int { $condition = \PSX\Sql\Condition::withAnd(); $condition->like('title', $value); @@ -221,7 +224,7 @@ class SqlTableTestTable extends \PSX\Sql\TableAbstract * @return array<\PSX\Sql\Tests\Generator\SqlTableTestRow> * @throws \PSX\Sql\Exception\QueryException */ - public function findByDate(\PSX\DateTime\LocalDateTime $value, ?int $startIndex = null, ?int $count = null, ?string $sortBy = null, ?\PSX\Sql\OrderBy $sortOrder = null) : array + public function findByDate(\PSX\DateTime\LocalDateTime $value, ?int $startIndex = null, ?int $count = null, ?\PSX\Sql\Tests\Generator\SqlTableTestColumn $sortBy = null, ?\PSX\Sql\OrderBy $sortOrder = null): array { $condition = \PSX\Sql\Condition::withAnd(); $condition->equals('date', $value); @@ -230,7 +233,7 @@ class SqlTableTestTable extends \PSX\Sql\TableAbstract /** * @throws \PSX\Sql\Exception\QueryException */ - public function findOneByDate(\PSX\DateTime\LocalDateTime $value) : ?\PSX\Sql\Tests\Generator\SqlTableTestRow + public function findOneByDate(\PSX\DateTime\LocalDateTime $value): ?\PSX\Sql\Tests\Generator\SqlTableTestRow { $condition = \PSX\Sql\Condition::withAnd(); $condition->equals('date', $value); @@ -239,7 +242,7 @@ class SqlTableTestTable extends \PSX\Sql\TableAbstract /** * @throws \PSX\Sql\Exception\ManipulationException */ - public function updateByDate(\PSX\DateTime\LocalDateTime $value, \PSX\Sql\Tests\Generator\SqlTableTestRow $record) : int + public function updateByDate(\PSX\DateTime\LocalDateTime $value, \PSX\Sql\Tests\Generator\SqlTableTestRow $record): int { $condition = \PSX\Sql\Condition::withAnd(); $condition->equals('date', $value); @@ -248,7 +251,7 @@ class SqlTableTestTable extends \PSX\Sql\TableAbstract /** * @throws \PSX\Sql\Exception\ManipulationException */ - public function deleteByDate(\PSX\DateTime\LocalDateTime $value) : int + public function deleteByDate(\PSX\DateTime\LocalDateTime $value): int { $condition = \PSX\Sql\Condition::withAnd(); $condition->equals('date', $value); @@ -257,42 +260,42 @@ class SqlTableTestTable extends \PSX\Sql\TableAbstract /** * @throws \PSX\Sql\Exception\ManipulationException */ - public function create(\PSX\Sql\Tests\Generator\SqlTableTestRow $record) : int + public function create(\PSX\Sql\Tests\Generator\SqlTableTestRow $record): int { return $this->doCreate($record->toRecord()); } /** * @throws \PSX\Sql\Exception\ManipulationException */ - public function update(\PSX\Sql\Tests\Generator\SqlTableTestRow $record) : int + public function update(\PSX\Sql\Tests\Generator\SqlTableTestRow $record): int { return $this->doUpdate($record->toRecord()); } /** * @throws \PSX\Sql\Exception\ManipulationException */ - public function updateBy(\PSX\Sql\Condition $condition, \PSX\Sql\Tests\Generator\SqlTableTestRow $record) : int + public function updateBy(\PSX\Sql\Condition $condition, \PSX\Sql\Tests\Generator\SqlTableTestRow $record): int { return $this->doUpdateBy($condition, $record->toRecord()); } /** * @throws \PSX\Sql\Exception\ManipulationException */ - public function delete(\PSX\Sql\Tests\Generator\SqlTableTestRow $record) : int + public function delete(\PSX\Sql\Tests\Generator\SqlTableTestRow $record): int { return $this->doDelete($record->toRecord()); } /** * @throws \PSX\Sql\Exception\ManipulationException */ - public function deleteBy(\PSX\Sql\Condition $condition) : int + public function deleteBy(\PSX\Sql\Condition $condition): int { return $this->doDeleteBy($condition); } /** * @param array $row */ - protected function newRecord(array $row) : \PSX\Sql\Tests\Generator\SqlTableTestRow + protected function newRecord(array $row): \PSX\Sql\Tests\Generator\SqlTableTestRow { return \PSX\Sql\Tests\Generator\SqlTableTestRow::from($row); } @@ -313,49 +316,67 @@ class SqlTableTestRow implements \JsonSerializable, \PSX\Record\RecordableInterf private ?int $id = null; private ?string $title = null; private ?\PSX\DateTime\LocalDateTime $date = null; - public function setId(int $id) : void + public function setId(int $id): void { $this->id = $id; } - public function getId() : int + public function getId(): int { - return $this->id; + return $this->id ?? throw new \PSX\Sql\Exception\NoValueAvailable('No value for required column "id" was provided'); } - public function setTitle(string $title) : void + public function setTitle(string $title): void { $this->title = $title; } - public function getTitle() : string + public function getTitle(): string { - return $this->title; + return $this->title ?? throw new \PSX\Sql\Exception\NoValueAvailable('No value for required column "title" was provided'); } - public function setDate(\PSX\DateTime\LocalDateTime $date) : void + public function setDate(\PSX\DateTime\LocalDateTime $date): void { $this->date = $date; } - public function getDate() : \PSX\DateTime\LocalDateTime + public function getDate(): \PSX\DateTime\LocalDateTime { - return $this->date; + return $this->date ?? throw new \PSX\Sql\Exception\NoValueAvailable('No value for required column "date" was provided'); } - public function toRecord() : \PSX\Record\RecordInterface + public function toRecord(): \PSX\Record\RecordInterface { + /** @var \PSX\Record\Record $record */ $record = new \PSX\Record\Record(); $record->put('id', $this->id); $record->put('title', $this->title); $record->put('date', $this->date); return $record; } - public function jsonSerialize() : object + public function jsonSerialize(): object { return (object) $this->toRecord()->getAll(); } - public static function from(array|\ArrayAccess $data) : self + public static function from(array|\ArrayAccess $data): self { $row = new self(); - $row->id = $data['id'] ?? null; - $row->title = $data['title'] ?? null; - $row->date = isset($data['date']) ? \PSX\DateTime\LocalDateTime::from($data['date']) : null; + $row->id = isset($data['id']) && is_int($data['id']) ? $data['id'] : null; + $row->title = isset($data['title']) && is_string($data['title']) ? $data['title'] : null; + $row->date = isset($data['date']) && $data['date'] instanceof \DateTimeInterface ? \PSX\DateTime\LocalDateTime::from($data['date']) : null; return $row; } } ``` + +## Column + +The following is an example of a generated table column. + +```php + + * + * Copyright 2010-2023 Christoph Kappestein + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace PSX\Sql; + +/** + * Represents a column + * + * @author Christoph Kappestein + * @license http://www.apache.org/licenses/LICENSE-2.0 + * @link https://phpsx.org + */ +interface ColumnInterface extends \BackedEnum +{ +} diff --git a/src/Generator/Generator.php b/src/Generator/Generator.php index 30e70b9..b0a8024 100644 --- a/src/Generator/Generator.php +++ b/src/Generator/Generator.php @@ -26,6 +26,8 @@ use Doctrine\DBAL\Schema\Table; use Doctrine\DBAL\Types; use PhpParser\Builder\Class_; +use PhpParser\Builder\Declaration; +use PhpParser\Builder\Enum_; use PhpParser\BuilderFactory; use PhpParser\Comment\Doc; use PhpParser\Modifiers; @@ -38,6 +40,7 @@ use PSX\Record\Record; use PSX\Record\RecordableInterface; use PSX\Record\RecordInterface; +use PSX\Sql\ColumnInterface; use PSX\Sql\Condition; use PSX\Sql\Exception\GeneratorException; use PSX\Sql\Exception\ManipulationException; @@ -90,12 +93,16 @@ public function generate(): \Generator $modelClassName = $this->normalizeName($tableName) . 'Row'; $repositoryClassName = $this->normalizeName($tableName) . 'Table'; + $columnClassName = $this->normalizeName($tableName) . 'Column'; $class = $this->generateModel($modelClassName, $table); yield $modelClassName => $this->prettyPrint($class); - $class = $this->generateRepository($repositoryClassName, $modelClassName, $table); + $class = $this->generateRepository($repositoryClassName, $modelClassName, $columnClassName, $table); yield $repositoryClassName => $this->prettyPrint($class); + + $class = $this->generateColumn($columnClassName, $repositoryClassName, $table); + yield $columnClassName => $this->prettyPrint($class); } } @@ -272,13 +279,10 @@ private function buildFrom(Class_ $class, array $columns): void $class->addStmt($fromArray); } - private function generateRepository(string $className, string $rowClass, Table $table): Class_ + private function generateRepository(string $className, string $rowClass, string $columnClass, Table $table): Class_ { - if ($this->namespace !== null) { - $rowClass = '\\' . $this->namespace . '\\' . $rowClass; - } else { - $rowClass = '\\' . $rowClass; - } + $rowClass = $this->namespace !== null ? '\\' . $this->namespace . '\\' . $rowClass : '\\' . $rowClass; + $columnClass = $this->namespace !== null ? '\\' . $this->namespace . '\\' . $columnClass : '\\' . $columnClass; $class = $this->factory->class($className); $class->extend('\\' . TableAbstract::class); @@ -287,13 +291,13 @@ private function generateRepository(string $className, string $rowClass, Table $ $this->buildConstants($class, $table); $this->buildGetName($class); $this->buildGetColumns($class, $table); - $this->buildFindAll($class, $rowClass); - $this->buildFindBy($class, $rowClass); + $this->buildFindAll($class, $rowClass, $columnClass); + $this->buildFindBy($class, $rowClass, $columnClass); $this->buildFindOneBy($class, $rowClass); $this->buildFind($class, $table, $rowClass); foreach ($table->getColumns() as $column) { - $this->buildFindByForColumn($class, $column, $rowClass); + $this->buildFindByForColumn($class, $column, $rowClass, $columnClass); $this->buildFindOneByForColumn($class, $column, $rowClass); $this->buildUpdateByForColumn($class, $column, $rowClass); $this->buildDeleteByForColumn($class, $column); @@ -387,7 +391,7 @@ private function buildFind(Class_ $class, Table $table, string $rowClass): void $class->addStmt($method); } - private function buildFindAll(Class_ $class, string $rowClass): void + private function buildFindAll(Class_ $class, string $rowClass, string $columnClass): void { $methodCall = new Node\Expr\MethodCall(new Node\Expr\Variable('this'), new Node\Identifier('doFindAll'), [ new Node\Arg(new Node\Expr\Variable('condition')), @@ -404,13 +408,13 @@ private function buildFindAll(Class_ $class, string $rowClass): void $method->addParam(new Node\Param(new Node\Expr\Variable('condition'), new Node\Expr\ConstFetch(new Node\Name('null')), new Node\NullableType(new Node\Name('\\' . Condition::class)))); $method->addParam(new Node\Param(new Node\Expr\Variable('startIndex'), new Node\Expr\ConstFetch(new Node\Name('null')), new Node\NullableType(new Node\Identifier('int')))); $method->addParam(new Node\Param(new Node\Expr\Variable('count'), new Node\Expr\ConstFetch(new Node\Name('null')), new Node\NullableType(new Node\Identifier('int')))); - $method->addParam(new Node\Param(new Node\Expr\Variable('sortBy'), new Node\Expr\ConstFetch(new Node\Name('null')), new Node\NullableType(new Node\Identifier('string')))); + $method->addParam(new Node\Param(new Node\Expr\Variable('sortBy'), new Node\Expr\ConstFetch(new Node\Name('null')), new Node\NullableType(new Node\Name($columnClass)))); $method->addParam(new Node\Param(new Node\Expr\Variable('sortOrder'), new Node\Expr\ConstFetch(new Node\Name('null')), new Node\NullableType(new Node\Name('\\' . OrderBy::class)))); $method->addStmt(new Node\Stmt\Return_($methodCall)); $class->addStmt($method); } - private function buildFindBy(Class_ $class, string $rowClass): void + private function buildFindBy(Class_ $class, string $rowClass, string $columnClass): void { $methodCall = new Node\Expr\MethodCall(new Node\Expr\Variable('this'), new Node\Identifier('doFindBy'), [ new Node\Arg(new Node\Expr\Variable('condition')), @@ -427,7 +431,7 @@ private function buildFindBy(Class_ $class, string $rowClass): void $method->addParam(new Node\Param(new Node\Expr\Variable('condition'), null, new Node\Name('\\' . Condition::class))); $method->addParam(new Node\Param(new Node\Expr\Variable('startIndex'), new Node\Expr\ConstFetch(new Node\Name('null')), new Node\NullableType(new Node\Identifier('int')))); $method->addParam(new Node\Param(new Node\Expr\Variable('count'), new Node\Expr\ConstFetch(new Node\Name('null')), new Node\NullableType(new Node\Identifier('int')))); - $method->addParam(new Node\Param(new Node\Expr\Variable('sortBy'), new Node\Expr\ConstFetch(new Node\Name('null')), new Node\NullableType(new Node\Identifier('string')))); + $method->addParam(new Node\Param(new Node\Expr\Variable('sortBy'), new Node\Expr\ConstFetch(new Node\Name('null')), new Node\NullableType(new Node\Name($columnClass)))); $method->addParam(new Node\Param(new Node\Expr\Variable('sortOrder'), new Node\Expr\ConstFetch(new Node\Name('null')), new Node\NullableType(new Node\Name('\\' . OrderBy::class)))); $method->addStmt(new Node\Stmt\Return_($methodCall)); $class->addStmt($method); @@ -448,7 +452,7 @@ private function buildFindOneBy(Class_ $class, string $rowClass): void $class->addStmt($method); } - private function buildFindByForColumn(Class_ $class, Column $column, string $rowClass): void + private function buildFindByForColumn(Class_ $class, Column $column, string $rowClass, string $columnClass): void { $methodCall = new Node\Expr\MethodCall(new Node\Expr\Variable('this'), new Node\Identifier('doFindBy'), [ new Node\Arg(new Node\Expr\Variable('condition')), @@ -467,7 +471,7 @@ private function buildFindByForColumn(Class_ $class, Column $column, string $row $method->addParam(new Node\Param(new Node\Expr\Variable('value'), null, new Node\Identifier($type))); $method->addParam(new Node\Param(new Node\Expr\Variable('startIndex'), new Node\Expr\ConstFetch(new Node\Name('null')), new Node\NullableType(new Node\Identifier('int')))); $method->addParam(new Node\Param(new Node\Expr\Variable('count'), new Node\Expr\ConstFetch(new Node\Name('null')), new Node\NullableType(new Node\Identifier('int')))); - $method->addParam(new Node\Param(new Node\Expr\Variable('sortBy'), new Node\Expr\ConstFetch(new Node\Name('null')), new Node\NullableType(new Node\Identifier('string')))); + $method->addParam(new Node\Param(new Node\Expr\Variable('sortBy'), new Node\Expr\ConstFetch(new Node\Name('null')), new Node\NullableType(new Node\Name($columnClass)))); $method->addParam(new Node\Param(new Node\Expr\Variable('sortOrder'), new Node\Expr\ConstFetch(new Node\Name('null')), new Node\NullableType(new Node\Name('\\' . OrderBy::class)))); $method->addStmt(new Node\Stmt\Expression(new Node\Expr\Assign(new Node\Expr\Variable('condition'), new Node\Expr\StaticCall(new Node\Name('\\' . Condition::class), new Node\Identifier('withAnd'))))); $method->addStmt(new Node\Stmt\Expression(new Node\Expr\MethodCall(new Node\Expr\Variable('condition'), new Node\Identifier($this->getOperatorForColumn($column)), [ @@ -636,6 +640,25 @@ private function buildNewRecord(Class_ $class, string $rowClass): void $class->addStmt($method); } + private function generateColumn(string $className, string $repositoryClass, Table $table): Enum_ + { + $tableClass = $this->namespace !== null ? '\\' . $this->namespace . '\\' . $repositoryClass : '\\' . $repositoryClass; + + $enum = $this->factory->enum($className); + $enum->implement('\\' . ColumnInterface::class); + $enum->setScalarType('string'); + + $columns = $table->getColumns(); + foreach ($columns as $column) { + $caseName = strtoupper($column->getName()); + $constName = 'COLUMN_' . strtoupper($column->getName()); + + $enum->addStmt(new Node\Stmt\EnumCase(new Node\Identifier($caseName), new Node\Expr\ClassConstFetch(new Node\Name($tableClass), new Node\Identifier($constName)))); + } + + return $enum; + } + private function normalizeName(string $name): string { return str_replace(' ', '', ucwords(str_replace('_', ' ', $name))); @@ -661,15 +684,15 @@ private function buildComment(array $tags): string return '/**' . "\n" . implode("\n", $lines) . "\n" . ' */'; } - private function prettyPrint(Class_ $class): string + private function prettyPrint(Declaration $declaration): string { if ($this->namespace !== null) { $namespace = $this->factory->namespace($this->namespace); - $namespace->addStmt($class); + $namespace->addStmt($declaration); return $this->printer->prettyPrint([$namespace->getNode()]); } else { - return $this->printer->prettyPrint([$class->getNode()]); + return $this->printer->prettyPrint([$declaration->getNode()]); } } diff --git a/src/TableAbstract.php b/src/TableAbstract.php index 011a042..009c6a0 100644 --- a/src/TableAbstract.php +++ b/src/TableAbstract.php @@ -183,7 +183,7 @@ protected function serializeType(mixed $value, int $type): string * @throws QueryException * @return array */ - protected function doFindAll(?Condition $condition = null, ?int $startIndex = null, ?int $count = null, ?string $sortBy = null, ?OrderBy $sortOrder = null): array + protected function doFindAll(?Condition $condition = null, ?int $startIndex = null, ?int $count = null, string|ColumnInterface|null $sortBy = null, ?OrderBy $sortOrder = null): array { $startIndex = $startIndex !== null ? $startIndex : 0; $count = $count !== null && $count > 0 ? $count : $this->limit(); @@ -191,7 +191,10 @@ protected function doFindAll(?Condition $condition = null, ?int $startIndex = nu $sortOrder = $sortOrder !== null ? $sortOrder : $this->sortOrder(); $columns = array_keys($this->getColumns()); - if (!in_array($sortBy, $columns)) { + + if ($sortBy instanceof ColumnInterface) { + $sortBy = $sortBy->value; + } elseif (!in_array($sortBy, $columns)) { $sortBy = $this->getPrimaryKeys()[0] ?? null; } @@ -218,7 +221,7 @@ protected function doFindAll(?Condition $condition = null, ?int $startIndex = nu * @throws QueryException * @return array */ - protected function doFindBy(Condition $condition, ?int $startIndex = null, ?int $count = null, ?string $sortBy = null, ?OrderBy $sortOrder = null): array + protected function doFindBy(Condition $condition, ?int $startIndex = null, ?int $count = null, string|ColumnInterface|null $sortBy = null, ?OrderBy $sortOrder = null): array { return $this->doFindAll($condition, $startIndex, $count, $sortBy, $sortOrder); } diff --git a/tests/Generator/GeneratorTest.php b/tests/Generator/GeneratorTest.php index 7f0f2c8..abd75ae 100644 --- a/tests/Generator/GeneratorTest.php +++ b/tests/Generator/GeneratorTest.php @@ -25,7 +25,6 @@ use PSX\DateTime\LocalDate; use PSX\DateTime\LocalDateTime; use PSX\DateTime\LocalTime; -use PSX\Record\Record; use PSX\Sql\Generator\Generator; use PSX\Sql\TableManager; use PSX\Sql\TableManagerInterface; diff --git a/tests/TableQueryTestTrait.php b/tests/TableQueryTestTrait.php index 5e6f234..38ee3b9 100644 --- a/tests/TableQueryTestTrait.php +++ b/tests/TableQueryTestTrait.php @@ -23,6 +23,7 @@ use PSX\Sql\Condition; use PSX\Sql\Fields; use PSX\Sql\OrderBy; +use PSX\Sql\Tests\Generator\HandlerCommentColumn; use PSX\Sql\Tests\Generator\HandlerCommentRow; /** @@ -147,7 +148,7 @@ public function testFindAllStartIndexAndCountDefault() public function testFindAllStartIndexAndCountDesc() { $table = $this->getTable(); - $result = $table->findAll(startIndex: 2, count: 2, sortBy: 'id', sortOrder: OrderBy::DESC); + $result = $table->findAll(startIndex: 2, count: 2, sortBy: HandlerCommentColumn::ID, sortOrder: OrderBy::DESC); $this->assertEquals(true, is_array($result)); $this->assertEquals(2, count($result)); @@ -173,7 +174,7 @@ public function testFindAllStartIndexAndCountDesc() public function testFindAllStartIndexAndCountAsc() { $table = $this->getTable(); - $result = $table->findAll(startIndex: 2, count: 2, sortBy: 'id', sortOrder: OrderBy::ASC); + $result = $table->findAll(startIndex: 2, count: 2, sortBy: HandlerCommentColumn::ID, sortOrder: OrderBy::ASC); $this->assertEquals(true, is_array($result)); $this->assertEquals(2, count($result)); @@ -199,7 +200,7 @@ public function testFindAllStartIndexAndCountAsc() public function testFindAllSortDesc() { $table = $this->getTable(); - $result = $table->findAll(startIndex: 0, count: 2, sortBy: 'id', sortOrder: OrderBy::DESC); + $result = $table->findAll(startIndex: 0, count: 2, sortBy: HandlerCommentColumn::ID, sortOrder: OrderBy::DESC); $this->assertEquals(true, is_array($result)); $this->assertEquals(2, count($result)); @@ -234,7 +235,7 @@ public function testFindAllSortDesc() public function testFindAllSortAsc() { $table = $this->getTable(); - $result = $table->findAll(startIndex: 0, count: 2, sortBy: 'id', sortOrder: OrderBy::ASC); + $result = $table->findAll(startIndex: 0, count: 2, sortBy: HandlerCommentColumn::ID, sortOrder: OrderBy::ASC); $this->assertEquals(true, is_array($result)); $this->assertEquals(2, count($result)); @@ -261,7 +262,7 @@ public function testFindAllCondition() { $table = $this->getTable(); $con = Condition::withAnd()->equals('userId', 1); - $result = $table->findAll(condition: $con, startIndex: 0, count: 16, sortBy: 'id', sortOrder: OrderBy::DESC); + $result = $table->findAll(condition: $con, startIndex: 0, count: 16, sortBy: HandlerCommentColumn::ID, sortOrder: OrderBy::DESC); $this->assertEquals(true, is_array($result)); $this->assertEquals(2, count($result)); @@ -291,7 +292,7 @@ public function testFindAllConditionAndConjunction() $con = Condition::withAnd(); $con->equals('userId', 1); $con->equals('userId', 3); - $result = $table->findAll(condition: $con, startIndex: 0, count: 16, sortBy: 'id', sortOrder: OrderBy::DESC); + $result = $table->findAll(condition: $con, startIndex: 0, count: 16, sortBy: HandlerCommentColumn::ID, sortOrder: OrderBy::DESC); $this->assertEquals(true, is_array($result)); $this->assertEquals(0, count($result)); @@ -300,7 +301,7 @@ public function testFindAllConditionAndConjunction() $con = Condition::withAnd(); $con->equals('userId', 1); $con->equals('title', 'foo'); - $result = $table->findAll(condition: $con, startIndex: 0, count: 16, sortBy: 'id', sortOrder: OrderBy::DESC); + $result = $table->findAll(condition: $con, startIndex: 0, count: 16, sortBy: HandlerCommentColumn::ID, sortOrder: OrderBy::DESC); $this->assertEquals(true, is_array($result)); $this->assertEquals(1, count($result)); @@ -324,7 +325,7 @@ public function testFindAllConditionOrConjunction() $con = Condition::withOr(); $con->equals('userId', 1); $con->equals('userId', 3); - $result = $table->findAll(condition: $con, startIndex: 0, count: 16, sortBy: 'id', sortOrder: OrderBy::DESC); + $result = $table->findAll(condition: $con, startIndex: 0, count: 16, sortBy: HandlerCommentColumn::ID, sortOrder: OrderBy::DESC); $this->assertEquals(true, is_array($result)); $this->assertEquals(3, count($result)); @@ -382,7 +383,7 @@ public function testFindBy() public function testFindByStartIndexCountOrder() { $table = $this->getTable(); - $result = $table->findBy(condition: Condition::withAnd()->equals('userId', 1), startIndex: 0, count: 1, sortBy: 'id', sortOrder: OrderBy::ASC); + $result = $table->findBy(condition: Condition::withAnd()->equals('userId', 1), startIndex: 0, count: 1, sortBy: HandlerCommentColumn::ID, sortOrder: OrderBy::ASC); $this->assertEquals(true, is_array($result)); $this->assertEquals(1, count($result));