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

Add PostgreSQL DB driver (#52)

This commit is contained in:
Samuel Štancl 2019-07-12 23:09:29 +02:00 committed by GitHub
parent f2819adcd2
commit b2e2460c34
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 87 additions and 8 deletions

View file

@ -26,7 +26,7 @@ services:
environment: environment:
MYSQL_ROOT_PASSWORD: password MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: main MYSQL_DATABASE: main
MYSQL_USER: user MYSQL_USER: user # redundant
MYSQL_PASSWORD: password MYSQL_PASSWORD: password
networks: networks:
- testnet - testnet
@ -34,8 +34,10 @@ services:
image: postgres:11 image: postgres:11
environment: environment:
POSTGRES_PASSWORD: password POSTGRES_PASSWORD: password
POSTGRES_USER: user POSTGRES_USER: root # superuser name
POSTGRES_DB: main POSTGRES_DB: main
networks:
- testnet
redis: redis:
image: redis:alpine image: redis:alpine
networks: networks:

View file

@ -36,6 +36,14 @@ class DatabaseManager
$this->database->setDefaultConnection($default_connection); $this->database->setDefaultConnection($default_connection);
} }
/**
* Create a database.
* @todo Should this handle prefixes?
*
* @param string $name
* @param string $driver
* @return bool
*/
public function create(string $name, string $driver = null) public function create(string $name, string $driver = null)
{ {
$this->createTenantConnection($name); $this->createTenantConnection($name);
@ -50,10 +58,18 @@ class DatabaseManager
if (config('tenancy.queue_database_creation', false)) { if (config('tenancy.queue_database_creation', false)) {
QueuedTenantDatabaseCreator::dispatch(app($databaseManagers[$driver]), $name, 'create'); QueuedTenantDatabaseCreator::dispatch(app($databaseManagers[$driver]), $name, 'create');
} else { } else {
app($databaseManagers[$driver])->createDatabase($name); return app($databaseManagers[$driver])->createDatabase($name);
} }
} }
/**
* Delete a database.
* @todo Should this handle prefixes?
*
* @param string $name
* @param string $driver
* @return bool
*/
public function delete(string $name, string $driver = null) public function delete(string $name, string $driver = null)
{ {
$this->createTenantConnection($name); $this->createTenantConnection($name);
@ -68,7 +84,7 @@ class DatabaseManager
if (config('tenancy.queue_database_deletion', false)) { if (config('tenancy.queue_database_deletion', false)) {
QueuedTenantDatabaseDeleter::dispatch(app($databaseManagers[$driver]), $name, 'delete'); QueuedTenantDatabaseDeleter::dispatch(app($databaseManagers[$driver]), $name, 'delete');
} else { } else {
app($databaseManagers[$driver])->deleteDatabase($name); return app($databaseManagers[$driver])->deleteDatabase($name);
} }
} }

View file

@ -0,0 +1,19 @@
<?php
namespace Stancl\Tenancy\TenantDatabaseManagers;
use Illuminate\Support\Facades\DB;
use Stancl\Tenancy\Interfaces\TenantDatabaseManager;
class PostgreSQLDatabaseManager implements TenantDatabaseManager
{
public function createDatabase(string $name): bool
{
return DB::statement("CREATE DATABASE $name WITH TEMPLATE=template0");
}
public function deleteDatabase(string $name): bool
{
return DB::statement("DROP DATABASE $name");
}
}

View file

@ -39,6 +39,7 @@ return [
'database_managers' => [ 'database_managers' => [
'sqlite' => 'Stancl\Tenancy\TenantDatabaseManagers\SQLiteDatabaseManager', 'sqlite' => 'Stancl\Tenancy\TenantDatabaseManagers\SQLiteDatabaseManager',
'mysql' => 'Stancl\Tenancy\TenantDatabaseManagers\MySQLDatabaseManager', 'mysql' => 'Stancl\Tenancy\TenantDatabaseManagers\MySQLDatabaseManager',
'pgsql' => 'Stancl\Tenancy\TenantDatabaseManagers\PostgreSQLDatabaseManager',
], ],
'queue_database_creation' => false, 'queue_database_creation' => false,
'queue_database_deletion' => false, 'queue_database_deletion' => false,

View file

@ -14,10 +14,10 @@ class TenantDatabaseManagerTest extends TestCase
public function sqlite_database_can_be_created_and_deleted() public function sqlite_database_can_be_created_and_deleted()
{ {
$db_name = 'testdatabase' . $this->randomString(10) . '.sqlite'; $db_name = 'testdatabase' . $this->randomString(10) . '.sqlite';
app(DatabaseManager::class)->create($db_name, 'sqlite'); $this->assertTrue(app(DatabaseManager::class)->create($db_name, 'sqlite'));
$this->assertFileExists(database_path($db_name)); $this->assertFileExists(database_path($db_name));
app(DatabaseManager::class)->delete($db_name, 'sqlite'); $this->assertTrue(app(DatabaseManager::class)->delete($db_name, 'sqlite'));
$this->assertFileNotExists(database_path($db_name)); $this->assertFileNotExists(database_path($db_name));
} }
@ -47,10 +47,10 @@ class TenantDatabaseManagerTest extends TestCase
config()->set('database.default', 'mysql'); config()->set('database.default', 'mysql');
$db_name = 'testdatabase' . $this->randomString(10); $db_name = 'testdatabase' . $this->randomString(10);
app(DatabaseManager::class)->create($db_name, 'mysql'); $this->assertTrue(app(DatabaseManager::class)->create($db_name, 'mysql'));
$this->assertNotEmpty(DB::select("SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = '$db_name'")); $this->assertNotEmpty(DB::select("SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = '$db_name'"));
app(DatabaseManager::class)->delete($db_name, 'mysql'); $this->assertTrue(app(DatabaseManager::class)->delete($db_name, 'mysql'));
$this->assertEmpty(DB::select("SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = '$db_name'")); $this->assertEmpty(DB::select("SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = '$db_name'"));
} }
@ -78,6 +78,47 @@ class TenantDatabaseManagerTest extends TestCase
$this->assertEmpty(DB::select("SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = '$db_name'")); $this->assertEmpty(DB::select("SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = '$db_name'"));
} }
/** @test */
public function pgsql_database_can_be_created_and_deleted()
{
if (! $this->isContainerized()) {
$this->markTestSkipped('As to not bloat your PostgreSQL instance with test databases, this test is not run by default.');
}
config()->set('database.default', 'pgsql');
$db_name = strtolower('testdatabase' . $this->randomString(10));
$this->assertTrue(app(DatabaseManager::class)->create($db_name, 'pgsql'));
$this->assertNotEmpty(DB::select("SELECT datname FROM pg_database WHERE datname = '$db_name'"));
$this->assertTrue(app(DatabaseManager::class)->delete($db_name, 'pgsql'));
$this->assertEmpty(DB::select("SELECT datname FROM pg_database WHERE datname = '$db_name'"));
}
/** @test */
public function pgsql_database_can_be_created_and_deleted_using_queued_commands()
{
if (! $this->isContainerized()) {
$this->markTestSkipped('As to not bloat your PostgreSQL instance with test databases, this test is not run by default.');
}
config()->set('database.default', 'pgsql');
$db_name = strtolower('testdatabase' . $this->randomString(10));
$databaseManagers = config('tenancy.database_managers');
$job = new QueuedTenantDatabaseCreator(app($databaseManagers['pgsql']), $db_name);
$job->handle();
$this->assertNotEmpty(DB::select("SELECT datname FROM pg_database WHERE datname = '$db_name'"));
$databaseManagers = config('tenancy.database_managers');
$job = new QueuedTenantDatabaseDeleter(app($databaseManagers['pgsql']), $db_name);
$job->handle();
$this->assertEmpty(DB::select("SELECT datname FROM pg_database WHERE datname = '$db_name'"));
}
/** @test */ /** @test */
public function database_creation_can_be_queued() public function database_creation_can_be_queued()
{ {