From 64e3f26022771ab8ecffe128c58de16fdfddd106 Mon Sep 17 00:00:00 2001 From: Murilo Elias Date: Sun, 29 Sep 2024 02:46:08 -0300 Subject: [PATCH] [update] - added database function declaration --- README.md | 2 -- example/Hr.php | 10 ++++++++++ src/Abstract/Schema.php | 12 ++++++++++++ src/Abstract/Table.php | 22 +++++++++++++++++++++ src/Core/Manager.php | 23 +++++++++++++++++++++- src/Database/DatabaseFunction.php | 32 +++++++++++++++++++++++++++++++ test.php | 3 +++ 7 files changed, 101 insertions(+), 3 deletions(-) create mode 100644 src/Database/DatabaseFunction.php diff --git a/README.md b/README.md index 4a8fa6d..4808326 100644 --- a/README.md +++ b/README.md @@ -253,8 +253,6 @@ foreach ($queries as $query) { } ``` -Sure! Here are the explanations for the available commands that can be included in the `README.md`: - ### Commands Maestro provides several commands to help you manage and synchronize your database schema. Here are the available commands: diff --git a/example/Hr.php b/example/Hr.php index ca08371..e929e97 100644 --- a/example/Hr.php +++ b/example/Hr.php @@ -2,9 +2,19 @@ namespace Maestro\Example; use Ilias\Maestro\Abstract\Schema; +use Ilias\Maestro\Types\Postgres; final class Hr extends Schema { public User $user; public AuthCode $authCode; + + public function __construct() + { + self::declareFunction( + 'generate_four_digit_auth_code', + Postgres::TEXT, + 'CREATE OR REPLACE FUNCTION generate_four_digit_auth_code() RETURNS TEXT AS $$ BEGIN RETURN CAST(FLOOR(1000 + RANDOM() * 9000) AS TEXT); END; $$ LANGUAGE plpgsql;' + ); + } } \ No newline at end of file diff --git a/src/Abstract/Schema.php b/src/Abstract/Schema.php index f05dac7..ecb39cd 100644 --- a/src/Abstract/Schema.php +++ b/src/Abstract/Schema.php @@ -2,11 +2,13 @@ namespace Ilias\Maestro\Abstract; +use Ilias\Maestro\Database\DatabaseFunction; use Ilias\Maestro\Utils\Utils; abstract class Schema extends \stdClass { use Sanitizable; + private static array $functions = []; public static function getSchemaName(): string { return static::class; @@ -27,6 +29,16 @@ public static function getTables(): array return $tables; } + public static function declareFunction(string $name, string $returnType, string $sqlDefinition) + { + self::$functions[$name] = new DatabaseFunction($name, $returnType, $sqlDefinition); + } + + public static function getFunctions(): array + { + return self::$functions; + } + public static function dumpSchema(): array { $tablesMap = []; diff --git a/src/Abstract/Table.php b/src/Abstract/Table.php index 14cc54b..e1d8237 100644 --- a/src/Abstract/Table.php +++ b/src/Abstract/Table.php @@ -3,6 +3,7 @@ namespace Ilias\Maestro\Abstract; use Exception; +use Ilias\Maestro\Core\Maestro; use Ilias\Maestro\Database\Select; use Ilias\Maestro\Utils\Utils; @@ -59,6 +60,27 @@ public static function tableColumns(): array return $columns; } + public static function getUniqueColumns(): array + { + return self::tableColumnsProperties(Maestro::DOC_UNIQUE); + } + + public static function tableColumnsProperties(string $atDocClause = ''): array + { + $reflection = new \ReflectionClass(static::class); + $properties = $reflection->getProperties(\ReflectionProperty::IS_PUBLIC); + $uniqueColumns = []; + + foreach ($properties as $property) { + $docComment = $property->getDocComment(); + if ($docComment && strpos($docComment, $atDocClause) !== false) { + $uniqueColumns[] = $property->getName(); + } + } + + return $uniqueColumns; + } + final public static function tableIdentifier(): array { foreach (static::tableColumns() as $name => $type) { diff --git a/src/Core/Manager.php b/src/Core/Manager.php index 1cc46ee..ea15cbd 100644 --- a/src/Core/Manager.php +++ b/src/Core/Manager.php @@ -49,6 +49,7 @@ public function createDatabase(Database $database, bool $executeOnComplete = tru $schemasSql = []; $tablesSql = []; $constraintsSql = []; + $functionsSql = []; $schemas = $database::getSchemas(); foreach ($schemas as $schemaClass) { @@ -56,9 +57,10 @@ public function createDatabase(Database $database, bool $executeOnComplete = tru [$create, $constraints] = $this->createSchemaTables($schemaClass); $tablesSql = array_merge($tablesSql, $create); $constraintsSql = array_merge($constraintsSql, ...$constraints); + $functionsSql = array_merge($functionsSql, $this->createSchemaFunctions($schemaClass)); } - $sql = array_merge($schemasSql, $tablesSql, $constraintsSql); + $sql = array_merge($schemasSql, $tablesSql, $constraintsSql, $functionsSql); if ($executeOnComplete) { foreach ($sql as $query) { $this->executeQuery($this->pdo, $query); @@ -177,6 +179,25 @@ public function createTable(string $table): string return $query; } + /** + * Create functions for a schema. + * + * @param string|Schema $schema + * @return array + */ + public function createSchemaFunctions(string|Schema $schema): array + { + $functionsSql = []; + new $schema(); + $functions = $schema::getFunctions(); + + foreach ($functions as $function) { + $functionsSql[] = $function->getSqlDefinition(); + } + + return $functionsSql; + } + /** * Get the column type. * diff --git a/src/Database/DatabaseFunction.php b/src/Database/DatabaseFunction.php new file mode 100644 index 0000000..ed097dd --- /dev/null +++ b/src/Database/DatabaseFunction.php @@ -0,0 +1,32 @@ +name = $name; + $this->returnType = $returnType; + $this->sqlDefinition = $sqlDefinition; + } + + public function getName(): string + { + return $this->name; + } + + public function getReturnType(): string + { + return $this->returnType; + } + + public function getSqlDefinition(): string + { + return $this->sqlDefinition; + } +} \ No newline at end of file diff --git a/test.php b/test.php index c945cb6..284d313 100644 --- a/test.php +++ b/test.php @@ -1,11 +1,14 @@ createDatabase($agrofastDB, false)) . "\n";