From e64ea2709cbe99ef65e775039a689cb412edefad Mon Sep 17 00:00:00 2001 From: Aldarien Date: Mon, 22 Apr 2024 12:04:14 -0400 Subject: [PATCH 1/4] Postgresql --- src/Database/Query/PostgreSQL/Create.php | 8 ++++++++ src/Database/Query/PostgreSQL/Delete.php | 8 ++++++++ src/Database/Query/PostgreSQL/Drop.php | 8 ++++++++ src/Database/Query/PostgreSQL/Insert.php | 8 ++++++++ src/Database/Query/PostgreSQL/Select.php | 8 ++++++++ src/Database/Query/PostgreSQL/Truncate.php | 8 ++++++++ src/Database/Query/PostgreSQL/Update.php | 8 ++++++++ 7 files changed, 56 insertions(+) create mode 100644 src/Database/Query/PostgreSQL/Create.php create mode 100644 src/Database/Query/PostgreSQL/Delete.php create mode 100644 src/Database/Query/PostgreSQL/Drop.php create mode 100644 src/Database/Query/PostgreSQL/Insert.php create mode 100644 src/Database/Query/PostgreSQL/Select.php create mode 100644 src/Database/Query/PostgreSQL/Truncate.php create mode 100644 src/Database/Query/PostgreSQL/Update.php diff --git a/src/Database/Query/PostgreSQL/Create.php b/src/Database/Query/PostgreSQL/Create.php new file mode 100644 index 0000000..1b2717b --- /dev/null +++ b/src/Database/Query/PostgreSQL/Create.php @@ -0,0 +1,8 @@ + Date: Sat, 3 Aug 2024 20:58:53 -0400 Subject: [PATCH 2/4] Update namespaces --- composer.json | 4 +- src/Concept/Database/Query.php | 5 +- src/Concept/Database/Query/Create.php | 5 +- src/Database/Query/MySQL/Create.php | 8 -- src/Database/Query/MySQL/Delete.php | 8 -- src/Database/Query/MySQL/Drop.php | 8 -- src/Database/Query/MySQL/Insert.php | 8 -- src/Database/Query/MySQL/Truncate.php | 8 -- src/Database/Query/MySQL/Update.php | 8 -- src/Database/Query/PostgreSQL/Create.php | 8 -- src/Database/Query/PostgreSQL/Delete.php | 8 -- src/Database/Query/PostgreSQL/Drop.php | 8 -- src/Database/Query/PostgreSQL/Insert.php | 8 -- src/Database/Query/PostgreSQL/Select.php | 8 -- src/Database/Query/PostgreSQL/Truncate.php | 8 -- src/Database/Query/PostgreSQL/Update.php | 8 -- src/{ => Enforce}/Database/Query/Builder.php | 32 ++++- src/Enforce/Database/Query/MySQL/Create.php | 8 ++ src/Enforce/Database/Query/MySQL/Delete.php | 8 ++ src/Enforce/Database/Query/MySQL/Drop.php | 8 ++ src/Enforce/Database/Query/MySQL/Insert.php | 8 ++ .../Database/Query/MySQL/Select.php | 9 +- src/Enforce/Database/Query/MySQL/Truncate.php | 8 ++ src/Enforce/Database/Query/MySQL/Update.php | 8 ++ .../Database/Query/PostgreSQL/Create.php | 8 ++ .../Database/Query/PostgreSQL/Delete.php | 8 ++ .../Database/Query/PostgreSQL/Drop.php | 8 ++ .../Database/Query/PostgreSQL/Insert.php | 8 ++ .../Database/Query/PostgreSQL/Select.php | 8 ++ .../Database/Query/PostgreSQL/Truncate.php | 8 ++ .../Database/Query/PostgreSQL/Update.php | 8 ++ src/{Implement => Ideal}/Database/Query.php | 7 +- src/Ideal/Database/Query/Create.php | 132 ++++++++++++++++++ .../Database/Query/Delete.php | 11 +- src/Ideal/Database/Query/Drop.php | 37 +++++ .../Database/Query/Insert.php | 12 +- .../Database/Query/Select.php | 42 +++++- .../Database/Query/Truncate.php | 11 +- .../Database/Query/Update.php | 25 +++- src/Implement/Database/Query/Create.php | 62 -------- src/Implement/Database/Query/Drop.php | 27 ---- .../Database/Query/hasConditions.php | 20 ++- .../Database/Query/hasTable.php | 5 +- 43 files changed, 422 insertions(+), 232 deletions(-) delete mode 100644 src/Database/Query/MySQL/Create.php delete mode 100644 src/Database/Query/MySQL/Delete.php delete mode 100644 src/Database/Query/MySQL/Drop.php delete mode 100644 src/Database/Query/MySQL/Insert.php delete mode 100644 src/Database/Query/MySQL/Truncate.php delete mode 100644 src/Database/Query/MySQL/Update.php delete mode 100644 src/Database/Query/PostgreSQL/Create.php delete mode 100644 src/Database/Query/PostgreSQL/Delete.php delete mode 100644 src/Database/Query/PostgreSQL/Drop.php delete mode 100644 src/Database/Query/PostgreSQL/Insert.php delete mode 100644 src/Database/Query/PostgreSQL/Select.php delete mode 100644 src/Database/Query/PostgreSQL/Truncate.php delete mode 100644 src/Database/Query/PostgreSQL/Update.php rename src/{ => Enforce}/Database/Query/Builder.php (65%) create mode 100644 src/Enforce/Database/Query/MySQL/Create.php create mode 100644 src/Enforce/Database/Query/MySQL/Delete.php create mode 100644 src/Enforce/Database/Query/MySQL/Drop.php create mode 100644 src/Enforce/Database/Query/MySQL/Insert.php rename src/{ => Enforce}/Database/Query/MySQL/Select.php (86%) create mode 100644 src/Enforce/Database/Query/MySQL/Truncate.php create mode 100644 src/Enforce/Database/Query/MySQL/Update.php create mode 100644 src/Enforce/Database/Query/PostgreSQL/Create.php create mode 100644 src/Enforce/Database/Query/PostgreSQL/Delete.php create mode 100644 src/Enforce/Database/Query/PostgreSQL/Drop.php create mode 100644 src/Enforce/Database/Query/PostgreSQL/Insert.php create mode 100644 src/Enforce/Database/Query/PostgreSQL/Select.php create mode 100644 src/Enforce/Database/Query/PostgreSQL/Truncate.php create mode 100644 src/Enforce/Database/Query/PostgreSQL/Update.php rename src/{Implement => Ideal}/Database/Query.php (50%) create mode 100644 src/Ideal/Database/Query/Create.php rename src/{Implement => Ideal}/Database/Query/Delete.php (67%) create mode 100644 src/Ideal/Database/Query/Drop.php rename src/{Implement => Ideal}/Database/Query/Insert.php (90%) rename src/{Implement => Ideal}/Database/Query/Select.php (86%) rename src/{Implement => Ideal}/Database/Query/Truncate.php (59%) rename src/{Implement => Ideal}/Database/Query/Update.php (70%) delete mode 100644 src/Implement/Database/Query/Create.php delete mode 100644 src/Implement/Database/Query/Drop.php rename src/{Implement => Reinforce}/Database/Query/hasConditions.php (67%) rename src/{Implement => Reinforce}/Database/Query/hasTable.php (82%) diff --git a/composer.json b/composer.json index 7cfe75d..f42ea8b 100644 --- a/composer.json +++ b/composer.json @@ -1,9 +1,9 @@ { "name": "provm/query_builder", + "version": "3.0.0", "type": "project", "require-dev": { - "phpunit/phpunit": "^9.5", - "kint-php/kint": "^4.2" + "phpunit/phpunit": "^10" }, "authors": [ { diff --git a/src/Concept/Database/Query.php b/src/Concept/Database/Query.php index 6a325ee..7e2a23e 100644 --- a/src/Concept/Database/Query.php +++ b/src/Concept/Database/Query.php @@ -1,8 +1,9 @@ setQueries($query_classes); } + /** + * @throws Exception + */ + public static function getClasses(string $databaseType): array + { + $directories = new FilesystemIterator(__DIR__); + foreach ($directories as $directory) { + if (!$directory->isDir()) { + continue; + } + if (strtolower($directory->getBasename()) !== strtolower($databaseType)) { + continue; + } + $classes = []; + $files = new FilesystemIterator($directory->getPathname()); + foreach ($files as $file) { + if ($file->isDir()) { + continue; + } + $base = $file->getBasename('.php'); + $interface = "ProVM\\Concept\\Database\\Query\\{$base}"; + $class = __NAMESPACE__ . "\\{$directory->getBasename()}\\{$base}"; + $classes[$interface] = $class; + } + return $classes; + } + throw new Exception("Database type's classes not found"); + } protected array $query_classes; protected function getQueries(): array diff --git a/src/Enforce/Database/Query/MySQL/Create.php b/src/Enforce/Database/Query/MySQL/Create.php new file mode 100644 index 0000000..1cabb3d --- /dev/null +++ b/src/Enforce/Database/Query/MySQL/Create.php @@ -0,0 +1,8 @@ +getLimitString() ]; - return implode('', $query); + return implode('', $query);*/ } } diff --git a/src/Enforce/Database/Query/MySQL/Truncate.php b/src/Enforce/Database/Query/MySQL/Truncate.php new file mode 100644 index 0000000..c2dbec0 --- /dev/null +++ b/src/Enforce/Database/Query/MySQL/Truncate.php @@ -0,0 +1,8 @@ +build(); diff --git a/src/Ideal/Database/Query/Create.php b/src/Ideal/Database/Query/Create.php new file mode 100644 index 0000000..f8a138e --- /dev/null +++ b/src/Ideal/Database/Query/Create.php @@ -0,0 +1,132 @@ +table($table); + } + } + + public function isTemp(): Database\Query\Create + { + $this->temp = true; + return $this; + } + public function ifNotExists(): Database\Query\Create + { + $this->exists = true; + return $this; + } + public function table(string $table): Database\Query\Create + { + return $this->setTable($table); + } + public function columns(array|string $columns): Database\Query\Create + { + return $this->setColumns($columns); + } + public function foreign(array|string $columnDefinition): Database\Query\Create + { + return $this->setForeign($columnDefinition); + } + + protected bool $temp = false; + protected bool $exists = false; + protected array|string $columns; + protected array|string $foreign; + + public function getColumns(): array + { + return $this->columns; + } + + public function addColumn(string $column): Database\Query\Create + { + $this->columns []= $column; + return $this; + } + + public function setColumns(array|string $columns): Database\Query\Create + { + if (is_string($columns)) { + $this->addColumn($columns); + return $this; + } + foreach ($columns as $column) { + $this->addColumn($column); + } + return $this; + } + public function getForegin(): array + { + return $this->foreign; + } + public function addForeign(string|array $definition): Database\Query\Create + { + if (is_string($definition)) { + $this->foreign []= $definition; + return $this; + } + $ids = implode(', ', $definition['ids']); + $columns = $definition['columns']; + if (is_array($definition['columns'])) { + $columns = implode(', ', $definition['columns']); + } + $delete = $definition['delete'] ?? 'CASCADE'; + $update = $definition['update'] ?? 'CASCADE'; + $fk = implode('_', ['fk', str_replace('.', '_', $definition['table']), $ids]); + $this->foreign []= "CONSTRAINT {$fk} FOREIGN KEY ({$columns}) REFERENCES {$definition['table']} ({$ids}) ON DELETE {$delete} ON UPDATE {$update}"; + return $this; + } + public function setForeign(array|string $columnDefinition): Database\Query\Create + { + if (is_string($columnDefinition)) { + $this->addForeign($columnDefinition); + return $this; + } + foreach ($columnDefinition as $column) { + $this->addForeign($column); + } + return $this; + } + + protected function getTempString(): string + { + return ($this->temp) ? ' TEMPORARY' : ''; + } + protected function getIfNotExistsString(): string + { + return ($this->exists) ? ' IF NOT EXISTS' : ''; + } + protected function getColumnsString(): string + { + if (is_string($this->columns)) { + return $this->columns; + } + return implode(', ', $this->getColumns()); + } + protected function getForeignString(): string + { + if (!isset($this->foreign)) { + return ''; + } + if (is_string($this->foreign)) { + return ", {$this->foreign}"; + } + return ', ' . implode(', ', $this->getForegin()); + } + + public function build(): string + { + return "CREATE{$this->getTempString()} TABLE{$this->getIfNotExistsString()} {$this->getTable()} ({$this->getColumnsString()}{$this->getForeignString()})"; + } +} diff --git a/src/Implement/Database/Query/Delete.php b/src/Ideal/Database/Query/Delete.php similarity index 67% rename from src/Implement/Database/Query/Delete.php rename to src/Ideal/Database/Query/Delete.php index 26b99b9..621afdf 100644 --- a/src/Implement/Database/Query/Delete.php +++ b/src/Ideal/Database/Query/Delete.php @@ -1,13 +1,20 @@ from($table); + } + } public function from(string $table): Database\Query\Delete { return $this->setTable($table); diff --git a/src/Ideal/Database/Query/Drop.php b/src/Ideal/Database/Query/Drop.php new file mode 100644 index 0000000..083ca3c --- /dev/null +++ b/src/Ideal/Database/Query/Drop.php @@ -0,0 +1,37 @@ +table($table); + } + } + public function table(string $table): Database\Query\Drop + { + return $this->setTable($table); + } + public function cascade(): Database\Query\Drop + { + $this->cascade = true; + return $this; + } + + protected bool $cascade = false; + protected function getCascadeString(): string + { + return $this->cascade ? ' CASCADE' : ''; + } + public function build(): string + { + return "DROP TABLE {$this->getTable()}{$this->getCascadeString()}"; + } +} diff --git a/src/Implement/Database/Query/Insert.php b/src/Ideal/Database/Query/Insert.php similarity index 90% rename from src/Implement/Database/Query/Insert.php rename to src/Ideal/Database/Query/Insert.php index 96dbde7..9f31fc6 100644 --- a/src/Implement/Database/Query/Insert.php +++ b/src/Ideal/Database/Query/Insert.php @@ -1,13 +1,21 @@ into($table); + } + } + public function into(string $table): Database\Query\Insert { return $this->setTable($table); diff --git a/src/Implement/Database/Query/Select.php b/src/Ideal/Database/Query/Select.php similarity index 86% rename from src/Implement/Database/Query/Select.php rename to src/Ideal/Database/Query/Select.php index ea6c2b2..5e1b358 100644 --- a/src/Implement/Database/Query/Select.php +++ b/src/Ideal/Database/Query/Select.php @@ -1,8 +1,9 @@ setOrders($ordering); } + public function limit(int $limit, ?int $offset = null): Database\Query\Select + { + $this->limit = $limit; + if ($offset !== null) { + $this->offset($offset); + } + return $this; + } + public function offset(int $offset): self + { + $this->offset = $offset; + return $this; + } protected array|string $columns; protected array|string $joins; protected array|string $groups; protected array|string $having; protected array|string $orders; + protected int $limit; + protected int $offset; public function getColumns(): array|string { @@ -178,8 +194,12 @@ abstract class Select extends Query implements Database\Query\Select protected function getColumnsString(): string { + if (!isset($this->columns) or (is_array($this->getColumns()) and count($this->getColumns()) === 0) + or (is_string($this->getColumns()) and $this->getColumns() === '*')) { + return '*'; + } $columns = (is_array($this->getColumns())) ? implode(', ', $this->getColumns()) : $this->getColumns(); - return " ({$columns})"; + return "({$columns})"; } protected function getJoinsString(): string { @@ -244,17 +264,29 @@ abstract class Select extends Query implements Database\Query\Select $ordering = (is_array($this->getOrders())) ? implode(', ', $this->getOrders()) : $this->getOrders(); return " ORDER BY {$ordering}"; } + protected function getLimitString(): string + { + if (!isset($this->limit)) { + return ''; + } + $limit = " LIMIT {$this->limit}"; + if (isset($this->offset)) { + $limit .= " OFFSET {$this->offset}"; + } + return $limit; + } public function build(): string { return implode('', [ "SELECT {$this->getColumnsString()}", - "FROM {$this->getTable()}", + " FROM {$this->getTable()}", $this->getJoinsString(), $this->getConditionsString(), $this->getGroupsString(), $this->getHavingString(), - $this->getOrderString() + $this->getOrderString(), + $this->getLimitString() ]); } } diff --git a/src/Implement/Database/Query/Truncate.php b/src/Ideal/Database/Query/Truncate.php similarity index 59% rename from src/Implement/Database/Query/Truncate.php rename to src/Ideal/Database/Query/Truncate.php index 0e35017..9299dd6 100644 --- a/src/Implement/Database/Query/Truncate.php +++ b/src/Ideal/Database/Query/Truncate.php @@ -1,16 +1,19 @@ table($table); + if ($table !== null) { + $this->table($table); + } } public function table(string $table): Database\Query\Truncate { diff --git a/src/Implement/Database/Query/Update.php b/src/Ideal/Database/Query/Update.php similarity index 70% rename from src/Implement/Database/Query/Update.php rename to src/Ideal/Database/Query/Update.php index a515b9e..8867325 100644 --- a/src/Implement/Database/Query/Update.php +++ b/src/Ideal/Database/Query/Update.php @@ -1,13 +1,20 @@ table($table); + } + } public function table(string $table): Database\Query\Update { return $this->setTable($table); @@ -28,8 +35,14 @@ abstract class Update extends Query implements Database\Query\Update return $this->values; } - public function addValue(string $column, int|string $value): Database\Query\Update + public function addValue(string|array $values): Database\Query\Update { + if (is_string($values)) { + $this->values []= $values; + return $this; + } + $column = $values['column'] ?? $values[0]; + $value = $values['value'] ?? $values[1]; if (!is_numeric($value)) { $value = "'{$value}'"; } @@ -40,13 +53,11 @@ abstract class Update extends Query implements Database\Query\Update public function setValues(array|string $values): Database\Query\Update { if (is_string($values)) { - $this->values = $values; + $this->addValue($values); return $this; } foreach ($values as $value) { - $column = $value['column'] ?? $value[0]; - $val = $value['value'] ?? $value[1]; - $this->addValue($column, $val); + $this->addValue($value); } return $this; } diff --git a/src/Implement/Database/Query/Create.php b/src/Implement/Database/Query/Create.php deleted file mode 100644 index 6ea7aeb..0000000 --- a/src/Implement/Database/Query/Create.php +++ /dev/null @@ -1,62 +0,0 @@ -table($table); - } - - public function table(string $table): Database\Query\Create - { - return $this->setTable($table); - } - public function columns(array|string $columns): Database\Query\Create - { - return $this->setColumns($columns); - } - - protected array|string $columns; - - public function getColumns(): array - { - return $this->columns; - } - - public function addColumn(string $column): Database\Query\Create - { - $this->columns []= $column; - return $this; - } - - public function setColumns(array|string $columns): Database\Query\Create - { - if (is_string($columns)) { - $this->columns = $columns; - return $this; - } - foreach ($columns as $column) { - $this->addColumn($column); - } - return $this; - } - - protected function getColumnsString(): string - { - if (is_string($this->columns)) { - return $this->columns; - } - return implode(', ', $this->getColumns()); - } - - public function build(): string - { - return "CREATE {$this->getTable()} ({$this->getColumnsString()})"; - } -} diff --git a/src/Implement/Database/Query/Drop.php b/src/Implement/Database/Query/Drop.php deleted file mode 100644 index 3217561..0000000 --- a/src/Implement/Database/Query/Drop.php +++ /dev/null @@ -1,27 +0,0 @@ -table($table); - } - } - - public function table(string $table): Database\Query\Drop - { - return $this->setTable($table); - } - - public function build(): string - { - return "DROP TABLE {$this->getTable()}"; - } -} diff --git a/src/Implement/Database/Query/hasConditions.php b/src/Reinforce/Database/Query/hasConditions.php similarity index 67% rename from src/Implement/Database/Query/hasConditions.php rename to src/Reinforce/Database/Query/hasConditions.php index b0e65f7..0f53bf0 100644 --- a/src/Implement/Database/Query/hasConditions.php +++ b/src/Reinforce/Database/Query/hasConditions.php @@ -1,5 +1,5 @@ conditions ?? ''; } - protected function setConditions(array|string $conditions) + protected function setConditions(array|string $conditions): self { - $this->conditions = $conditions; + if (is_array($conditions)) { + foreach ($conditions as $condition) { + $this->addCondition($condition); + } + } else { + $this->addCondition($conditions); + } + return $this; + } + protected function addCondition(array|string $condition): self + { + $this->conditions []= $condition; return $this; } @@ -35,7 +46,8 @@ trait hasConditions return "AND {$condition}"; }, $conditions)); } - if (trim($conditions) === '') { + $conditions = trim($conditions); + if ($conditions === '') { return ''; } return " WHERE {$conditions}"; diff --git a/src/Implement/Database/Query/hasTable.php b/src/Reinforce/Database/Query/hasTable.php similarity index 82% rename from src/Implement/Database/Query/hasTable.php rename to src/Reinforce/Database/Query/hasTable.php index f1b478d..dffc2e3 100644 --- a/src/Implement/Database/Query/hasTable.php +++ b/src/Reinforce/Database/Query/hasTable.php @@ -1,5 +1,5 @@ table; } - public function setTable(string $table, ?string $alias = null) + public function setTable(string $table, ?string $alias = null): self { - $table = "`{$table}`"; if ($alias !== null) { $table = "{$table} '{$alias}'"; } From e6759bcf0661c3fcc912ef0473e385a157b7620a Mon Sep 17 00:00:00 2001 From: Aldarien Date: Sat, 3 Aug 2024 21:04:28 -0400 Subject: [PATCH 3/4] FIX: parenthesis --- src/Ideal/Database/Query/Select.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ideal/Database/Query/Select.php b/src/Ideal/Database/Query/Select.php index 5e1b358..7aed37b 100644 --- a/src/Ideal/Database/Query/Select.php +++ b/src/Ideal/Database/Query/Select.php @@ -199,7 +199,7 @@ abstract class Select extends Query implements Database\Query\Select return '*'; } $columns = (is_array($this->getColumns())) ? implode(', ', $this->getColumns()) : $this->getColumns(); - return "({$columns})"; + return "{$columns}"; } protected function getJoinsString(): string { From f07ad79e753386a385e4c4d5c3a361d6e72e679b Mon Sep 17 00:00:00 2001 From: Aldarien Date: Mon, 29 Sep 2025 16:40:43 -0300 Subject: [PATCH 4/4] Update namespaces --- .gitignore | 3 ++ Readme.md | 8 ++-- composer.json | 2 +- phpunit.xml | 25 ++++++++++ src/Concept/Database/Query/Delete.php | 10 ---- src/Concept/Database/Query/Drop.php | 9 ---- src/Concept/Database/Query/Insert.php | 12 ----- src/Concept/Database/Query/Select.php | 15 ------ src/Concept/Database/Query/Truncate.php | 9 ---- src/Concept/Database/Query/Update.php | 11 ----- src/{Concept/Database => Define}/Query.php | 2 +- .../Database => Define}/Query/Builder.php | 2 +- .../Database => Define}/Query/Create.php | 4 +- src/Define/Query/Delete.php | 10 ++++ src/Define/Query/Drop.php | 9 ++++ src/Define/Query/Insert.php | 12 +++++ src/Define/Query/Select.php | 15 ++++++ src/Define/Query/Truncate.php | 9 ++++ src/Define/Query/Update.php | 11 +++++ src/Enforce/Database/Query/MySQL/Create.php | 8 ---- src/Enforce/Database/Query/MySQL/Delete.php | 8 ---- src/Enforce/Database/Query/MySQL/Drop.php | 8 ---- src/Enforce/Database/Query/MySQL/Insert.php | 8 ---- src/Enforce/Database/Query/MySQL/Truncate.php | 8 ---- src/Enforce/Database/Query/MySQL/Update.php | 8 ---- .../Database/Query/PostgreSQL/Create.php | 8 ---- .../Database/Query/PostgreSQL/Delete.php | 8 ---- .../Database/Query/PostgreSQL/Drop.php | 8 ---- .../Database/Query/PostgreSQL/Insert.php | 8 ---- .../Database/Query/PostgreSQL/Select.php | 8 ---- .../Database/Query/PostgreSQL/Truncate.php | 8 ---- .../Database/Query/PostgreSQL/Update.php | 8 ---- src/Except/Missing/Columns.php | 15 ++++++ src/Except/Query.php | 15 ++++++ src/Ideal/{Database => }/Query.php | 6 +-- src/Ideal/{Database => }/Query/Create.php | 35 ++++++++------ src/Ideal/{Database => }/Query/Delete.php | 14 +++--- src/Ideal/{Database => }/Query/Drop.php | 14 +++--- src/Ideal/{Database => }/Query/Insert.php | 28 +++++------ src/Ideal/{Database => }/Query/Select.php | 46 +++++++++---------- src/Ideal/{Database => }/Query/Truncate.php | 12 ++--- src/Ideal/{Database => }/Query/Update.php | 20 ++++---- .../Database => Implement}/Query/Builder.php | 8 ++-- src/Implement/Query/MySQL/Create.php | 13 ++++++ src/Implement/Query/MySQL/Delete.php | 13 ++++++ src/Implement/Query/MySQL/Drop.php | 13 ++++++ src/Implement/Query/MySQL/Insert.php | 13 ++++++ .../Query/MySQL/Select.php | 16 +++++-- src/Implement/Query/MySQL/Truncate.php | 13 ++++++ src/Implement/Query/MySQL/Update.php | 22 +++++++++ src/Implement/Query/PostgreSQL/Create.php | 8 ++++ src/Implement/Query/PostgreSQL/Delete.php | 8 ++++ src/Implement/Query/PostgreSQL/Drop.php | 8 ++++ src/Implement/Query/PostgreSQL/Insert.php | 8 ++++ src/Implement/Query/PostgreSQL/Select.php | 8 ++++ src/Implement/Query/PostgreSQL/Truncate.php | 8 ++++ src/Implement/Query/PostgreSQL/Update.php | 8 ++++ .../{Database => }/Query/hasConditions.php | 2 +- .../{Database => }/Query/hasTable.php | 2 +- tests/MySQLCreateTest.php | 24 ++++++++++ tests/MySQLDeleteTest.php | 15 ++++++ tests/MySQLDropTest.php | 15 ++++++ tests/MySQLInsertTest.php | 16 +++++++ tests/MySQLSelectTest.php | 24 ++++++++++ tests/MySQLTruncateTest.php | 15 ++++++ tests/MySQLUpdateTest.php | 16 +++++++ 66 files changed, 509 insertions(+), 274 deletions(-) create mode 100644 phpunit.xml delete mode 100644 src/Concept/Database/Query/Delete.php delete mode 100644 src/Concept/Database/Query/Drop.php delete mode 100644 src/Concept/Database/Query/Insert.php delete mode 100644 src/Concept/Database/Query/Select.php delete mode 100644 src/Concept/Database/Query/Truncate.php delete mode 100644 src/Concept/Database/Query/Update.php rename src/{Concept/Database => Define}/Query.php (74%) rename src/{Concept/Database => Define}/Query/Builder.php (91%) rename src/{Concept/Database => Define}/Query/Create.php (74%) create mode 100644 src/Define/Query/Delete.php create mode 100644 src/Define/Query/Drop.php create mode 100644 src/Define/Query/Insert.php create mode 100644 src/Define/Query/Select.php create mode 100644 src/Define/Query/Truncate.php create mode 100644 src/Define/Query/Update.php delete mode 100644 src/Enforce/Database/Query/MySQL/Create.php delete mode 100644 src/Enforce/Database/Query/MySQL/Delete.php delete mode 100644 src/Enforce/Database/Query/MySQL/Drop.php delete mode 100644 src/Enforce/Database/Query/MySQL/Insert.php delete mode 100644 src/Enforce/Database/Query/MySQL/Truncate.php delete mode 100644 src/Enforce/Database/Query/MySQL/Update.php delete mode 100644 src/Enforce/Database/Query/PostgreSQL/Create.php delete mode 100644 src/Enforce/Database/Query/PostgreSQL/Delete.php delete mode 100644 src/Enforce/Database/Query/PostgreSQL/Drop.php delete mode 100644 src/Enforce/Database/Query/PostgreSQL/Insert.php delete mode 100644 src/Enforce/Database/Query/PostgreSQL/Select.php delete mode 100644 src/Enforce/Database/Query/PostgreSQL/Truncate.php delete mode 100644 src/Enforce/Database/Query/PostgreSQL/Update.php create mode 100644 src/Except/Missing/Columns.php create mode 100644 src/Except/Query.php rename src/Ideal/{Database => }/Query.php (68%) rename src/Ideal/{Database => }/Query/Create.php (78%) rename src/Ideal/{Database => }/Query/Delete.php (56%) rename src/Ideal/{Database => }/Query/Drop.php (63%) rename src/Ideal/{Database => }/Query/Insert.php (68%) rename src/Ideal/{Database => }/Query/Select.php (83%) rename src/Ideal/{Database => }/Query/Truncate.php (53%) rename src/Ideal/{Database => }/Query/Update.php (72%) rename src/{Enforce/Database => Implement}/Query/Builder.php (95%) create mode 100644 src/Implement/Query/MySQL/Create.php create mode 100644 src/Implement/Query/MySQL/Delete.php create mode 100644 src/Implement/Query/MySQL/Drop.php create mode 100644 src/Implement/Query/MySQL/Insert.php rename src/{Enforce/Database => Implement}/Query/MySQL/Select.php (75%) create mode 100644 src/Implement/Query/MySQL/Truncate.php create mode 100644 src/Implement/Query/MySQL/Update.php create mode 100644 src/Implement/Query/PostgreSQL/Create.php create mode 100644 src/Implement/Query/PostgreSQL/Delete.php create mode 100644 src/Implement/Query/PostgreSQL/Drop.php create mode 100644 src/Implement/Query/PostgreSQL/Insert.php create mode 100644 src/Implement/Query/PostgreSQL/Select.php create mode 100644 src/Implement/Query/PostgreSQL/Truncate.php create mode 100644 src/Implement/Query/PostgreSQL/Update.php rename src/Reinforce/{Database => }/Query/hasConditions.php (97%) rename src/Reinforce/{Database => }/Query/hasTable.php (89%) create mode 100644 tests/MySQLCreateTest.php create mode 100644 tests/MySQLDeleteTest.php create mode 100644 tests/MySQLDropTest.php create mode 100644 tests/MySQLInsertTest.php create mode 100644 tests/MySQLSelectTest.php create mode 100644 tests/MySQLTruncateTest.php create mode 100644 tests/MySQLUpdateTest.php diff --git a/.gitignore b/.gitignore index eed7ff6..145d260 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,6 @@ # PHPStorm **/.idea/ + +# PHPUnit +**/.phpunit.cache/ diff --git a/Readme.md b/Readme.md index a78b9f7..a90d64a 100644 --- a/Readme.md +++ b/Readme.md @@ -28,16 +28,16 @@ ## Setup ``` -$container->set(ProVM\Concept\Database\Query\Select::class, function(Psr\Container\ContainerInterface $container) { +$container->set(Database\Define\Query\Select::class, function(Psr\Container\ContainerInterface $container) { return $container->get(ProVM\Database\Query\MySQL\Select::class); }); -$container->set(ProVM\Concept\Database\Query\Insert::class, function(Psr\Container\ContainerInterface $container) { +$container->set(Database\Define\Query\Insert::class, function(Psr\Container\ContainerInterface $container) { return $container->get(ProVM\Database\Query\MySQL\Insert::class); }); -$container->set(ProVM\Concept\Database\Query\Update::class, function(Psr\Container\ContainerInterface $container) { +$container->set(Database\Define\Query\Update::class, function(Psr\Container\ContainerInterface $container) { return $container->get(ProVM\Database\Query\MySQL\Update::class); }); -$container->set(ProVM\Concept\Database\Query\Delete::class, function(Psr\Container\ContainerInterface $container) { +$container->set(Database\Define\Query\Delete::class, function(Psr\Container\ContainerInterface $container) { return $container->get(ProVM\Database\Query\MySQL\Delete::class); }); ``` diff --git a/composer.json b/composer.json index f42ea8b..0988624 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,7 @@ }, "autoload": { "psr-4": { - "ProVM\\": "src/" + "Database\\": "src/" } } } diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 0000000..4e0d19f --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,25 @@ + + + + + tests + + + + + + src + + + diff --git a/src/Concept/Database/Query/Delete.php b/src/Concept/Database/Query/Delete.php deleted file mode 100644 index 57529a4..0000000 --- a/src/Concept/Database/Query/Delete.php +++ /dev/null @@ -1,10 +0,0 @@ -temp = true; return $this; } - public function ifNotExists(): Database\Query\Create + public function ifNotExists(): self { $this->exists = true; return $this; } - public function table(string $table): Database\Query\Create + public function table(string $table): self { return $this->setTable($table); } - public function columns(array|string $columns): Database\Query\Create + public function columns(array|string $columns): self { return $this->setColumns($columns); } - public function foreign(array|string $columnDefinition): Database\Query\Create + public function foreign(array|string $columnDefinition): self { return $this->setForeign($columnDefinition); } @@ -46,16 +47,19 @@ abstract class Create extends Query implements Database\Query\Create public function getColumns(): array { + if (!isset($this->columns)) { + throw new Except\Missing\Columns($this->getTable()); + } return $this->columns; } - public function addColumn(string $column): Database\Query\Create + public function addColumn(string $column): self { $this->columns []= $column; return $this; } - public function setColumns(array|string $columns): Database\Query\Create + public function setColumns(array|string $columns): self { if (is_string($columns)) { $this->addColumn($columns); @@ -70,7 +74,7 @@ abstract class Create extends Query implements Database\Query\Create { return $this->foreign; } - public function addForeign(string|array $definition): Database\Query\Create + public function addForeign(string|array $definition): self { if (is_string($definition)) { $this->foreign []= $definition; @@ -87,7 +91,7 @@ abstract class Create extends Query implements Database\Query\Create $this->foreign []= "CONSTRAINT {$fk} FOREIGN KEY ({$columns}) REFERENCES {$definition['table']} ({$ids}) ON DELETE {$delete} ON UPDATE {$update}"; return $this; } - public function setForeign(array|string $columnDefinition): Database\Query\Create + public function setForeign(array|string $columnDefinition): self { if (is_string($columnDefinition)) { $this->addForeign($columnDefinition); @@ -109,6 +113,9 @@ abstract class Create extends Query implements Database\Query\Create } protected function getColumnsString(): string { + if (!isset($this->columns)) { + throw new Except\Missing\Columns($this->getTable()); + } if (is_string($this->columns)) { return $this->columns; } diff --git a/src/Ideal/Database/Query/Delete.php b/src/Ideal/Query/Delete.php similarity index 56% rename from src/Ideal/Database/Query/Delete.php rename to src/Ideal/Query/Delete.php index 621afdf..4579157 100644 --- a/src/Ideal/Database/Query/Delete.php +++ b/src/Ideal/Query/Delete.php @@ -1,11 +1,11 @@ from($table); } } - public function from(string $table): Database\Query\Delete + public function from(string $table): self { return $this->setTable($table); } - public function where(array|string $conditions): Database\Query\Delete + public function where(array|string $conditions): self { return $this->setConditions($conditions); } diff --git a/src/Ideal/Database/Query/Drop.php b/src/Ideal/Query/Drop.php similarity index 63% rename from src/Ideal/Database/Query/Drop.php rename to src/Ideal/Query/Drop.php index 083ca3c..9857377 100644 --- a/src/Ideal/Database/Query/Drop.php +++ b/src/Ideal/Query/Drop.php @@ -1,11 +1,11 @@ table($table); } } - public function table(string $table): Database\Query\Drop + public function table(string $table): self { return $this->setTable($table); } - public function cascade(): Database\Query\Drop + public function cascade(): self { $this->cascade = true; return $this; diff --git a/src/Ideal/Database/Query/Insert.php b/src/Ideal/Query/Insert.php similarity index 68% rename from src/Ideal/Database/Query/Insert.php rename to src/Ideal/Query/Insert.php index 9f31fc6..00daa9c 100644 --- a/src/Ideal/Database/Query/Insert.php +++ b/src/Ideal/Query/Insert.php @@ -1,11 +1,11 @@ setTable($table); } - public function columns(array|string $columns): Database\Query\Insert + public function columns(array|string $columns): self { return $this->setColumns($columns); } - public function values(array|string $values): Database\Query\Insert + public function values(array|string $values): self { return $this->setValues($values); } - public function select(Database\Query\Select|string $select): Database\Query\Insert + public function select(Define\Query\Select|string $select): self { return $this->setSelect($select); } protected array|string $columns; protected array|string $values; - protected Database\Query\Select|string $select; + protected Define\Query\Select|string $select; public function getColumns(): array|string { @@ -45,22 +45,22 @@ abstract class Insert extends Query implements Database\Query\Insert { return $this->values; } - public function getSelect(): Database\Query\Select|string + public function getSelect(): Define\Query\Select|string { return $this->select; } - public function setColumns(array|string $columns): Database\Query\Insert + public function setColumns(array|string $columns): self { $this->columns = $columns; return $this; } - public function setValues(array|string $values): Database\Query\Insert + public function setValues(array|string $values): self { $this->values = $values; return $this; } - public function setSelect(Database\Query\Select|string $select): Database\Query\Insert + public function setSelect(Define\Query\Select|string $select): self { $this->select = $select; return $this; diff --git a/src/Ideal/Database/Query/Select.php b/src/Ideal/Query/Select.php similarity index 83% rename from src/Ideal/Database/Query/Select.php rename to src/Ideal/Query/Select.php index 7aed37b..07e188e 100644 --- a/src/Ideal/Database/Query/Select.php +++ b/src/Ideal/Query/Select.php @@ -1,11 +1,11 @@ columns($columns); } - public function columns(array|string $columns = '*'): Database\Query\Select + public function columns(array|string $columns = '*'): self { return $this->setColumns($columns); } - public function from(string $table): Database\Query\Select + public function from(string $table): self { return $this->setTable($table); } - public function joined(array|string $joins): Database\Query\Select + public function joined(array|string $joins): self { return $this->setJoins($joins); } - public function where(array|string $conditions): Database\Query\Select + public function where(array|string $conditions): self { return $this->setConditions($conditions); } - public function groupBy(array|string $grouping): Database\Query\Select + public function groupBy(array|string $grouping): self { return $this->setGroups($grouping); } - public function having(array|string $having): Database\Query\Select + public function having(array|string $having): self { return $this->setHaving($having); } - public function orderBy(array|string $ordering): Database\Query\Select + public function orderBy(array|string $ordering): self { return $this->setOrders($ordering); } - public function limit(int $limit, ?int $offset = null): Database\Query\Select + public function limit(int $limit, ?int $offset = null): self { $this->limit = $limit; if ($offset !== null) { @@ -85,7 +85,7 @@ abstract class Select extends Query implements Database\Query\Select return $this->orders; } - public function addColumn(string $column, ?string $alias = null): Database\Query\Select + public function addColumn(string $column, ?string $alias = null): self { if ($column === '*') { $this->columns []= $column; @@ -98,22 +98,22 @@ abstract class Select extends Query implements Database\Query\Select $this->columns[] = "`{$column}`{$a}"; return $this; } - public function addJoin(string $table, string $expression): Database\Query\Select + public function addJoin(string $table, string $expression): self { $this->joins []= "{$table} ON {$expression}"; return $this; } - public function addGroup(string $group): Database\Query\Select + public function addGroup(string $group): self { $this->groups []= "`{$group}`"; return $this; } - public function addHaving(string $having): Database\Query\Select + public function addHaving(string $having): self { $this->having []= $having; return $this; } - public function addOrder(string $column, ?string $direction = null): Database\Query\Select + public function addOrder(string $column, ?string $direction = null): self { if ($direction === null) { $direction = 'ASC'; @@ -122,7 +122,7 @@ abstract class Select extends Query implements Database\Query\Select return $this; } - public function setColumns(array|string $columns): Database\Query\Select + public function setColumns(array|string $columns): self { if (is_string($columns)) { $this->columns = $columns; @@ -139,7 +139,7 @@ abstract class Select extends Query implements Database\Query\Select } return $this; } - public function setJoins(array|string $joins): Database\Query\Select + public function setJoins(array|string $joins): self { if (is_string($joins)) { $this->joins = $joins; @@ -152,7 +152,7 @@ abstract class Select extends Query implements Database\Query\Select } return $this; } - public function setGroups(array|string $groups): Database\Query\Select + public function setGroups(array|string $groups): self { if (is_string($groups)) { $this->groups = $groups; @@ -163,7 +163,7 @@ abstract class Select extends Query implements Database\Query\Select } return $this; } - public function setHaving(array|string $having): Database\Query\Select + public function setHaving(array|string $having): self { if (is_string($having)) { $this->having = $having; @@ -174,7 +174,7 @@ abstract class Select extends Query implements Database\Query\Select } return $this; } - public function setOrders(array|string $orders): Database\Query\Select + public function setOrders(array|string $orders): self { if (is_string($orders)) { $this->orders = $orders; diff --git a/src/Ideal/Database/Query/Truncate.php b/src/Ideal/Query/Truncate.php similarity index 53% rename from src/Ideal/Database/Query/Truncate.php rename to src/Ideal/Query/Truncate.php index 9299dd6..9d87c22 100644 --- a/src/Ideal/Database/Query/Truncate.php +++ b/src/Ideal/Query/Truncate.php @@ -1,11 +1,11 @@ table($table); } } - public function table(string $table): Database\Query\Truncate + public function table(string $table): self { return $this->setTable($table); } diff --git a/src/Ideal/Database/Query/Update.php b/src/Ideal/Query/Update.php similarity index 72% rename from src/Ideal/Database/Query/Update.php rename to src/Ideal/Query/Update.php index 8867325..bf5645d 100644 --- a/src/Ideal/Database/Query/Update.php +++ b/src/Ideal/Query/Update.php @@ -1,11 +1,11 @@ table($table); } } - public function table(string $table): Database\Query\Update + public function table(string $table): self { return $this->setTable($table); } - public function set(array|string $value_pairs): Database\Query\Update + public function set(array|string $value_pairs): self { return $this->setValues($value_pairs); } - public function where(array|string $conditions): Database\Query\Update + public function where(array|string $conditions): self { return $this->setConditions($conditions); } @@ -35,7 +35,7 @@ abstract class Update extends Query implements Database\Query\Update return $this->values; } - public function addValue(string|array $values): Database\Query\Update + public function addValue(string|array $values): self { if (is_string($values)) { $this->values []= $values; @@ -50,7 +50,7 @@ abstract class Update extends Query implements Database\Query\Update return $this; } - public function setValues(array|string $values): Database\Query\Update + public function setValues(array|string $values): self { if (is_string($values)) { $this->addValue($values); diff --git a/src/Enforce/Database/Query/Builder.php b/src/Implement/Query/Builder.php similarity index 95% rename from src/Enforce/Database/Query/Builder.php rename to src/Implement/Query/Builder.php index 5f4f054..ef194b1 100644 --- a/src/Enforce/Database/Query/Builder.php +++ b/src/Implement/Query/Builder.php @@ -1,9 +1,9 @@ query_classes[$query_interface]; } - protected function addQuery(string $query_interface, string $query): Builder + protected function addQuery(string $query_interface, string $query): self { $this->query_classes[$query_interface] = $query; return $this; } - protected function setQueries(array $queries): Builder + protected function setQueries(array $queries): self { foreach ($queries as $interface => $query) { $this->addQuery($interface, $query); diff --git a/src/Implement/Query/MySQL/Create.php b/src/Implement/Query/MySQL/Create.php new file mode 100644 index 0000000..6a00bb8 --- /dev/null +++ b/src/Implement/Query/MySQL/Create.php @@ -0,0 +1,13 @@ +setLimit($limit); if ($offset !== null) { @@ -14,6 +14,12 @@ class Select extends Query\Select return $this; } + public function getTable(): string + { + $table = parent::getTable(); + return "`{$table}`"; + } + protected int $limit; protected int $offset; @@ -26,12 +32,12 @@ class Select extends Query\Select return $this->offset; } - public function setLimit(int $limit): Select + public function setLimit(int $limit): self { $this->limit = $limit; return $this; } - public function setOffset(int $offset): Select + public function setOffset(int $offset): self { $this->offset = $offset; return $this; diff --git a/src/Implement/Query/MySQL/Truncate.php b/src/Implement/Query/MySQL/Truncate.php new file mode 100644 index 0000000..fcda278 --- /dev/null +++ b/src/Implement/Query/MySQL/Truncate.php @@ -0,0 +1,13 @@ +getTable()}", + $this->getValuesString(), + $this->getConditionsString() + ]); + } +} diff --git a/src/Implement/Query/PostgreSQL/Create.php b/src/Implement/Query/PostgreSQL/Create.php new file mode 100644 index 0000000..a596f4c --- /dev/null +++ b/src/Implement/Query/PostgreSQL/Create.php @@ -0,0 +1,8 @@ +table('test_table'); + $query->columns('`column1` int'); + + $expected = "CREATE TABLE `test_table` (`column1` int)"; + + $this->assertEquals($expected, "{$query}"); + } + public function testMissingColumns(): void + { + $query = new Database\Implement\Query\MySQL\Create(); + $query->table('test_table'); + + $this->expectException(Database\Except\Missing\Columns::class); + echo "{$query}"; + } +} \ No newline at end of file diff --git a/tests/MySQLDeleteTest.php b/tests/MySQLDeleteTest.php new file mode 100644 index 0000000..f811a19 --- /dev/null +++ b/tests/MySQLDeleteTest.php @@ -0,0 +1,15 @@ +from('test_table'); + + $expected = "DELETE FROM `test_table`"; + + $this->assertEquals($expected, "{$query}"); + } +} \ No newline at end of file diff --git a/tests/MySQLDropTest.php b/tests/MySQLDropTest.php new file mode 100644 index 0000000..4729fa4 --- /dev/null +++ b/tests/MySQLDropTest.php @@ -0,0 +1,15 @@ +table('test_table'); + + $expected = "DROP TABLE `test_table`"; + + $this->assertEquals($expected, "{$query}"); + } +} \ No newline at end of file diff --git a/tests/MySQLInsertTest.php b/tests/MySQLInsertTest.php new file mode 100644 index 0000000..01e1cde --- /dev/null +++ b/tests/MySQLInsertTest.php @@ -0,0 +1,16 @@ +into('test_table'); + $query->values('?, ?, ?'); + + $expected = "INSERT INTO `test_table` VALUES (?, ?, ?)"; + + $this->assertEquals($expected, "{$query}"); + } +} \ No newline at end of file diff --git a/tests/MySQLSelectTest.php b/tests/MySQLSelectTest.php new file mode 100644 index 0000000..6758971 --- /dev/null +++ b/tests/MySQLSelectTest.php @@ -0,0 +1,24 @@ +from('test_table'); + + $expected = "SELECT * FROM `test_table`"; + + $this->assertEquals($expected, "{$query}"); + } + public function testColumns(): void + { + $query = new Database\Implement\Query\MySQL\Select('asd'); + $query->from('test_table'); + + $expected = "SELECT asd FROM `test_table`"; + + $this->assertEquals($expected, "{$query}"); + } +} \ No newline at end of file diff --git a/tests/MySQLTruncateTest.php b/tests/MySQLTruncateTest.php new file mode 100644 index 0000000..69b22e0 --- /dev/null +++ b/tests/MySQLTruncateTest.php @@ -0,0 +1,15 @@ +table('test_table'); + + $expected = "TRUNCATE TABLE `test_table`"; + + $this->assertEquals($expected, "{$query}"); + } +} diff --git a/tests/MySQLUpdateTest.php b/tests/MySQLUpdateTest.php new file mode 100644 index 0000000..ceccf32 --- /dev/null +++ b/tests/MySQLUpdateTest.php @@ -0,0 +1,16 @@ +table('test_table'); + $query->set('column1 = 0'); + + $expected = "UPDATE TABLE `test_table` SET column1 = 0"; + + $this->assertEquals($expected, "{$query}"); + } +} \ No newline at end of file