1
0
Fork 0
mirror of https://github.com/archtechx/tenancy.git synced 2025-12-12 21:54:03 +00:00

general refactor, move more classes under Database namespace

This commit is contained in:
Samuel Štancl 2022-08-27 03:17:16 +02:00
parent 2d7e9dfd89
commit 40bf28c7d0
41 changed files with 122 additions and 133 deletions

View file

@ -0,0 +1,58 @@
<?php
declare(strict_types=1);
// todo likely move all of these classes to Database\
namespace Stancl\Tenancy\Database\TenantDatabaseManagers;
use Illuminate\Database\Connection;
use Illuminate\Support\Facades\DB;
use Stancl\Tenancy\Database\Contracts\TenantDatabaseManager;
use Stancl\Tenancy\Database\Contracts\TenantWithDatabase;
use Stancl\Tenancy\Database\Exceptions\NoConnectionSetException;
class MicrosoftSQLDatabaseManager implements TenantDatabaseManager
{
protected string $connection; // todo docblock, in all of these classes
protected function database(): Connection // todo consider abstracting this method & setConnection() into a base class
{
if ($this->connection === null) {
throw new NoConnectionSetException(static::class);
}
return DB::connection($this->connection);
}
public function setConnection(string $connection): void
{
$this->connection = $connection;
}
public function createDatabase(TenantWithDatabase $tenant): bool
{
$database = $tenant->database()->getName();
$charset = $this->database()->getConfig('charset');
$collation = $this->database()->getConfig('collation'); // todo check why these are not used
return $this->database()->statement("CREATE DATABASE [{$database}]");
}
public function deleteDatabase(TenantWithDatabase $tenant): bool
{
return $this->database()->statement("DROP DATABASE [{$tenant->database()->getName()}]");
}
public function databaseExists(string $name): bool
{
return (bool) $this->database()->select("SELECT name FROM master.sys.databases WHERE name = '$name'");
}
public function makeConnectionConfig(array $baseConfig, string $databaseName): array
{
$baseConfig['database'] = $databaseName;
return $baseConfig;
}
}

View file

@ -0,0 +1,57 @@
<?php
declare(strict_types=1);
namespace Stancl\Tenancy\Database\TenantDatabaseManagers;
use Illuminate\Database\Connection;
use Illuminate\Support\Facades\DB;
use Stancl\Tenancy\Database\Contracts\TenantDatabaseManager;
use Stancl\Tenancy\Database\Contracts\TenantWithDatabase;
use Stancl\Tenancy\Database\Exceptions\NoConnectionSetException;
class MySQLDatabaseManager implements TenantDatabaseManager
{
/** @var string */
protected $connection;
protected function database(): Connection
{
if ($this->connection === null) {
throw new NoConnectionSetException(static::class);
}
return DB::connection($this->connection);
}
public function setConnection(string $connection): void
{
$this->connection = $connection;
}
public function createDatabase(TenantWithDatabase $tenant): bool
{
$database = $tenant->database()->getName();
$charset = $this->database()->getConfig('charset');
$collation = $this->database()->getConfig('collation');
return $this->database()->statement("CREATE DATABASE `{$database}` CHARACTER SET `$charset` COLLATE `$collation`");
}
public function deleteDatabase(TenantWithDatabase $tenant): bool
{
return $this->database()->statement("DROP DATABASE `{$tenant->database()->getName()}`");
}
public function databaseExists(string $name): bool
{
return (bool) $this->database()->select("SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = '$name'");
}
public function makeConnectionConfig(array $baseConfig, string $databaseName): array
{
$baseConfig['database'] = $databaseName;
return $baseConfig;
}
}

View file

@ -0,0 +1,64 @@
<?php
declare(strict_types=1);
namespace Stancl\Tenancy\Database\TenantDatabaseManagers;
use Stancl\Tenancy\Database\Concerns\CreatesDatabaseUsers;
use Stancl\Tenancy\Database\Contracts\ManagesDatabaseUsers;
use Stancl\Tenancy\Database\DatabaseConfig;
class PermissionControlledMySQLDatabaseManager extends MySQLDatabaseManager implements ManagesDatabaseUsers
{
use CreatesDatabaseUsers;
public static $grants = [
'ALTER', 'ALTER ROUTINE', 'CREATE', 'CREATE ROUTINE', 'CREATE TEMPORARY TABLES', 'CREATE VIEW',
'DELETE', 'DROP', 'EVENT', 'EXECUTE', 'INDEX', 'INSERT', 'LOCK TABLES', 'REFERENCES', 'SELECT',
'SHOW VIEW', 'TRIGGER', 'UPDATE',
];
public function createUser(DatabaseConfig $databaseConfig): bool
{
$database = $databaseConfig->getName();
$username = $databaseConfig->getUsername();
$hostname = $databaseConfig->connection()['host'];
$password = $databaseConfig->getPassword();
$this->database()->statement("CREATE USER `{$username}`@`%` IDENTIFIED BY '{$password}'");
$grants = implode(', ', static::$grants);
if ($this->isVersion8()) { // MySQL 8+
$grantQuery = "GRANT $grants ON `$database`.* TO `$username`@`%`";
} else { // MySQL 5.7
$grantQuery = "GRANT $grants ON `$database`.* TO `$username`@`%` IDENTIFIED BY '$password'";
}
return $this->database()->statement($grantQuery);
}
protected function isVersion8(): bool
{
$version = $this->database()->select($this->database()->raw('select version()'))[0]->{'version()'};
return version_compare($version, '8.0.0') >= 0;
}
public function deleteUser(DatabaseConfig $databaseConfig): bool
{
return $this->database()->statement("DROP USER IF EXISTS '{$databaseConfig->getUsername()}'");
}
public function userExists(string $username): bool
{
return (bool) $this->database()->select("SELECT count(*) FROM mysql.user WHERE user = '$username'")[0]->{'count(*)'};
}
public function makeConnectionConfig(array $baseConfig, string $databaseName): array
{
$baseConfig['database'] = $databaseName;
return $baseConfig;
}
}

View file

@ -0,0 +1,53 @@
<?php
declare(strict_types=1);
namespace Stancl\Tenancy\Database\TenantDatabaseManagers;
use Illuminate\Database\Connection;
use Illuminate\Support\Facades\DB;
use Stancl\Tenancy\Database\Contracts\TenantDatabaseManager;
use Stancl\Tenancy\Database\Contracts\TenantWithDatabase;
use Stancl\Tenancy\Database\Exceptions\NoConnectionSetException;
class PostgreSQLDatabaseManager implements TenantDatabaseManager
{
/** @var string */
protected $connection;
protected function database(): Connection
{
if ($this->connection === null) {
throw new NoConnectionSetException(static::class);
}
return DB::connection($this->connection);
}
public function setConnection(string $connection): void
{
$this->connection = $connection;
}
public function createDatabase(TenantWithDatabase $tenant): bool
{
return $this->database()->statement("CREATE DATABASE \"{$tenant->database()->getName()}\" WITH TEMPLATE=template0");
}
public function deleteDatabase(TenantWithDatabase $tenant): bool
{
return $this->database()->statement("DROP DATABASE \"{$tenant->database()->getName()}\"");
}
public function databaseExists(string $name): bool
{
return (bool) $this->database()->select("SELECT datname FROM pg_database WHERE datname = '$name'");
}
public function makeConnectionConfig(array $baseConfig, string $databaseName): array
{
$baseConfig['database'] = $databaseName;
return $baseConfig;
}
}

View file

@ -0,0 +1,57 @@
<?php
declare(strict_types=1);
namespace Stancl\Tenancy\Database\TenantDatabaseManagers;
use Illuminate\Database\Connection;
use Illuminate\Support\Facades\DB;
use Stancl\Tenancy\Database\Contracts\TenantDatabaseManager;
use Stancl\Tenancy\Database\Contracts\TenantWithDatabase;
use Stancl\Tenancy\Database\Exceptions\NoConnectionSetException;
class PostgreSQLSchemaManager implements TenantDatabaseManager
{
/** @var string */
protected $connection;
protected function database(): Connection
{
if ($this->connection === null) {
throw new NoConnectionSetException(static::class);
}
return DB::connection($this->connection);
}
public function setConnection(string $connection): void
{
$this->connection = $connection;
}
public function createDatabase(TenantWithDatabase $tenant): bool
{
return $this->database()->statement("CREATE SCHEMA \"{$tenant->database()->getName()}\"");
}
public function deleteDatabase(TenantWithDatabase $tenant): bool
{
return $this->database()->statement("DROP SCHEMA \"{$tenant->database()->getName()}\" CASCADE");
}
public function databaseExists(string $name): bool
{
return (bool) $this->database()->select("SELECT schema_name FROM information_schema.schemata WHERE schema_name = '$name'");
}
public function makeConnectionConfig(array $baseConfig, string $databaseName): array
{
if (version_compare(app()->version(), '9.0', '>=')) {
$baseConfig['search_path'] = $databaseName;
} else {
$baseConfig['schema'] = $databaseName;
}
return $baseConfig;
}
}

View file

@ -0,0 +1,46 @@
<?php
declare(strict_types=1);
namespace Stancl\Tenancy\Database\TenantDatabaseManagers;
use Stancl\Tenancy\Database\Contracts\TenantDatabaseManager;
use Stancl\Tenancy\Database\Contracts\TenantWithDatabase;
class SQLiteDatabaseManager implements TenantDatabaseManager
{
public function createDatabase(TenantWithDatabase $tenant): bool
{
try {
return file_put_contents(database_path($tenant->database()->getName()), '');
} catch (\Throwable) {
return false;
}
}
public function deleteDatabase(TenantWithDatabase $tenant): bool
{
try {
return unlink(database_path($tenant->database()->getName()));
} catch (\Throwable) {
return false;
}
}
public function databaseExists(string $name): bool
{
return file_exists(database_path($name));
}
public function makeConnectionConfig(array $baseConfig, string $databaseName): array
{
$baseConfig['database'] = database_path($databaseName);
return $baseConfig;
}
public function setConnection(string $connection): void
{
//
}
}