mirror of
https://github.com/archtechx/tenancy.git
synced 2026-02-04 07:14:02 +00:00
fix: Refactor database management methods to use parameterized queries and add identifier quoting
This commit is contained in:
parent
8bdacf566b
commit
712d7aabec
3 changed files with 41 additions and 9 deletions
|
|
@ -17,18 +17,28 @@ trait ManagesRLSPolicies
|
||||||
{
|
{
|
||||||
return array_map(
|
return array_map(
|
||||||
fn (stdClass $policy) => $policy->policyname,
|
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
|
public static function dropRLSPolicies(string $table): int
|
||||||
{
|
{
|
||||||
$policies = static::getRLSPolicies($table);
|
$policies = static::getRLSPolicies($table);
|
||||||
|
$quotedTable = static::quoteIdentifier($table);
|
||||||
|
|
||||||
foreach ($policies as $policy) {
|
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);
|
return count($policies);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected static function quoteIdentifier(string $identifier): string
|
||||||
|
{
|
||||||
|
return '"' . str_replace('"', '""', $identifier) . '"';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,20 +10,30 @@ class MySQLDatabaseManager extends TenantDatabaseManager
|
||||||
{
|
{
|
||||||
public function createDatabase(TenantWithDatabase $tenant): bool
|
public function createDatabase(TenantWithDatabase $tenant): bool
|
||||||
{
|
{
|
||||||
$database = $tenant->database()->getName();
|
$database = $this->quoteIdentifier($tenant->database()->getName());
|
||||||
$charset = $this->connection()->getConfig('charset');
|
$charset = $this->connection()->getConfig('charset');
|
||||||
$collation = $this->connection()->getConfig('collation');
|
$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
|
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
|
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) . '`';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,16 +10,28 @@ class PostgreSQLDatabaseManager extends TenantDatabaseManager
|
||||||
{
|
{
|
||||||
public function createDatabase(TenantWithDatabase $tenant): bool
|
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
|
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
|
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) . '"';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue