From e3105e50783db1416e45143739d648e8e504cc61 Mon Sep 17 00:00:00 2001 From: noelma Date: Sun, 5 Dec 2021 20:06:03 +0100 Subject: [PATCH 1/2] feat: strict type for phpstan --- src/Field.php | 28 ++++-- src/Field/StringType.php | 2 - src/Request.php | 107 +++++++++++----------- src/RequestHandler.php | 105 +++++++++++++-------- src/RequestInterface.php | 88 +++++++++--------- src/Schema.php | 167 +++++++++++++++++----------------- src/Table.php | 15 +++ src/TableBuilder.php | 7 +- src/Where.php | 98 ++++++++++++++------ src/WhereHandler.php | 25 +++-- tests/unit/RequestTest.php | 56 ++++++++---- tests/unit/TableAlterTest.php | 4 +- 12 files changed, 418 insertions(+), 284 deletions(-) diff --git a/src/Field.php b/src/Field.php index 1392c44..9ab181c 100644 --- a/src/Field.php +++ b/src/Field.php @@ -17,6 +17,16 @@ * Pattern fluent pour la création et configuration des types de données. * * @author Mathieu NOËL + * + * @phpstan-type FieldToArray array{ + * _comment?: string, + * default?: null|scalar, + * length?: int, + * nullable?: bool, + * opt?: string, + * type: string, + * unsigned?: bool, + * } */ abstract class Field { @@ -33,7 +43,7 @@ abstract class Field protected const INVALID_ARGUMENT_MESSAGE = 'The value of the %s field must be of type %s: %s given.'; /** - * @var bool|null|numeric|string + * @var null|scalar */ protected $valueDefault; @@ -92,11 +102,11 @@ public function nullable(): self * Enregistre une valeur par défaut au champ précédent. * Lève une exception si la valeur par défaut ne correspond pas au type de valeur passée en paramètre. * - * @param bool|null|numeric|string $value Valeur à tester. + * @param null|scalar $value Valeur à tester. * * @throws ColumnsValueException * - * @return bool|null|numeric|string + * @return null|scalar */ abstract public function filterValue($value); @@ -104,7 +114,7 @@ abstract public function filterValue($value); * Enregistre une valeur par défaut au champ précédent. * Lève une exception si la valeur par défaut ne correspond pas au type de valeur passée en paramètre. * - * @param bool|null|numeric|string $value Valeur à tester. + * @param null|scalar $value Valeur à tester. * * @throws TableBuilderException * @@ -122,7 +132,7 @@ public function valueDefault($value) * * @throws ColumnsValueException * - * @return bool|null|numeric|string Valeur par defaut. + * @return null|scalar Valeur par defaut. */ public function getValueDefault() { @@ -178,14 +188,12 @@ public function setName(string $name): self /** * Retourne les données du champ. * - * @return array + * @return FieldToArray */ public function toArray(): array { - $data = []; - if (static::TYPE !== '') { - $data[ 'type' ] = static::TYPE; - } + $data[ 'type' ] = static::TYPE; + if ($this->isNullable) { $data[ 'nullable' ] = $this->isNullable; } diff --git a/src/Field/StringType.php b/src/Field/StringType.php index fb1f738..7c95675 100644 --- a/src/Field/StringType.php +++ b/src/Field/StringType.php @@ -10,8 +10,6 @@ namespace Queryflatfile\Field; -use Queryflatfile\Field; - /** * @author Mathieu NOËL */ diff --git a/src/Request.php b/src/Request.php index 52cb592..731077d 100644 --- a/src/Request.php +++ b/src/Request.php @@ -22,20 +22,23 @@ * Les requêtes se construisent avec le pattern fluent. * * @author Mathieu NOËL + * + * @phpstan-import-type RowData from Schema + * @phpstan-import-type TableData from Schema */ class Request extends RequestHandler { /** - * Toutes les configurations du schéma des champs utilisés. + * Tous les champs utilisés. * - * @var array + * @var Field[] */ - private $allColumnsSchema; + private $allFieldsSchema; /** * Les données de la table. * - * @var array + * @var TableData */ private $tableData = []; @@ -90,7 +93,7 @@ public function __toString(): string if ($this->where) { $output .= sprintf('WHERE %s ', (string) $this->where); } - foreach ($this->union as $union) { + foreach ($this->unions as $union) { $type = $union[ 'type' ] === self::UNION_SIMPLE ? 'UNION' : 'UNION ALL'; $subRequest = trim((string) $union[ 'request' ], ';'); $output .= sprintf('%s %s ', $type, $subRequest); @@ -133,23 +136,23 @@ public function setSchema(Schema $schema): self /** * Lit les données d'une table. * - * @param string $name Nom de la table. + * @param string $tableName Nom de la table. * * @return array Données de la table. */ - public function getTableData(string $name): array + public function getTableData(string $tableName): array { - return $this->schema->read($name); + return $this->schema->read($tableName); } /** * {@inheritdoc} */ - public function from(string $table): self + public function from(string $tableName): self { - parent::from($table); - $this->table = $this->schema->getTableSchema($table); - $this->tableData = $this->getTableData($table); + parent::from($tableName); + $this->table = $this->schema->getTableSchema($tableName); + $this->tableData = $this->getTableData($tableName); return $this; } @@ -162,7 +165,7 @@ public function from(string $table): self public function execute(): void { $this->filterFrom(); - $this->loadAllColumnsSchema(); + $this->loadAllFieldsSchema(); $this->filterSelect(); $this->filterWhere(); @@ -183,12 +186,12 @@ public function execute(): void /** * Retourne tous les résultats de la requête. * - * @return array les données + * @return TableData les données */ public function fetchAll(): array { $this->filterFrom(); - $this->loadAllColumnsSchema(); + $this->loadAllFieldsSchema(); $this->filterSelect(); $this->filterWhere(); $this->filterUnion(); @@ -209,7 +212,7 @@ public function fetchAll(): array $this->executeJoins($value[ 'type' ], $value[ 'table' ], $value[ 'where' ]); } - $limitHandel = $this->orderBy || $this->union; + $limitHandel = $this->orderBy || $this->unions; foreach ($this->tableData as $row) { /* WHERE */ if ($this->where && !$this->where->execute($row)) { @@ -233,7 +236,7 @@ public function fetchAll(): array } /* UNION */ - foreach ($this->union as $union) { + foreach ($this->unions as $union) { /* Si le retour est demandé en liste. */ $fetchAll = $union[ 'request' ]->fetchAll(); @@ -268,7 +271,7 @@ public function fetchAll(): array /** * Retourne le premier résultat de la requête. * - * @return array Résultat de la requête. + * @return RowData Résultat de la requête. */ public function fetch(): array { @@ -283,18 +286,18 @@ public function fetch(): array * Retourne les résultats de la requête sous forme de tableau simple, * composé uniquement du champ passé en paramètre ou du premier champ sélectionné. * - * @param string $name Nom du champ. - * @param string|null $key Clé des valeurs de la liste + * @param string $columnName Nom du champ. + * @param string|null $key Clé des valeurs de la liste * * @throws ColumnsNotFoundException * - * @return array Liste du champ passé en paramètre. + * @return array Liste du champ passé en paramètre. */ - public function lists(string $name, ?string $key = null): array + public function lists(string $columnName, ?string $key = null): array { $data = $this->fetchAll(); - return array_column($data, $name, $key); + return array_column($data, $columnName, $key); } /** @@ -303,10 +306,10 @@ public function lists(string $name, ?string $key = null): array public function init(): self { parent::init(); - $this->allColumnsSchema = []; - $this->execute = null; - $this->tableData = []; - $this->where = null; + $this->allFieldsSchema = []; + $this->execute = null; + $this->tableData = []; + $this->where = null; return $this; } @@ -337,21 +340,21 @@ protected static function arrayUniqueMultidimensional(array &$input): void * Execute les jointures. * * @param string $type - * @param string $table + * @param string $tableName * @param Where $where * * @return void */ - protected function executeJoins(string $type, string $table, Where $where): void + protected function executeJoins(string $type, string $tableName, Where $where): void { $result = []; - $rowTableNull = $this->getRowTableNull($table); + $rowTableNull = $this->getRowTableNull($tableName); $left = $type === self::JOIN_LEFT; $tableData = $left ? $this->tableData - : $this->getTableData($table); + : $this->getTableData($tableName); $tableJoin = $left - ? $this->getTableData($table) + ? $this->getTableData($tableName) : $this->tableData; foreach ($tableData as $row) { @@ -505,7 +508,7 @@ protected function executeUpdate(): void if ($this->where && !$this->where->execute($row)) { continue; } - $row = array_merge($row, $this->values); + $row = array_merge($row, $this->values[0]); } unset($row); } @@ -529,13 +532,13 @@ protected function executeDelete(): void /** * Charge les colonnes de la table courante et des tables de jointure. */ - private function loadAllColumnsSchema(): void + private function loadAllFieldsSchema(): void { - $this->allColumnsSchema = $this->table->getFields(); + $this->allFieldsSchema = $this->table->getFields(); foreach ($this->joins as $value) { - $this->allColumnsSchema = array_merge( - $this->allColumnsSchema, + $this->allFieldsSchema = array_merge( + $this->allFieldsSchema, $this->schema->getTableSchema($value[ 'table' ])->getFields() ); } @@ -631,16 +634,18 @@ private function filterOrderBy(): void private function filterUnion(): void { $count = count($this->columns); - foreach ($this->union as $request) { - if ($count != count($request[ 'request' ]->columns)) { - throw new ColumnsNotFoundException( - sprintf( - 'The number of fields in the selections are different: %s != %s', - implode(', ', $this->columns), - implode(', ', $request[ 'request' ]->columns) - ) - ); + foreach ($this->unions as $union) { + if ($count === count($union[ 'request' ]->getColumns())) { + continue; } + + throw new ColumnsNotFoundException( + sprintf( + 'The number of fields in the selections are different: %s != %s', + implode(', ', $this->columns), + implode(', ', $union[ 'request' ]->getColumns()) + ) + ); } } @@ -648,7 +653,7 @@ private function filterUnion(): void * Déclenche une exception si l'un des champs passés en paramètre diffère * des champs disponibles dans les tables. * - * @param array $columns Liste des champs. + * @param string[] $columns Liste des champs. * * @throws ColumnsNotFoundException */ @@ -656,7 +661,7 @@ private function diffColumns(array $columns): void { $diff = array_diff_key( array_flip($columns), - $this->allColumnsSchema + $this->allFieldsSchema ); if ($diff) { @@ -677,12 +682,12 @@ private function diffColumns(array $columns): void * Si des champs existent dans le schéma ils seront rajouté. Fonction utilisée * pour les jointures en cas d'absence de résultat. * - * @param string $table Nom de la table. + * @param string $tableName Nom de la table. */ - private function getRowTableNull(string $table): array + private function getRowTableNull(string $tableName): array { /* Prend les noms des champs de la table à joindre. */ - $rowTableKey = $this->schema->getTableSchema($table)->getFieldsName(); + $rowTableKey = $this->schema->getTableSchema($tableName)->getFieldsName(); /* Prend les noms des champs dans la requête précédente. */ if ($this->table->getFields() !== []) { $rowTableAllKey = $this->table->getFieldsName(); diff --git a/src/RequestHandler.php b/src/RequestHandler.php index 62d345d..3bef177 100644 --- a/src/RequestHandler.php +++ b/src/RequestHandler.php @@ -46,6 +46,11 @@ * @method Request notWhereGroup(\Closure $callable) Alias de la fonction de l'objet Queryflatfile\Where * @method Request orWhereGroup(\Closure $callable) Alias de la fonction de l'objet Queryflatfile\Where * @method Request orNotWhereGroup(\Closure $callable) Alias de la fonction de l'objet Queryflatfile\Where + * + * @phpstan-import-type TableData from Schema + * + * @phpstan-type Join array{type: string, table: string, where: Where} + * @phpstan-type Union array{request: RequestInterface, type: string} */ abstract class RequestHandler implements RequestInterface { @@ -55,12 +60,22 @@ abstract class RequestHandler implements RequestInterface protected const DELETE = 'delete'; + /** + * La valeur pour une union simple. + */ + protected const UNION_SIMPLE = 'simple'; + + /** + * La valeur pour une union totale. + */ + protected const UNION_ALL = 'all'; + /** * Le type d'exécution (delete|update|insert). * * @var string|null */ - protected $execute; + protected $execute = null; /** * Le nom de la table courante. @@ -72,21 +87,21 @@ abstract class RequestHandler implements RequestInterface /** * Les jointures à calculer. * - * @var array + * @var Join[] */ protected $joins = []; /** * Les unions. * - * @var array + * @var Union[] */ - protected $union = []; + protected $unions = []; /** * Les colonnes à trier. * - * @var array + * @var array */ protected $orderBy = []; @@ -121,7 +136,7 @@ abstract class RequestHandler implements RequestInterface /** * Les valeurs à insérer ou mettre à jour. * - * @var array + * @var TableData */ protected $values = []; @@ -171,9 +186,9 @@ public function delete() /** * {@inheritdoc} */ - public function from(string $table) + public function from(string $tableName) { - $this->from = $table; + $this->from = $tableName; return $this; } @@ -181,10 +196,18 @@ public function from(string $table) /** * {@inheritdoc} */ - public function insertInto(string $table, array $columns) + public function getColumns(): array + { + return $this->columns; + } + + /** + * {@inheritdoc} + */ + public function insertInto(string $tableName, array $columns) { $this->execute = self::INSERT; - $this->from($table)->select(...$columns); + $this->from($tableName)->select(...$columns); return $this; } @@ -192,14 +215,14 @@ public function insertInto(string $table, array $columns) /** * {@inheritdoc} */ - public function leftJoin(string $table, $column, string $operator = '', $value = null) + public function leftJoin(string $tableName, $column, string $operator = '', string $value ='') { if ($column instanceof \Closure) { - $this->joinGroup(self::JOIN_LEFT, $table, $column); + $this->joinGroup(self::JOIN_LEFT, $tableName, $column); return $this; } - $this->join(self::JOIN_LEFT, $table, $column, $operator, $value); + $this->join(self::JOIN_LEFT, $tableName, $column, $operator, $value); return $this; } @@ -219,9 +242,9 @@ public function limit(int $limit, int $offset = 0) /** * {@inheritdoc} */ - public function orderBy(string $columns, int $order = SORT_ASC) + public function orderBy(string $column, int $order = SORT_ASC) { - $this->orderBy[ $columns ] = $order; + $this->orderBy[ $column ] = $order; return $this; } @@ -229,14 +252,14 @@ public function orderBy(string $columns, int $order = SORT_ASC) /** * {@inheritdoc} */ - public function rightJoin(string $table, $column, string $operator = '', $value = null) + public function rightJoin(string $tableName, $column, string $operator = '', string $value = '') { if ($column instanceof \Closure) { - $this->joinGroup(self::JOIN_RIGHT, $table, $column); + $this->joinGroup(self::JOIN_RIGHT, $tableName, $column); return $this; } - $this->join(self::JOIN_RIGHT, $table, $column, $operator, $value); + $this->join(self::JOIN_RIGHT, $tableName, $column, $operator, $value); return $this; } @@ -256,9 +279,9 @@ public function select(string ...$columns) /** * {@inheritdoc} */ - public function union(RequestInterface $request, string $type = self::UNION_SIMPLE) + public function union(RequestInterface $request) { - $this->union[] = compact('request', 'type'); + $this->unions[] = [ 'request' => $request, 'type' => self::UNION_SIMPLE ]; return $this; } @@ -268,17 +291,19 @@ public function union(RequestInterface $request, string $type = self::UNION_SIMP */ public function unionAll(RequestInterface $request) { - return $this->union($request, self::UNION_ALL); + $this->unions[] = [ 'request' => $request, 'type' => self::UNION_ALL ]; + + return $this; } /** * {@inheritdoc} */ - public function update(string $table, array $columns) + public function update(string $tableName, array $columns) { - $this->execute = self::UPDATE; - $this->from($table)->select(...array_keys($columns)); - $this->values = $columns; + $this->execute = self::UPDATE; + $this->from($tableName)->select(...array_keys($columns)); + $this->values[ 0 ] = $columns; return $this; } @@ -308,7 +333,7 @@ protected function init() $this->offset = 0; $this->orderBy = []; $this->sumLimit = 0; - $this->union = []; + $this->unions = []; $this->values = []; return $this; @@ -317,24 +342,32 @@ protected function init() /** * Enregistre une jointure. * - * @param string $type Type de la jointure. - * @param string $table Nom de la table à joindre - * @param string $column Nom de la colonne d'une des tables précédentes. - * @param string $operator Opérateur logique ou null pour une closure. - * @param null|scalar $value Valeur ou une colonne de la table jointe (au format nom_table.colonne) + * @param string $type Type de la jointure. + * @param string $tableName Nom de la table à joindre + * @param string $column Nom de la colonne d'une des tables précédentes. + * @param string $operator Opérateur logique ou null pour une closure. + * @param string $value Valeur ou une colonne de la table jointe (au format nom_table.colonne) */ - private function join(string $type, string $table, string $column, string $operator, $value): void + private function join(string $type, string $tableName, string $column, string $operator, string $value): void { - $where = (new Where())->where($column, $operator, $value); + $where = new Where(); + $where->where($column, $operator, $value); - $this->joins[] = compact('type', 'table', 'where'); + $this->joins[] = [ 'type' => $type, 'table' => $tableName, 'where' => $where ]; } - private function joinGroup(string $type, string $table, \Closure $callable): void + /** + * Enregistre une jointure avec une condition groupée. + * + * @param string $type Type de la jointure. + * @param string $tableName Nom de la table à joindre + * @param \Closure $callable Nom de la colonne d'une des tables précédentes. + */ + private function joinGroup(string $type, string $tableName, \Closure $callable): void { $where = new Where(); call_user_func_array($callable, [ &$where ]); - $this->joins[] = compact('type', 'table', 'where'); + $this->joins[] = [ 'type' => $type, 'table' => $tableName, 'where' => $where ]; } } diff --git a/src/RequestInterface.php b/src/RequestInterface.php index 279d91d..a0ac4c0 100644 --- a/src/RequestInterface.php +++ b/src/RequestInterface.php @@ -17,6 +17,9 @@ * Ensemble des fonctions nécessaires à une requête. * * @author Mathieu NOËL + + * @phpstan-import-type RowData from Schema + * @phpstan-import-type TableData from Schema */ interface RequestInterface { @@ -25,16 +28,6 @@ interface RequestInterface */ public const ALL = 0; - /** - * La valeur pour une union simple. - */ - public const UNION_SIMPLE = 'simple'; - - /** - * La valeur pour une union totale. - */ - public const UNION_ALL = 'all'; - /** * Valeur pour un join gauche. */ @@ -45,54 +38,60 @@ interface RequestInterface */ public const JOIN_RIGHT = 'right'; + /** + * @return string + */ + public function __toString(): string; + /** * Enregistre les champs sélectionnées par la requête. * En cas d'absence de selection, la requêtes retournera toutes les champs. * - * @param string $columns Liste ou tableau des noms des colonnes. + * @param string ...$columns Liste ou tableau des noms des colonnes. * * @return $this */ public function select(string ...$columns); + /** + * @return string[] + */ + public function getColumns(): array; + /** * Enregistre le nom de la source des données principale de la requête. * - * @param string $table Nom de la table. + * @param string $tableName Nom de la table. * * @return $this */ - public function from(string $table); + public function from(string $tableName); /** * Enregistre une jointure gauche. * - * @param string $table Nom de la table à joindre. - * @param string|\Closure $column Nom de la colonne d'une des tables précédentes - * ou une closure pour affiner les conditions. - * @param string $operator Opérateur logique ou null pour une closure. - * @param scalar|null $value Valeur - * ou une colonne de la table jointe (au format nom_table.colonne) - * ou null pour une closure. + * @param string $tableName Nom de la table à joindre. + * @param string|\Closure $column Nom de la colonne d'une des tables précédentes + * ou une closure pour affiner les conditions. + * @param string $operator Opérateur logique ou null pour une closure. + * @param string $value Colonne de la table jointe (au format nom_table.colonne) * * @return $this */ - public function leftJoin(string $table, $column, string $operator = '', $value = null); + public function leftJoin(string $tableName, $column, string $operator = '', string $value = ''); /** * Enregistre une jointure droite. * - * @param string $table Nom de la table à joindre - * @param string|\Closure $column Nom de la colonne d'une des tables précédentes - * ou une closure pour affiner les conditions. - * @param string $operator Opérateur logique ou null pour une closure. - * @param scalar|null $value Valeur - * ou une colonne de la table jointe (au format nom_table.colonne) - * ou null pour une closure. + * @param string $tableName Nom de la table à joindre + * @param string|\Closure $column Nom de la colonne d'une des tables précédentes + * ou une closure pour affiner les conditions. + * @param string $operator Opérateur logique ou null pour une closure. + * @param string $value Colonne de la table jointe (au format nom_table.colonne) * * @return $this */ - public function rightJoin(string $table, $column, string $operator = '', $value = null); + public function rightJoin(string $tableName, $column, string $operator = '', string $value = ''); /** * Enregistre une limitation et un décalage au retour de la requête. @@ -107,30 +106,30 @@ public function limit(int $limit, int $offset = 0); /** * Enregistre un trie des résultats de la requête. * - * @param string $columns Colonnes à trier. - * @param int $order Ordre du trie (SORT_ASC|SORT_DESC). + * @param string $column Colonne à trier. + * @param int $order Ordre du trie (SORT_ASC|SORT_DESC). * * @return $this */ - public function orderBy(string $columns, int $order = SORT_ASC); + public function orderBy(string $column, int $order = SORT_ASC); /** * Enregistre l'action d'insertion de données. * Cette fonction doit-être suivie la fonction values(). * - * @param string $table Nom de la table. - * @param array $columns Liste des champs par ordre d'insertion dans - * la fonction values(). + * @param string $tableName Nom de la table. + * @param string[] $columns Liste des champs par ordre d'insertion dans + * la fonction values(). * * @return $this */ - public function insertInto(string $table, array $columns); + public function insertInto(string $tableName, array $columns); /** * Cette fonction doit suivre la fonction insertInto(). * Les valeurs doivent suivre le même ordre que les clés précédemment enregistrées. * - * @param array $columns Valeurs des champs. + * @param array $columns Valeurs des champs. * * @return $this */ @@ -139,12 +138,12 @@ public function values(array $columns); /** * Enregistre l'action de modification de données. * - * @param string $table Nom de la table. - * @param array $columns key=>value des données à modifier. + * @param string $tableName Nom de la table. + * @param RowData $columns key=>value des données à modifier. * * @return $this */ - public function update(string $table, array $columns); + public function update(string $tableName, array $columns); /** * Enregistre l'action de suppression des données. @@ -158,11 +157,10 @@ public function delete(); * Le résultat de l'union ne possède pas de doublon de ligne. * * @param RequestInterface $request Seconde requête. - * @param string $type (simple|all) Type d'union. * * @return $this */ - public function union(RequestInterface $request, string $type = self::UNION_SIMPLE); + public function union(RequestInterface $request); /** * Enregistre une union all entre 2 ensembles. @@ -177,14 +175,14 @@ public function unionAll(RequestInterface $request); /** * Retourne tous les résultats de la requête. * - * @return array les données + * @return TableData les données */ public function fetchAll(): array; /** * Retourne le premier résultat de la requête. * - * @return array Résultat de la requête. + * @return RowData Résultat de la requête. */ public function fetch(): array; @@ -197,7 +195,7 @@ public function fetch(): array; * * @throws ColumnsNotFoundException * - * @return array Liste du champ passé en paramètre. + * @return array Liste du champ passé en paramètre. */ public function lists(string $name, ?string $key = null): array; diff --git a/src/Schema.php b/src/Schema.php index ecf3aec..7f1c51e 100644 --- a/src/Schema.php +++ b/src/Schema.php @@ -25,6 +25,9 @@ * Pattern fluent pour la gestion d'un schéma de données. * * @author Mathieu NOËL + * + * @phpstan-type RowData array + * @phpstan-type TableData RowData[] */ class Schema { @@ -135,7 +138,7 @@ public function setPathRoot(string $root = ''): self /** * Modifie la valeur incrémentale d'une table. * - * @param string $table Nom de la table. + * @param string $tableName Nom de la table. * @param int $increment Nouvelle valeur incrémentale. * * @throws TableNotFoundException @@ -143,19 +146,19 @@ public function setPathRoot(string $root = ''): self * * @return bool Si le schéma d'incrémentaion est bien enregistré. */ - public function setIncrement(string $table, int $increment): bool + public function setIncrement(string $tableName, int $increment): bool { - if (!$this->hasTable($table)) { - throw new TableNotFoundException($table); + if (!$this->hasTable($tableName)) { + throw new TableNotFoundException($tableName); } - if (!$this->schema[ $table ]->hasIncrement()) { + if (!$this->schema[ $tableName ]->hasIncrement()) { throw new Exception( - sprintf('Table %s does not have an incremental value.', $table) + sprintf('Table %s does not have an incremental value.', $tableName) ); } - $this->schema[ $table ]->setIncrement($increment); + $this->schema[ $tableName ]->setIncrement($increment); return $this->save($this->name, $this->toArray()); } @@ -163,26 +166,26 @@ public function setIncrement(string $table, int $increment): bool /** * Retourne la valeur incrémentale d'une table. * - * @param string $table Nom de la table. + * @param string $tableName Nom de la table. * * @throws TableNotFoundException * @throws Exception * * @return int */ - public function getIncrement(string $table): int + public function getIncrement(string $tableName): int { - if (!$this->hasTable($table)) { - throw new TableNotFoundException($table); + if (!$this->hasTable($tableName)) { + throw new TableNotFoundException($tableName); } - if ($this->schema[ $table ]->getIncrement() === null) { + if ($this->schema[ $tableName ]->getIncrement() === null) { throw new Exception( - sprintf('Table %s does not have an incremental value.', $table) + sprintf('Table %s does not have an incremental value.', $tableName) ); } - return $this->schema[ $table ]->getIncrement(); + return $this->schema[ $tableName ]->getIncrement(); } /** @@ -209,19 +212,19 @@ public function getSchema(): array /** * Cherche le schéma de la table passée en paramètre. * - * @param string $table Nom de la table. + * @param string $tableName Nom de la table. * * @throws TableNotFoundException * * @return Table Schéma de la table. */ - public function getTableSchema(string $table): Table + public function getTableSchema(string $tableName): Table { - if (!$this->hasTable($table)) { - throw new TableNotFoundException($table); + if (!$this->hasTable($tableName)) { + throw new TableNotFoundException($tableName); } - return $this->getSchema()[ $table ]; + return $this->getSchema()[ $tableName ]; } /** @@ -234,8 +237,8 @@ public function dropSchema(): self $schema = $this->getSchema(); /* Supprime les fichiers des tables. */ - foreach (array_keys($schema) as $table) { - $this->delete($table); + foreach (array_keys($schema) as $tableName) { + $this->delete($tableName); } /* Supprime le fichier de schéma. */ @@ -257,23 +260,23 @@ public function dropSchema(): self /** * Créer une référence dans le schéma et le fichier de la table. * - * @param string $table Nom de la table. - * @param callable|null $callback fonction(TableBuilder $table) pour créer les champs. + * @param string $tableName Nom de la table. + * @param callable|null $callback fonction(TableBuilder $tableName) pour créer les champs. * * @throws Exception * * @return $this */ - public function createTable(string $table, ?callable $callback = null): self + public function createTable(string $tableName, ?callable $callback = null): self { - if ($this->hasTable($table)) { - throw new Exception(sprintf('Table %s exist.', $table)); + if ($this->hasTable($tableName)) { + throw new Exception(sprintf('Table %s exist.', $tableName)); } - $this->schema[ $table ] = self::tableBuilder($table, $callback)->getTable(); + $this->schema[ $tableName ] = self::tableBuilder($tableName, $callback)->getTable(); $this->save($this->name, $this->toArray()); - $this->create($table); + $this->create($tableName); return $this; } @@ -281,19 +284,19 @@ public function createTable(string $table, ?callable $callback = null): self /** * Créer une référence dans le schéma et un fichier de données si ceux si n'existe pas. * - * @param string $table Nom de la table. - * @param callable|null $callback fonction(TableBuilder $table) pour créer les champs. + * @param string $tableName Nom de la table. + * @param callable|null $callback fonction(TableBuilder $table) pour créer les champs. * * @return $this */ - public function createTableIfNotExists(string $table, ?callable $callback = null): self + public function createTableIfNotExists(string $tableName, ?callable $callback = null): self { /* Créer la table si elle n'existe pas dans le schéma. */ - if (!$this->hasTable($table)) { - $this->createTable($table, $callback); - } elseif (!$this->driver->has($this->root . $this->path, $table)) { + if (!$this->hasTable($tableName)) { + $this->createTable($tableName, $callback); + } elseif (!$this->driver->has($this->root . $this->path, $tableName)) { /* Si elle existe dans le schéma et que le fichier est absent alors on le créer. */ - $this->create($table); + $this->create($tableName); } return $this; @@ -302,16 +305,16 @@ public function createTableIfNotExists(string $table, ?callable $callback = null /** * Modifie les champs du schéma de données. * - * @param string $table Nom de la table. - * @param callable $callback fonction(TableAleter $tableAlter) pour manipuler les champs. + * @param string $tableName Nom de la table. + * @param callable $callback fonction(TableAleter $tableAlter) pour manipuler les champs. * * @return $this */ - public function alterTable(string $table, callable $callback): self + public function alterTable(string $tableName, callable $callback): self { - $tableSchema = $this->getTableSchema($table); - $tableBuilder = self::tableAlterBuilder($table, $callback)->getTable(); - $tableData = $this->read($table); + $tableSchema = $this->getTableSchema($tableName); + $tableBuilder = self::tableAlterBuilder($tableName, $callback)->getTable(); + $tableData = $this->read($tableName); foreach ($tableBuilder->getFields() as $field) { if ($field->getOpt() === Field::OPT_CREATE) { @@ -329,9 +332,9 @@ public function alterTable(string $table, callable $callback): self } } - $this->schema[ $table ] = $tableSchema; + $this->schema[ $tableName ] = $tableSchema; $this->save($this->name, $this->toArray()); - $this->save($table, $tableData); + $this->save($tableName, $tableData); return $this; } @@ -339,52 +342,52 @@ public function alterTable(string $table, callable $callback): self /** * Détermine une table existe. * - * @param string $table Nom de la table. + * @param string $tableName Nom de la table. * * @return bool Si le schéma de référence et le fichier de données existent. */ - public function hasTable(string $table): bool + public function hasTable(string $tableName): bool { - return isset($this->getSchema()[ $table ]) && $this->driver->has($this->root . $this->path, $table); + return isset($this->getSchema()[ $tableName ]) && $this->driver->has($this->root . $this->path, $tableName); } /** * Détermine si une colonne existe. * - * @param string $table Nom de la table. - * @param string $column Nom de la colonne. + * @param string $tableName Nom de la table. + * @param string $column Nom de la colonne. * * @return bool Si le schéma de référence et le fichier de données existent. */ - public function hasColumn(string $table, string $column): bool + public function hasColumn(string $tableName, string $column): bool { - return isset($this->getSchema()[ $table ]) && - $this->getSchema()[ $table ]->hasField($column) && - $this->driver->has($this->root . $this->path, $table); + return isset($this->getSchema()[ $tableName ]) && + $this->getSchema()[ $tableName ]->hasField($column) && + $this->driver->has($this->root . $this->path, $tableName); } /** * Vide la table et initialise les champs incrémentaux. * - * @param String $table Nom de la table. + * @param String $tableName Nom de la table. * * @throws TableNotFoundException * * @return bool */ - public function truncateTable(string $table): bool + public function truncateTable(string $tableName): bool { - if (!$this->hasTable($table)) { - throw new TableNotFoundException($table); + if (!$this->hasTable($tableName)) { + throw new TableNotFoundException($tableName); } $deleteSchema = true; - if ($this->schema[ $table ]->hasIncrement()) { - $this->schema[ $table ]->setIncrement(0); + if ($this->schema[ $tableName ]->hasIncrement()) { + $this->schema[ $tableName ]->setIncrement(0); $deleteSchema = $this->save($this->name, $this->toArray()); } - $deleteData = $this->save($table, []); + $deleteData = $this->save($tableName, []); return $deleteSchema && $deleteData; } @@ -392,20 +395,20 @@ public function truncateTable(string $table): bool /** * Supprime du schéma la référence de la table et son fichier de données. * - * @param string $table Nom de la table. + * @param string $tableName Nom de la table. * * @throws TableNotFoundException * * @return bool Si la suppression du schema et des données se son bien passé. */ - public function dropTable(string $table): bool + public function dropTable(string $tableName): bool { - if (!$this->hasTable($table)) { - throw new TableNotFoundException($table); + if (!$this->hasTable($tableName)) { + throw new TableNotFoundException($tableName); } - unset($this->schema[ $table ]); - $deleteData = $this->delete($table); + unset($this->schema[ $tableName ]); + $deleteData = $this->delete($tableName); $deleteSchema = $this->save($this->name, $this->toArray()); return $deleteSchema && $deleteData; @@ -414,13 +417,13 @@ public function dropTable(string $table): bool /** * Supprime une table si elle existe. * - * @param string $table Nom de la table. + * @param string $tableName Nom de la table. * * @return bool Si la table n'existe plus. */ - public function dropTableIfExists(string $table): bool + public function dropTableIfExists(string $tableName): bool { - return $this->hasTable($table) && $this->dropTable($table); + return $this->hasTable($tableName) && $this->dropTable($tableName); } /** @@ -486,9 +489,9 @@ protected function delete(string $file): bool /** * Ajoute un champ dans les paramètre de la table et ses données. * - * @param Table $table Schéma de la table. - * @param Field $field Nouveau champ. - * @param array $tableData Les données de la table. + * @param Table $table Schéma de la table. + * @param Field $field Nouveau champ. + * @param TableData $tableData Les données de la table. * * @return void */ @@ -505,7 +508,7 @@ protected static function add( try { $valueDefault = $field->getValueDefault(); - } catch (ColumnsValueException|\InvalidArgumentException $e) { + } catch (ColumnsValueException | \InvalidArgumentException $e) { $valueDefault = ''; } @@ -602,14 +605,14 @@ protected static function drop( /** * Passe en premier paramètre d'une fonction anonyme un objet TableBuilder et le retourne. * - * @param string $table Nom de la table. - * @param callable $callback Fonction anonyme. + * @param string $tableName Nom de la table. + * @param callable $callback Fonction anonyme. * * @return TableBuilder */ - protected static function tableAlterBuilder(string $table, callable $callback): TableBuilder + protected static function tableAlterBuilder(string $tableName, callable $callback): TableBuilder { - $builder = new TableAlter($table); + $builder = new TableAlter($tableName); call_user_func_array($callback, [ &$builder ]); return $builder; @@ -618,14 +621,14 @@ protected static function tableAlterBuilder(string $table, callable $callback): /** * Passe en premier paramètre d'une fonction anonyme un objet TableBuilder et le retourne. * - * @param string $table Nom de la table. - * @param callable|null $callback Fonction anonyme. + * @param string $tableName Nom de la table. + * @param callable|null $callback Fonction anonyme. * * @return TableBuilder */ - protected static function tableBuilder(string $table, ?callable $callback = null): TableBuilder + protected static function tableBuilder(string $tableName, ?callable $callback = null): TableBuilder { - $builder = new TableBuilder($table); + $builder = new TableBuilder($tableName); if ($callback !== null) { call_user_func_array($callback, [ &$builder ]); } @@ -762,8 +765,8 @@ private static function filterFieldDrop(Table $table, DropType $field): void private function toArray(): array { $tables = []; - foreach ($this->schema as $name => $table) { - $tables[ $name ] = $table->toArray(); + foreach ($this->schema as $tableName => $table) { + $tables[ $tableName ] = $table->toArray(); } return $tables; diff --git a/src/Table.php b/src/Table.php index df5b5a3..008fb44 100644 --- a/src/Table.php +++ b/src/Table.php @@ -12,6 +12,16 @@ use Queryflatfile\Field\IncrementType; +/** + * @author Mathieu NOËL + * + * @phpstan-import-type FieldToArray from Field + * + * @phpstan-type TableToArray array{ + * fields: array, + * increments?: int|null + * } + */ final class Table { /** @@ -105,6 +115,11 @@ public function setIncrement(?int $increment): void $this->increment = $increment; } + /** + * Retourne les données de la table. + * + * @return TableToArray + */ public function toArray(): array { $fields = []; diff --git a/src/TableBuilder.php b/src/TableBuilder.php index 1396de9..33130ac 100644 --- a/src/TableBuilder.php +++ b/src/TableBuilder.php @@ -25,6 +25,8 @@ * Pattern fluent pour la création et configuration des types de données. * * @author Mathieu NOËL + * + * @phpstan-import-type TableToArray from Table */ class TableBuilder { @@ -194,10 +196,11 @@ public function getTable(): Table /** * Créer une table à partir d'un tableau de données. * - * @param string $table Nom de la table. - * @param array $data Donnaées pour créer une table. + * @param string $table Nom de la table. + * @param TableToArray $data Donnaées pour créer une table. * * @throws TableBuilderException + * * @return Table */ public static function createTableFromArray(string $table, array $data): Table diff --git a/src/Where.php b/src/Where.php index 1bdfc03..684e9ce 100644 --- a/src/Where.php +++ b/src/Where.php @@ -16,6 +16,9 @@ * Pattern fluent pour la création des clauses (conditions) de manipulation des données. * * @author Mathieu NOËL + * + * @phpstan-import-type RowData from Schema + * @phpstan-import-type Between from WhereHandler */ class Where extends WhereHandler { @@ -35,47 +38,44 @@ public function __toString(): string $not = $where[ 'not' ] ? 'NOT ' : ''; + $whereColumn = $where[ 'column' ]; switch ($where[ 'type' ]) { case 'where': - $value = \is_int($where[ 'value' ]) - ? $where[ 'value' ] - : sprintf('\'%s\'', addslashes($where[ 'value' ])); - $output .= sprintf('%s%s %s %s ', $not, addslashes($where[ 'column' ]), $where[ 'condition' ], $value); + $output .= sprintf('%s%s %s %s ', $not, addslashes($whereColumn), $where[ 'condition' ], self::getValueToString($where['value'])); break; case 'like': - $output .= sprintf('%s %sLIKE %s ', addslashes($where[ 'column' ]), $not, addslashes($where[ 'value' ])); + $output .= sprintf('%s %sLIKE %s ', addslashes($whereColumn), $not, self::getValueToString($where['value'])); break; case 'isNull': - $output .= sprintf('%s IS %sNULL ', addslashes($where[ 'column' ]), $not); + $output .= sprintf('%s IS %sNULL ', addslashes($whereColumn), $not); break; case 'in': $output .= sprintf( '%s %sIN %s ', - addslashes($where[ 'column' ]), + addslashes($whereColumn), $not, - addslashes(implode(', ', $where[ 'value' ])) + self::getValueToString($where['value']) ); break; case 'whereGroup': - $output .= sprintf('%s(%s) ', $not, $where[ 'value' ]); + $output .= sprintf('%s(%s) ', $not, self::getValueToString($where['value'])); break; case 'between': $output .= sprintf( - '%s %sBETWEEN %s AND %s ', - addslashes($where[ 'column' ]), + '%s %sBETWEEN %s ', + addslashes($whereColumn), $not, - addslashes((string) $where[ 'value' ][ 'min' ]), - addslashes((string) $where[ 'value' ][ 'max' ]) + self::getValueToString($where['value']) ); break; case 'regex': - $output .= sprintf('%s %sREGEX %s ', addslashes($where[ 'column' ]), $not, $where[ 'value' ]); + $output .= sprintf('%s %sREGEX %s ', addslashes($whereColumn), $not, self::getValueToString($where['value'])); break; } @@ -91,14 +91,14 @@ public function __toString(): string /** * Retourne toutes les colonnes utilisées pour créer la clause. * - * @return array Colonnes. + * @return string[] Colonnes. */ public function getColumns(): array { $output = []; foreach ($this->where as $value) { - if (\is_array($value[ 'column' ])) { - $output = array_merge($output, $value[ 'column' ]); + if (isset($value[ 'columns' ])) { + $output = array_merge($output, $value[ 'columns' ]); continue; } @@ -112,7 +112,7 @@ public function getColumns(): array /** * Retourne TRUE si la suite de condition enregistrée valide les champs du tableau. * - * @param array $row Tableau associatif de champ. + * @param RowData $row Tableau associatif de champ. * * @return bool */ @@ -121,9 +121,11 @@ public function execute(array $row): bool $output = true; foreach ($this->where as $key => $value) { /* Si la clause est standard ou une sous clause. */ - $predicate = $value[ 'type' ] === 'whereGroup' - ? $value[ 'value' ]->execute($row) - : self::predicate($row[ $value[ 'column' ] ], $value[ 'condition' ], $value[ 'value' ]); + if ($value[ 'value' ] instanceof Where) { + $predicate = $value[ 'value' ]->execute($row); + } else { + $predicate = self::predicate($row[ $value[ 'column' ] ], $value[ 'condition' ], $value[ 'value' ]); + } /* Si la clause est inversé. */ if ($value[ 'not' ]) { $predicate = !$predicate; @@ -150,8 +152,8 @@ public function execute(array $row): bool * Retourne TRUE si la suite de condition enregistrée valide les champs du tableau * par rapport à un autre tableau. * - * @param array $row Tableau associatif de champ. - * @param array $rowTable Tableau associatif de champ à tester. + * @param RowData $row Tableau associatif de champ. + * @param RowData $rowTable Tableau associatif de champ à tester. * * @return bool */ @@ -161,9 +163,10 @@ public function executeJoin(array $row, array &$rowTable): bool foreach ($this->where as $key => $value) { $predicate = true; - if ($value[ 'type' ] === 'whereGroup') { + if ($value[ 'value' ] instanceof Where) { $predicate = $value[ 'value' ]->executeJoin($row, $rowTable); } else { + /** @var array{value:string, column: string, condition: string, bool:string} $value */ $val = $rowTable[ self::getColumn($value[ 'value' ]) ]; $predicate = self::predicate($row[ $value[ 'column' ] ], $value[ 'condition' ], $val); @@ -185,9 +188,9 @@ public function executeJoin(array $row, array &$rowTable): bool /** * Retourne TRUE si la condition est validée. * - * @param bool|null|numeric|string $columns Valeur à tester. - * @param string $operator Condition à réaliser. - * @param array|bool|null|numeric|string $value Valeur de comparaison. + * @param null|scalar $columns Valeur à tester. + * @param string $operator Condition à réaliser. + * @param array|null|scalar $value Valeur de comparaison. * * @throws \Exception * @@ -225,7 +228,7 @@ protected static function predicate($columns, string $operator, $value): bool /** @var string $value */ return preg_match($value, (string) $columns) === 1; case 'between': - /** @var array{min: string|numeric, max: string|numeric} $value */ + /** @var Between $value */ return $columns >= $value[ 'min' ] && $columns <= $value[ 'max' ]; } @@ -247,4 +250,43 @@ protected static function getColumn(string $value): string ? substr(strrchr($value, '.'), 1) : $value; } + + /** + * @param array|null|scalar|Where $value + * + * @return string + */ + protected static function getValueToString($value): string + { + if (is_int($value)) { + return (string) $value; + } + if (is_string($value)) { + return sprintf('\'%s\'', addslashes($value)); + } + if ($value instanceof Where) { + return (string) $value; + } + if (is_array($value)) { + if (isset($value[ 'min' ], $value[ 'max' ]) && is_scalar($value[ 'min' ]) && is_scalar($value[ 'max' ])) { + return sprintf( + '%s AND %s', + self::getValueToString($value[ 'min' ]), + self::getValueToString($value[ 'max' ]) + ); + } + + return implode( + ', ', + array_map( + function ($item): string { + return self::getValueToString($item); + }, + $value + ) + ); + } + + return 'null'; + } } diff --git a/src/WhereHandler.php b/src/WhereHandler.php index 65071ae..43ad2ec 100644 --- a/src/WhereHandler.php +++ b/src/WhereHandler.php @@ -17,6 +17,17 @@ * Pattern fluent pour la création des clauses (conditions) de manipulation des données. * * @author Mathieu NOËL + * + * @phpstan-type Between array{min: numeric|string, max: numeric|string} + * @phpstan-type WhereToArray array{ + * bool: string, + * column: string, + * columns?: array, + * condition: string, + * not: bool, + * type: string, + * value: array|Between|null|scalar|Where, + * } */ class WhereHandler { @@ -41,7 +52,7 @@ class WhereHandler /** * Les conditions à exécuter. * - * @var array + * @var WhereToArray[] */ protected $where = []; @@ -358,11 +369,13 @@ public function whereGroup( call_user_func_array($callable, [ &$where ]); $this->where[] = [ - 'type' => __FUNCTION__, - 'column' => $where->getColumns(), - 'value' => $where, - 'bool' => $bool, - 'not' => $not + 'type' => __FUNCTION__, + 'column' => '', + 'columns' => $where->getColumns(), + 'condition' => '', + 'value' => $where, + 'bool' => $bool, + 'not' => $not ]; } diff --git a/tests/unit/RequestTest.php b/tests/unit/RequestTest.php index 6037b83..3665172 100644 --- a/tests/unit/RequestTest.php +++ b/tests/unit/RequestTest.php @@ -563,6 +563,22 @@ public function testWhereIsNull(): void ); } + public function testWhereEqualsNull(): void + { + $data = $this->request + ->from('user') + ->where('firstname', '===', null); + + self::assertEquals( + 'SELECT * FROM user WHERE firstname === null;', + (string) $data + ); + self::assertEquals( + [ 'id' => 6, 'name' => 'ROBERT', 'firstname' => null ], + $data->fetch() + ); + } + public function testWhereIsNotNull(): void { $data = $this->request @@ -676,7 +692,7 @@ public function whereLikeProvider(): \Generator // LIKE yield [ 'like', 'DUP%', - 'SELECT id, name FROM user WHERE name LIKE /^DUP.*$/;', + 'SELECT id, name FROM user WHERE name LIKE \'/^DUP.*$/\';', [ [ 'id' => 1, 'name' => 'DUPOND' ], [ 'id' => 4, 'name' => 'DUPOND' ] @@ -684,24 +700,24 @@ public function whereLikeProvider(): \Generator ]; yield [ 'like', '%TI%', - 'SELECT id, name FROM user WHERE name LIKE /^.*TI.*$/;', + 'SELECT id, name FROM user WHERE name LIKE \'/^.*TI.*$/\';', [ [ 'id' => 2, 'name' => 'MARTIN' ] ] ]; yield [ 'like', 'OND', - 'SELECT id, name FROM user WHERE name LIKE /^OND$/;', + 'SELECT id, name FROM user WHERE name LIKE \'/^OND$/\';', [] ]; yield [ 'like', 'OND%', - 'SELECT id, name FROM user WHERE name LIKE /^OND.*$/;', + 'SELECT id, name FROM user WHERE name LIKE \'/^OND.*$/\';', [] ]; yield [ 'like', '%OND', - 'SELECT id, name FROM user WHERE name LIKE /^.*OND$/;', + 'SELECT id, name FROM user WHERE name LIKE \'/^.*OND$/\';', [ [ 'id' => 1, 'name' => 'DUPOND' ], [ 'id' => 4, 'name' => 'DUPOND' ] @@ -709,7 +725,7 @@ public function whereLikeProvider(): \Generator ]; yield [ 'like', '%OND%', - 'SELECT id, name FROM user WHERE name LIKE /^.*OND.*$/;', + 'SELECT id, name FROM user WHERE name LIKE \'/^.*OND.*$/\';', [ [ 'id' => 1, 'name' => 'DUPOND' ], [ 'id' => 4, 'name' => 'DUPOND' ] @@ -719,7 +735,7 @@ public function whereLikeProvider(): \Generator // ILIKE yield [ 'ilike', 'Dup%', - 'SELECT id, name FROM user WHERE name LIKE /^Dup.*$/i;', + 'SELECT id, name FROM user WHERE name LIKE \'/^Dup.*$/i\';', [ [ 'id' => 1, 'name' => 'DUPOND' ], [ 'id' => 4, 'name' => 'DUPOND' ] @@ -727,7 +743,7 @@ public function whereLikeProvider(): \Generator ]; yield [ 'ilike', '%OnD', - 'SELECT id, name FROM user WHERE name LIKE /^.*OnD$/i;', + 'SELECT id, name FROM user WHERE name LIKE \'/^.*OnD$/i\';', [ [ 'id' => 1, 'name' => 'DUPOND' ], [ 'id' => 4, 'name' => 'DUPOND' ] @@ -735,7 +751,7 @@ public function whereLikeProvider(): \Generator ]; yield [ 'ilike', '%ti%', - 'SELECT id, name FROM user WHERE name LIKE /^.*ti.*$/i;', + 'SELECT id, name FROM user WHERE name LIKE \'/^.*ti.*$/i\';', [ [ 'id' => 2, 'name' => 'MARTIN' ] ] @@ -744,7 +760,7 @@ public function whereLikeProvider(): \Generator // NOT LIKE yield [ 'not like', 'DUP%', - 'SELECT id, name FROM user WHERE name NOT LIKE /^DUP.*$/;', + 'SELECT id, name FROM user WHERE name NOT LIKE \'/^DUP.*$/\';', [ [ 'id' => 0, 'name' => 'NOEL' ], [ 'id' => 2, 'name' => 'MARTIN' ], @@ -754,7 +770,7 @@ public function whereLikeProvider(): \Generator ]; yield [ 'not like', '%OND', - 'SELECT id, name FROM user WHERE name NOT LIKE /^.*OND$/;', + 'SELECT id, name FROM user WHERE name NOT LIKE \'/^.*OND$/\';', [ [ 'id' => 0, 'name' => 'NOEL' ], [ 'id' => 2, 'name' => 'MARTIN' ], @@ -764,7 +780,7 @@ public function whereLikeProvider(): \Generator ]; yield [ 'not like', '%E%', - 'SELECT id, name FROM user WHERE name NOT LIKE /^.*E.*$/;', + 'SELECT id, name FROM user WHERE name NOT LIKE \'/^.*E.*$/\';', [ [ 'id' => 1, 'name' => 'DUPOND' ], [ 'id' => 2, 'name' => 'MARTIN' ], @@ -775,7 +791,7 @@ public function whereLikeProvider(): \Generator // NOT ILIKE yield [ 'not ilike', 'DuP%', - 'SELECT id, name FROM user WHERE name NOT LIKE /^DuP.*$/i;', + 'SELECT id, name FROM user WHERE name NOT LIKE \'/^DuP.*$/i\';', [ [ 'id' => 0, 'name' => 'NOEL' ], [ 'id' => 2, 'name' => 'MARTIN' ], @@ -785,7 +801,7 @@ public function whereLikeProvider(): \Generator ]; yield [ 'not ilike', '%D', - 'SELECT id, name FROM user WHERE name NOT LIKE /^.*D$/i;', + 'SELECT id, name FROM user WHERE name NOT LIKE \'/^.*D$/i\';', [ [ 'id' => 0, 'name' => 'NOEL' ], [ 'id' => 2, 'name' => 'MARTIN' ], @@ -795,7 +811,7 @@ public function whereLikeProvider(): \Generator ]; yield [ 'not ilike', '%E%', - 'SELECT id, name FROM user WHERE name NOT LIKE /^.*E.*$/i;', + 'SELECT id, name FROM user WHERE name NOT LIKE \'/^.*E.*$/i\';', [ [ 'id' => 1, 'name' => 'DUPOND' ], [ 'id' => 2, 'name' => 'MARTIN' ], @@ -810,7 +826,7 @@ public function testWhereRegex(): void ->from('user') ->regex('name', '/^D/'); - self::assertEquals('SELECT * FROM user WHERE name REGEX /^D/;', (string) $data); + self::assertEquals('SELECT * FROM user WHERE name REGEX \'/^D/\';', (string) $data); self::assertEquals( [ [ 'id' => 1, 'name' => 'DUPOND', 'firstname' => 'Jean' ], @@ -826,7 +842,7 @@ public function testWhereNotRegex(): void ->from('user') ->notRegex('name', '/^D/'); - self::assertEquals('SELECT * FROM user WHERE name NOT REGEX /^D/;', (string) $data); + self::assertEquals('SELECT * FROM user WHERE name NOT REGEX \'/^D/\';', (string) $data); self::assertEquals( [ [ 'id' => 0, 'name' => 'NOEL', 'firstname' => 'Mathieu' ], @@ -846,7 +862,7 @@ public function testWhereOrNotRegex(): void ->orNotRegex('firstname', '/^M/'); self::assertEquals( - 'SELECT * FROM user WHERE name REGEX /^D/ OR firstname NOT REGEX /^M/;', + 'SELECT * FROM user WHERE name REGEX \'/^D/\' OR firstname NOT REGEX \'/^M/\';', (string) $data ); self::assertEquals( @@ -867,7 +883,7 @@ public function testWhereOrRegex(): void ->orRegex('name', '/^N/'); self::assertEquals( - 'SELECT * FROM user WHERE name REGEX /^D/ OR name REGEX /^N/;', + 'SELECT * FROM user WHERE name REGEX \'/^D/\' OR name REGEX \'/^N/\';', (string) $data ); self::assertEquals( @@ -883,7 +899,7 @@ public function testWhereOrRegex(): void public function testWhereRegexExceptionColumns(): void { $this->expectException(ColumnsNotFoundException::class); - $this->expectExceptionMessage('Column foo is absent: SELECT * FROM user WHERE foo REGEX /^D/ LIMIT 1;'); + $this->expectExceptionMessage('Column foo is absent: SELECT * FROM user WHERE foo REGEX \'/^D/\' LIMIT 1;'); $this->request ->from('user') ->regex('foo', '/^D/') diff --git a/tests/unit/TableAlterTest.php b/tests/unit/TableAlterTest.php index 6fa8d58..e16443a 100644 --- a/tests/unit/TableAlterTest.php +++ b/tests/unit/TableAlterTest.php @@ -23,7 +23,7 @@ public function testDrop(): void self::assertEquals($this->object->getTable()->toArray(), [ 'fields' => [ - '0' => [ 'opt' => Field::OPT_DROP ] + '0' => [ 'type' => '', 'opt' => Field::OPT_DROP ] ], 'increments' => null ]); @@ -35,7 +35,7 @@ public function testRename(): void self::assertEquals($this->object->getTable()->toArray(), [ 'fields' => [ - '0' => [ 'opt' => Field::OPT_RENAME, 'to' => '1' ] + '0' => [ 'type' => '', 'opt' => Field::OPT_RENAME, 'to' => '1' ] ], 'increments' => null ]); From a114aff0c47e63909bc43b42b31c1edd987137c4 Mon Sep 17 00:00:00 2001 From: noelma Date: Wed, 8 Dec 2021 20:00:31 +0100 Subject: [PATCH 2/2] fix: use prefixed tags phpstan --- src/Field.php | 4 +++- src/Request.php | 12 +++++++++--- src/RequestHandler.php | 12 +++++++++--- src/RequestInterface.php | 14 ++++++++++---- src/Schema.php | 8 +++++--- src/Table.php | 4 +++- src/TableBuilder.php | 6 ++++-- src/Where.php | 11 ++++++++--- src/WhereHandler.php | 4 +++- 9 files changed, 54 insertions(+), 21 deletions(-) diff --git a/src/Field.php b/src/Field.php index 9ab181c..04c57ef 100644 --- a/src/Field.php +++ b/src/Field.php @@ -188,7 +188,9 @@ public function setName(string $name): self /** * Retourne les données du champ. * - * @return FieldToArray + * @return array + * + * @phpstan-return FieldToArray */ public function toArray(): array { diff --git a/src/Request.php b/src/Request.php index 731077d..7c7e3f7 100644 --- a/src/Request.php +++ b/src/Request.php @@ -38,7 +38,9 @@ class Request extends RequestHandler /** * Les données de la table. * - * @var TableData + * @var array + * + * @phpstan-var TableData */ private $tableData = []; @@ -186,7 +188,9 @@ public function execute(): void /** * Retourne tous les résultats de la requête. * - * @return TableData les données + * @return array les données + * + * @phpstan-return TableData */ public function fetchAll(): array { @@ -271,7 +275,9 @@ public function fetchAll(): array /** * Retourne le premier résultat de la requête. * - * @return RowData Résultat de la requête. + * @return array Résultat de la requête. + * + * @phpstan-return RowData */ public function fetch(): array { diff --git a/src/RequestHandler.php b/src/RequestHandler.php index 3bef177..4289d87 100644 --- a/src/RequestHandler.php +++ b/src/RequestHandler.php @@ -87,14 +87,18 @@ abstract class RequestHandler implements RequestInterface /** * Les jointures à calculer. * - * @var Join[] + * @var array + * + * @phpstan-var Join[] */ protected $joins = []; /** * Les unions. * - * @var Union[] + * @var array + * + * @phpstan-var Union[] */ protected $unions = []; @@ -136,7 +140,9 @@ abstract class RequestHandler implements RequestInterface /** * Les valeurs à insérer ou mettre à jour. * - * @var TableData + * @var array + * + * @phpstan-var TableData */ protected $values = []; diff --git a/src/RequestInterface.php b/src/RequestInterface.php index a0ac4c0..20ebf24 100644 --- a/src/RequestInterface.php +++ b/src/RequestInterface.php @@ -138,8 +138,10 @@ public function values(array $columns); /** * Enregistre l'action de modification de données. * - * @param string $tableName Nom de la table. - * @param RowData $columns key=>value des données à modifier. + * @param string $tableName Nom de la table. + * @param array $columns key=>value des données à modifier. + * + * @phpstan-param RowData $columns * * @return $this */ @@ -175,14 +177,18 @@ public function unionAll(RequestInterface $request); /** * Retourne tous les résultats de la requête. * - * @return TableData les données + * @return array les données + * + * @phpstan-return TableData */ public function fetchAll(): array; /** * Retourne le premier résultat de la requête. * - * @return RowData Résultat de la requête. + * @return array Résultat de la requête. + * + * @phpstan-return RowData */ public function fetch(): array; diff --git a/src/Schema.php b/src/Schema.php index 7f1c51e..138b59c 100644 --- a/src/Schema.php +++ b/src/Schema.php @@ -489,9 +489,11 @@ protected function delete(string $file): bool /** * Ajoute un champ dans les paramètre de la table et ses données. * - * @param Table $table Schéma de la table. - * @param Field $field Nouveau champ. - * @param TableData $tableData Les données de la table. + * @param Table $table Schéma de la table. + * @param Field $field Nouveau champ. + * @param array $tableData Les données de la table. + * + * @phpstan-param TableData $tableData * * @return void */ diff --git a/src/Table.php b/src/Table.php index 008fb44..93c53cf 100644 --- a/src/Table.php +++ b/src/Table.php @@ -118,7 +118,9 @@ public function setIncrement(?int $increment): void /** * Retourne les données de la table. * - * @return TableToArray + * @return array + * + * @phpstan-return TableToArray */ public function toArray(): array { diff --git a/src/TableBuilder.php b/src/TableBuilder.php index 33130ac..6a348a1 100644 --- a/src/TableBuilder.php +++ b/src/TableBuilder.php @@ -196,8 +196,10 @@ public function getTable(): Table /** * Créer une table à partir d'un tableau de données. * - * @param string $table Nom de la table. - * @param TableToArray $data Donnaées pour créer une table. + * @param string $table Nom de la table. + * @param array $data Donnaées pour créer une table. + * + * @phpstan-param TableToArray $data * * @throws TableBuilderException * diff --git a/src/Where.php b/src/Where.php index 684e9ce..9d7d9aa 100644 --- a/src/Where.php +++ b/src/Where.php @@ -112,7 +112,9 @@ public function getColumns(): array /** * Retourne TRUE si la suite de condition enregistrée valide les champs du tableau. * - * @param RowData $row Tableau associatif de champ. + * @param array $row Tableau associatif de champ. + * + * @phpstan-param RowData $row * * @return bool */ @@ -152,8 +154,11 @@ public function execute(array $row): bool * Retourne TRUE si la suite de condition enregistrée valide les champs du tableau * par rapport à un autre tableau. * - * @param RowData $row Tableau associatif de champ. - * @param RowData $rowTable Tableau associatif de champ à tester. + * @param array $row Tableau associatif de champ. + * @param array $rowTable Tableau associatif de champ à tester. + * + * @phpstan-param RowData $row + * @phpstan-param RowData $rowTable * * @return bool */ diff --git a/src/WhereHandler.php b/src/WhereHandler.php index 43ad2ec..68505e3 100644 --- a/src/WhereHandler.php +++ b/src/WhereHandler.php @@ -52,7 +52,9 @@ class WhereHandler /** * Les conditions à exécuter. * - * @var WhereToArray[] + * @var array + * + * @phpstan-var WhereToArray[] */ protected $where = [];