1
0
Fork 0
mirror of https://github.com/archtechx/tenancy.git synced 2026-02-04 09:04:03 +00:00

fix: Refactor database management methods to use parameterized queries and add identifier quoting

This commit is contained in:
Hayatunnabi Nabil 2025-11-07 15:41:38 +06:00
parent 8bdacf566b
commit 712d7aabec
3 changed files with 41 additions and 9 deletions

View file

@ -17,18 +17,28 @@ trait ManagesRLSPolicies
{
return array_map(
fn (stdClass $policy) => $policy->policyname,
DB::select("SELECT policyname FROM pg_policies WHERE tablename = '{$table}' AND policyname LIKE '%_rls_policy%'")
DB::select(
"SELECT policyname FROM pg_policies WHERE tablename = ? AND policyname LIKE ?",
[$table, '%_rls_policy%']
)
);
}
public static function dropRLSPolicies(string $table): int
{
$policies = static::getRLSPolicies($table);
$quotedTable = static::quoteIdentifier($table);
foreach ($policies as $policy) {
DB::statement('DROP POLICY ? ON ?', [$policy, $table]);
$quotedPolicy = static::quoteIdentifier($policy);
DB::statement("DROP POLICY {$quotedPolicy} ON {$quotedTable}");
}
return count($policies);
}
protected static function quoteIdentifier(string $identifier): string
{
return '"' . str_replace('"', '""', $identifier) . '"';
}
}

View file

@ -10,20 +10,30 @@ class MySQLDatabaseManager extends TenantDatabaseManager
{
public function createDatabase(TenantWithDatabase $tenant): bool
{
$database = $tenant->database()->getName();
$database = $this->quoteIdentifier($tenant->database()->getName());
$charset = $this->connection()->getConfig('charset');
$collation = $this->connection()->getConfig('collation');
return $this->connection()->statement("CREATE DATABASE `{$database}` CHARACTER SET `$charset` COLLATE `$collation`");
return $this->connection()->statement("CREATE DATABASE {$database} CHARACTER SET `$charset` COLLATE `$collation`");
}
public function deleteDatabase(TenantWithDatabase $tenant): bool
{
return $this->connection()->statement("DROP DATABASE `{$tenant->database()->getName()}`");
$database = $this->quoteIdentifier($tenant->database()->getName());
return $this->connection()->statement("DROP DATABASE {$database}");
}
public function databaseExists(string $name): bool
{
return (bool) $this->connection()->select("SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = '$name'");
return (bool) $this->connection()->selectOne(
'SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = ? LIMIT 1',
[$name]
);
}
protected function quoteIdentifier(string $identifier): string
{
return '`' . str_replace('`', '``', $identifier) . '`';
}
}

View file

@ -10,16 +10,28 @@ class PostgreSQLDatabaseManager extends TenantDatabaseManager
{
public function createDatabase(TenantWithDatabase $tenant): bool
{
return $this->connection()->statement("CREATE DATABASE \"{$tenant->database()->getName()}\" WITH TEMPLATE=template0");
$database = $this->quoteIdentifier($tenant->database()->getName());
return $this->connection()->statement("CREATE DATABASE {$database} WITH TEMPLATE=template0");
}
public function deleteDatabase(TenantWithDatabase $tenant): bool
{
return $this->connection()->statement("DROP DATABASE \"{$tenant->database()->getName()}\"");
$database = $this->quoteIdentifier($tenant->database()->getName());
return $this->connection()->statement("DROP DATABASE {$database}");
}
public function databaseExists(string $name): bool
{
return (bool) $this->connection()->selectOne("SELECT datname FROM pg_database WHERE datname = '$name'");
return (bool) $this->connection()->selectOne(
'SELECT datname FROM pg_database WHERE datname = ? LIMIT 1',
[$name]
);
}
protected function quoteIdentifier(string $identifier): string
{
return '"' . str_replace('"', '""', $identifier) . '"';
}
}