From 6dba837581578f0ebf7d9d82be1e5198f6afc587 Mon Sep 17 00:00:00 2001 From: megasteve19 Date: Mon, 8 Sep 2025 12:27:36 +0300 Subject: [PATCH 1/2] Fix PostgresGrammar initialization and update createBlueprint method signature --- src/Database/Schema/Builder.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Database/Schema/Builder.php b/src/Database/Schema/Builder.php index 83789fa..a861987 100755 --- a/src/Database/Schema/Builder.php +++ b/src/Database/Schema/Builder.php @@ -15,7 +15,7 @@ class Builder extends IlluminateBuilder public function __construct(Connection $connection) { parent::__construct($connection); - $this->grammar = new PostgresGrammar(); + $this->grammar = new PostgresGrammar($connection); } /** @@ -284,7 +284,7 @@ public function detachPartition(string $table, Closure $callback, string $partit * @return Closure|mixed|object|Blueprint|null * @throws BindingResolutionException */ - protected function createBlueprint($table, Closure $callback = null): mixed + protected function createBlueprint($table, ?Closure $callback = null): mixed { $prefix = $this->connection->getConfig('prefix_indexes') ? $this->connection->getConfig('prefix') From 335cb48dc9961e17602605bb872f691c752c0a62 Mon Sep 17 00:00:00 2001 From: megasteve19 Date: Mon, 8 Sep 2025 12:47:23 +0300 Subject: [PATCH 2/2] Extract compiling to individual trait for re-usability --- .../Concerns/CompilesPartitionQueries.php | 275 ++++++++++++++++++ .../Schema/Grammars/PostgresGrammar.php | 239 +-------------- 2 files changed, 277 insertions(+), 237 deletions(-) create mode 100644 src/Database/Concerns/CompilesPartitionQueries.php diff --git a/src/Database/Concerns/CompilesPartitionQueries.php b/src/Database/Concerns/CompilesPartitionQueries.php new file mode 100644 index 0000000..5f9d66e --- /dev/null +++ b/src/Database/Concerns/CompilesPartitionQueries.php @@ -0,0 +1,275 @@ +getColumns($blueprint)); + + if ($primaryKey = $this->shouldUsePrimaryKey($blueprint)) + { + $columns = sprintf('%s, %s', $columns, sprintf('primary key (%s, %s)', $blueprint->pkCompositeOne, $blueprint->pkCompositeTwo)); + } + + return array_values(array_filter(array_merge([sprintf( + 'create table %s (%s) partition by range (%s)', + $this->wrapTable($blueprint), + $columns, + $blueprint->rangeKey + )], $primaryKey ? $this->compileAutoIncrementStartingValues($blueprint, $command) : []))); + } + + /** + * Compile a create table partition command for a range partitioned table. + * + * @param Blueprint $blueprint + * @param Fluent $command + * + * @return array + */ + public function compileCreateRangePartition(Blueprint $blueprint, Fluent $command): array + { + return array_values(array_filter(array_merge([sprintf( + 'create table %s_%s partition of %s for values from (\'%s\') to (\'%s\')', + str_replace("\"", "", $this->wrapTable($blueprint)), + $blueprint->suffixForPartition, + str_replace("\"", "", $this->wrapTable($blueprint)), + $blueprint->startDate, + $blueprint->endDate + )], $this->shouldUsePrimaryKey($blueprint) ? $this->compileAutoIncrementStartingValues($blueprint, $command) : []))); + } + + /** + * Compile a create table command with its list partitions. + * + * @param Blueprint $blueprint + * @param Fluent $command + * + * @return string + */ + public function compileCreateListPartitioned(Blueprint $blueprint, Fluent $command): string + { + $columns = implode(', ', $this->getColumns($blueprint)); + + if ($this->shouldUsePrimaryKey($blueprint)) + { + $columns = sprintf('%s, %s', $columns, sprintf('primary key (%s, %s)', $blueprint->pkCompositeOne, $blueprint->pkCompositeTwo)); + } + + return sprintf( + 'create table %s (%s) partition by list(%s)', + $this->wrapTable($blueprint), + $columns, + $blueprint->listPartitionKey + ); + } + + /** + * Compile an attach partition command for a range partitioned table. + * + * @param Blueprint $blueprint + * @param Fluent $command + * + * @return string + */ + public function compileAttachRangePartition(Blueprint $blueprint, Fluent $command): string + { + return sprintf( + 'ALTER table %s attach partition %s for values from (\'%s\') to (\'%s\')', + str_replace("\"", "", $this->wrapTable($blueprint)), + $blueprint->partitionTableName, + $blueprint->startDate, + $blueprint->endDate + ); + } + + /** + * Compile a create table partition command for a list partitioned table. + * + * @param Blueprint $blueprint + * @param Fluent $command + * + * @return string + */ + public function compileCreateListPartition(Blueprint $blueprint, Fluent $command): string + { + return sprintf( + 'create table %s_%s partition of %s for values in (\'%s\')', + str_replace("\"", "", $this->wrapTable($blueprint)), + $blueprint->suffixForPartition, + str_replace("\"", "", $this->wrapTable($blueprint)), + $blueprint->listPartitionValue, + ); + } + + /** + * Compile an attach partition command for a list partitioned table. + * + * @param Blueprint $blueprint + * @param Fluent $command + * + * @return string + */ + public function compileAttachListPartition(Blueprint $blueprint, Fluent $command): string + { + return sprintf( + 'alter table %s partition of %s for values in (\'%s\')', + str_replace("\"", "", $this->wrapTable($blueprint)), + $blueprint->partitionTableName, + $blueprint->listPartitionValue, + ); + } + + /** + * Compile a create table partition command for a hash partitioned table. + * + * @param Blueprint $blueprint + * @param Fluent $command + * + * @return string + */ + public function compileCreateHashPartition(Blueprint $blueprint, Fluent $command): string + { + return sprintf( + 'create table %s_%s partition of %s for values with (modulus %s, remainder %s)', + str_replace("\"", "", $this->wrapTable($blueprint)), + $blueprint->suffixForPartition, + str_replace("\"", "", $this->wrapTable($blueprint)), + $blueprint->hashModulus, + $blueprint->hashRemainder + ); + } + + /** + * Compile a create table command with its hash partitions. + * + * @param Blueprint $blueprint + * @param Fluent $command + * + * @return array + */ + public function compileCreateHashPartitioned(Blueprint $blueprint, Fluent $command): array + { + $columns = implode(', ', $this->getColumns($blueprint)); + + if ($primaryKey = $this->shouldUsePrimaryKey($blueprint)) + { + $columns = sprintf('%s, %s', $columns, sprintf('primary key (%s, %s)', $blueprint->pkCompositeOne, $blueprint->pkCompositeTwo)); + } + + return array_values(array_filter(array_merge([sprintf( + 'create table %s (%s) partition by hash(%s)', + $this->wrapTable($blueprint), + $columns, + $blueprint->hashPartitionKey + )], $primaryKey ? $this->compileAutoIncrementStartingValues($blueprint, $command) : []))); + } + + /** + * Compile an attach partition command for a hash partitioned table. + * + * @param Blueprint $blueprint + * @param Fluent $command + * + * @return string + */ + public function compileAttachHashPartition(Blueprint $blueprint, Fluent $command): string + { + return sprintf( + 'alter table %s partition of %s for values with (modulus %s, remainder %s)', + str_replace("\"", "", $this->wrapTable($blueprint)), + $blueprint->partitionTableName, + $blueprint->hashModulus, + $blueprint->hashRemainder, + ); + } + + /** + * Get a list of all partitioned tables in the Database. + * + * @param string $table + * + * @return string + */ + public function compileGetPartitions(string $table): string + { + return sprintf( + "SELECT inhrelid::regclass as tables + FROM pg_catalog.pg_inherits + WHERE inhparent = '%s'::regclass;", + $table, + ); + } + + /** + * Get all range partitioned tables. + * + * @return string + */ + public function compileGetAllRangePartitionedTables(): string + { + return "select pg_class.relname as tables from pg_class inner join pg_partitioned_table on pg_class.oid = pg_partitioned_table.partrelid where pg_partitioned_table.partstrat = 'r';"; + } + + /** + * Get all list partitioned tables. + * + * @return string + */ + public function compileGetAllListPartitionedTables(): string + { + return "select pg_class.relname as tables from pg_class inner join pg_partitioned_table on pg_class.oid = pg_partitioned_table.partrelid where pg_partitioned_table.partstrat = 'l';"; + } + + /** + * Get all hash partitioned tables. + * + * @return string + */ + public function compileGetAllHashPartitionedTables(): string + { + return "select pg_class.relname as tables from pg_class inner join pg_partitioned_table on pg_class.oid = pg_partitioned_table.partrelid where pg_partitioned_table.partstrat = 'h';"; + } + + /** + * Compile a detach query for a partitioned table. + * + * @param Blueprint $blueprint + * @param Fluent $command + * + * @return string + */ + public function compileDetachPartition(Blueprint $blueprint, Fluent $command): string + { + return sprintf( + 'alter table %s detach partition %s', + str_replace("\"", "", $this->wrapTable($blueprint)), + $blueprint->partitionTableName + ); + } + + /** + * Checks if the table should have a primary key. + * + * @param Blueprint $blueprint + * + * @return bool + */ + public function shouldUsePrimaryKey(Blueprint $blueprint): bool + { + return $blueprint->pkCompositeOne && $blueprint->pkCompositeTwo; + } +} diff --git a/src/Database/Schema/Grammars/PostgresGrammar.php b/src/Database/Schema/Grammars/PostgresGrammar.php index dbaac59..3a09f34 100755 --- a/src/Database/Schema/Grammars/PostgresGrammar.php +++ b/src/Database/Schema/Grammars/PostgresGrammar.php @@ -2,245 +2,10 @@ namespace ORPTech\MigrationPartition\Database\Schema\Grammars; -use Illuminate\Support\Fluent; -use ORPTech\MigrationPartition\Database\Schema\Blueprint; +use ORPTech\MigrationPartition\Database\Concerns\CompilesPartitionQueries; use \Illuminate\Database\Schema\Grammars\PostgresGrammar as IlluminatePostgresGrammar; class PostgresGrammar extends IlluminatePostgresGrammar { - /** - * Compile a create table command with its range partitions. - * - * @param Blueprint $blueprint - * @param Fluent $command - * @return array - */ - public function compileCreateRangePartitioned(Blueprint $blueprint, Fluent $command): array - { - $columns = implode(', ', $this->getColumns($blueprint)); - - if ($primaryKey = $this->shouldUsePrimaryKey($blueprint)) { - $columns = sprintf('%s, %s', $columns, sprintf('primary key (%s, %s)', $blueprint->pkCompositeOne, $blueprint->pkCompositeTwo)); - } - - return array_values(array_filter(array_merge([sprintf('create table %s (%s) partition by range (%s)', - $this->wrapTable($blueprint), - $columns, - $blueprint->rangeKey - )], $primaryKey ? $this->compileAutoIncrementStartingValues($blueprint, $command) : []))); - } - - /** - * Compile a create table partition command for a range partitioned table. - * - * @param Blueprint $blueprint - * @param Fluent $command - * @return array - */ - public function compileCreateRangePartition(Blueprint $blueprint, Fluent $command): array - { - return array_values(array_filter(array_merge([sprintf('create table %s_%s partition of %s for values from (\'%s\') to (\'%s\')', - str_replace("\"", "", $this->wrapTable($blueprint)), - $blueprint->suffixForPartition, - str_replace("\"", "", $this->wrapTable($blueprint)), - $blueprint->startDate, - $blueprint->endDate - )], $this->shouldUsePrimaryKey($blueprint) ? $this->compileAutoIncrementStartingValues($blueprint, $command) : []))); - } - - /** - * Compile a create table command with its list partitions. - * - * @param Blueprint $blueprint - * @param Fluent $command - * @return string - */ - public function compileCreateListPartitioned(Blueprint $blueprint, Fluent $command): string - { - $columns = implode(', ', $this->getColumns($blueprint)); - - if ($this->shouldUsePrimaryKey($blueprint)) { - $columns = sprintf('%s, %s', $columns, sprintf('primary key (%s, %s)', $blueprint->pkCompositeOne, $blueprint->pkCompositeTwo)); - } - - return sprintf('create table %s (%s) partition by list(%s)', - $this->wrapTable($blueprint), - $columns, - $blueprint->listPartitionKey - ); - } - - /** - * Compile an attach partition command for a range partitioned table. - * - * @param Blueprint $blueprint - * @param Fluent $command - * @return string - */ - public function compileAttachRangePartition(Blueprint $blueprint, Fluent $command): string - { - return sprintf('ALTER table %s attach partition %s for values from (\'%s\') to (\'%s\')', - str_replace("\"", "", $this->wrapTable($blueprint)), - $blueprint->partitionTableName, - $blueprint->startDate, - $blueprint->endDate - ); - } - - /** - * Compile a create table partition command for a list partitioned table. - * - * @param Blueprint $blueprint - * @param Fluent $command - * @return string - */ - public function compileCreateListPartition(Blueprint $blueprint, Fluent $command): string - { - return sprintf('create table %s_%s partition of %s for values in (\'%s\')', - str_replace("\"", "", $this->wrapTable($blueprint)), - $blueprint->suffixForPartition, - str_replace("\"", "", $this->wrapTable($blueprint)), - $blueprint->listPartitionValue, - ); - } - - /** - * Compile an attach partition command for a list partitioned table. - * - * @param Blueprint $blueprint - * @param Fluent $command - * @return string - */ - public function compileAttachListPartition(Blueprint $blueprint, Fluent $command): string - { - return sprintf('alter table %s partition of %s for values in (\'%s\')', - str_replace("\"", "", $this->wrapTable($blueprint)), - $blueprint->partitionTableName, - $blueprint->listPartitionValue, - ); - } - - /** - * Compile a create table partition command for a hash partitioned table. - * - * @param Blueprint $blueprint - * @param Fluent $command - * @return string - */ - public function compileCreateHashPartition(Blueprint $blueprint, Fluent $command): string - { - return sprintf('create table %s_%s partition of %s for values with (modulus %s, remainder %s)', - str_replace("\"", "", $this->wrapTable($blueprint)), - $blueprint->suffixForPartition, - str_replace("\"", "", $this->wrapTable($blueprint)), - $blueprint->hashModulus, - $blueprint->hashRemainder - ); - } - - /** - * Compile a create table command with its hash partitions. - * - * @param Blueprint $blueprint - * @param Fluent $command - * @return array - */ - public function compileCreateHashPartitioned(Blueprint $blueprint, Fluent $command): array - { - $columns = implode(', ', $this->getColumns($blueprint)); - - if ($primaryKey = $this->shouldUsePrimaryKey($blueprint)) { - $columns = sprintf('%s, %s', $columns, sprintf('primary key (%s, %s)', $blueprint->pkCompositeOne, $blueprint->pkCompositeTwo)); - } - - return array_values(array_filter(array_merge([sprintf('create table %s (%s) partition by hash(%s)', - $this->wrapTable($blueprint), - $columns, - $blueprint->hashPartitionKey - )], $primaryKey ? $this->compileAutoIncrementStartingValues($blueprint, $command) : []))); - } - - /** - * Compile an attach partition command for a hash partitioned table. - * - * @param Blueprint $blueprint - * @param Fluent $command - * @return string - */ - public function compileAttachHashPartition(Blueprint $blueprint, Fluent $command): string - { - return sprintf('alter table %s partition of %s for values with (modulus %s, remainder %s)', - str_replace("\"", "", $this->wrapTable($blueprint)), - $blueprint->partitionTableName, - $blueprint->hashModulus, - $blueprint->hashRemainder, - ); - } - - /** - * Get a list of all partitioned tables in the Database. - * @param string $table - * @return string - */ - public function compileGetPartitions(string $table): string - { - return sprintf("SELECT inhrelid::regclass as tables - FROM pg_catalog.pg_inherits - WHERE inhparent = '%s'::regclass;", - $table, - ); - } - - /** - * Get all range partitioned tables. - * @return string - */ - public function compileGetAllRangePartitionedTables(): string - { - return "select pg_class.relname as tables from pg_class inner join pg_partitioned_table on pg_class.oid = pg_partitioned_table.partrelid where pg_partitioned_table.partstrat = 'r';"; - } - - /** - * Get all list partitioned tables. - * @return string - */ - public function compileGetAllListPartitionedTables(): string - { - return "select pg_class.relname as tables from pg_class inner join pg_partitioned_table on pg_class.oid = pg_partitioned_table.partrelid where pg_partitioned_table.partstrat = 'l';"; - } - - /** - * Get all hash partitioned tables. - * @return string - */ - public function compileGetAllHashPartitionedTables(): string - { - return "select pg_class.relname as tables from pg_class inner join pg_partitioned_table on pg_class.oid = pg_partitioned_table.partrelid where pg_partitioned_table.partstrat = 'h';"; - } - - /** - * Compile a detach query for a partitioned table. - * - * @param Blueprint $blueprint - * @param Fluent $command - * @return string - */ - public function compileDetachPartition(Blueprint $blueprint, Fluent $command): string - { - return sprintf('alter table %s detach partition %s', - str_replace("\"", "", $this->wrapTable($blueprint)), - $blueprint->partitionTableName - ); - } - - /** - * Checks if the table should have a primary key. - * - * @param Blueprint $blueprint - * @return bool - */ - public function shouldUsePrimaryKey(Blueprint $blueprint): bool - { - return $blueprint->pkCompositeOne && $blueprint->pkCompositeTwo; - } + use CompilesPartitionQueries; }