1
0
Fork 0
mirror of https://github.com/archtechx/tenancy.git synced 2025-12-13 01:44:04 +00:00

Atomic tenant creation

This commit is contained in:
Samuel Štancl 2019-09-08 15:05:04 +02:00
parent b0d119753d
commit 37567336a5
4 changed files with 68 additions and 3 deletions

View file

@ -29,4 +29,12 @@ interface StorageDriver
* @return Tenant * @return Tenant
*/ */
public function findByDomain(string $domain): Tenant; public function findByDomain(string $domain): Tenant;
/**
* Check if a tenant can be created.
*
* @param Tenant $tenant
* @return true|TenantCannotBeCreatedException
*/
public function canCreate(Tenant $tenant);
} }

View file

@ -0,0 +1,15 @@
<?php
namespace Stancl\Tenancy\Contracts;
abstract class TenantCannotBeCreatedException extends \Exception
{
abstract function reason(): string;
private $message;
public function __construct()
{
$this->message = 'Tenant cannot be craeted. Reason: ' . $this->reason();
}
}

View file

@ -57,4 +57,15 @@ class DatabaseManagerv2
$this->database->reconnect($connection); $this->database->reconnect($connection);
$this->database->setDefaultConnection($connection); $this->database->setDefaultConnection($connection);
} }
/**
* Check if a tenant can be created.
*
* @param Tenant $tenant
* @return true|TenantCannotBeCreatedException
*/
public function canCreate(Tenant $tenant)
{
// todo
}
} }

View file

@ -5,6 +5,8 @@ declare(strict_types=1);
namespace Stancl\Tenancy; namespace Stancl\Tenancy;
use Illuminate\Foundation\Application; use Illuminate\Foundation\Application;
use Illuminate\Contracts\Console\Kernel as Artisan;
use Stancl\Tenancy\Contracts\TenantCannotBeCreatedException;
use Stancl\Tenancy\Exceptions\NoTenantIdentifiedException; use Stancl\Tenancy\Exceptions\NoTenantIdentifiedException;
use Stancl\Tenancy\Exceptions\TenantCouldNotBeIdentifiedException; use Stancl\Tenancy\Exceptions\TenantCouldNotBeIdentifiedException;
@ -30,7 +32,7 @@ class TenantManagerv2
/** @var callable[][] */ /** @var callable[][] */
protected $callbacks = []; protected $callbacks = [];
public function __construct(Application $app, Contracts\StorageDriver $storage) public function __construct(Application $app, Contracts\StorageDriver $storage, Artisan $artisan)
{ {
$this->app = $app; $this->app = $app;
$this->storage = $storage; $this->storage = $storage;
@ -40,14 +42,38 @@ class TenantManagerv2
public function createTenant(Tenant $tenant): self public function createTenant(Tenant $tenant): self
{ {
// todo make this atomic $this->ensureTenantCanBeCreated($tenant);
$this->storage->createTenant($tenant); $this->storage->createTenant($tenant);
$this->database->create($tenant); $this->database->create($tenant);
// todo create database, optionally migrate
if ($this->migrateAfterCreation()) {
$this->artisan->call('tenants:migrate', [
'--tenants' => [$tenant['id']],
]);
}
return $this; return $this;
} }
/**
* Ensure that a tenant can be created.
*
* @param Tenant $tenant
* @return void
* @throws TenantCannotBeCreatedException
*/
public function ensureTenantCanBeCreated(Tenant $tenant): void
{
if (($e = $this->storage->canCreateTenant($tenant)) instanceof TenantCannotBeCreatedException) {
throw new $e;
}
if (($e = $this->database->canCreateTenant($tenant)) instanceof TenantCannotBeCreatedException) {
throw new $e;
}
}
public function updateTenant(Tenant $tenant): self public function updateTenant(Tenant $tenant): self
{ {
$this->storage->updateTenant($tenant); $this->storage->updateTenant($tenant);
@ -169,6 +195,11 @@ class TenantManagerv2
return array_key_diff($this->app['config']['tenancy.bootstrappers'], $except); return array_key_diff($this->app['config']['tenancy.bootstrappers'], $except);
} }
public function migrateAfterCreation(): bool
{
return $this->app['config']['tenancy.migrate_after_creation'] ?? false;
}
/** /**
* Add an event callback. * Add an event callback.
* *