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

DatabaseManager WIP

This commit is contained in:
Samuel Štancl 2019-09-05 19:26:29 +02:00
parent 798df54d76
commit 41d8bb7e09
8 changed files with 125 additions and 78 deletions

View file

@ -57,6 +57,5 @@ return [
],
'queue_database_creation' => false,
'queue_database_deletion' => false,
'database_name_key' => null,
'unique_id_generator' => 'Stancl\Tenancy\UUIDGenerator',
];

View file

@ -54,7 +54,7 @@ class Migrate extends MigrateCommand
// See Illuminate\Database\Migrations\DatabaseMigrationRepository::getConnection.
// Database connections are cached by Illuminate\Database\ConnectionResolver.
$connectionName = "tenant{$tenant['uuid']}";
$connectionName = "tenant{$tenant['uuid']}"; // todo use Illuminate DatabaseManager reconnect()?
$this->input->setOption('database', $connectionName);
$this->database->connectToTenant($tenant, $connectionName);

51
src/DatabaseManagerv2.php Normal file
View file

@ -0,0 +1,51 @@
<?php
namespace Stancl\Tenancy;
use Illuminate\Database\DatabaseManager as BaseDatabaseManager;
class DatabaseManagerv2
{
/** @var BaseDatabaseManager */
protected $database;
public function __construct(BaseDatabaseManager $database)
{
$this->database = $database;
}
public function connect(Tenant $tenant)
{
$connection = $tenant->getConnectionName(); // todo
$this->createTenantConnection($tenant->getDatabaseName(), $connection);
$this->switchConnection($connection);
}
public function reconnect()
{
$this->switchConnection($this->originalDefaultConnection);
}
public function createTenantConnection(string $databaseName, string $connectionName = null)
{
$connectionName = $connectionName ?: $this->defaultTenantConnectionName;
// Create the database connection.
$based_on = config('tenancy.database.based_on') ?: config('database.default');
config()->set([
"database.connections.$connectionName" => config('database.connections.' . $based_on),
]);
// Change DB name
$databaseName = $this->getDriver($connectionName) === 'sqlite' ? database_path($databaseName) : $databaseName;
config()->set(["database.connections.$connectionName.database" => $databaseName]);
}
public function switchConnection($connection)
{
$this->database->purge();
$this->database->reconnect($connection);
$this->database->setDefaultConnection($connection);
}
}

View file

@ -1,29 +0,0 @@
<?php
declare(strict_types=1);
namespace Stancl\Tenancy\Interfaces;
interface StorageDriver
{
public function identifyTenant(string $domain): array;
/** @return array[] */
public function getAllTenants(array $uuids = []): array;
public function getTenantById(string $uuid, array $fields = []): array;
public function getTenantIdByDomain(string $domain): ?string;
public function createTenant(string $domain, string $uuid): array;
public function deleteTenant(string $uuid): bool;
public function get(string $uuid, string $key);
public function getMany(string $uuid, array $keys): array;
public function put(string $uuid, string $key, $value);
public function putMany(string $uuid, array $values): array;
}

View file

@ -1,24 +0,0 @@
<?php
declare(strict_types=1);
namespace Stancl\Tenancy\Interfaces;
interface TenantDatabaseManager
{
/**
* Create a database.
*
* @param string $name Name of the database.
* @return bool
*/
public function createDatabase(string $name): bool;
/**
* Delete a database.
*
* @param string $name Name of the database.
* @return bool
*/
public function deleteDatabase(string $name): bool;
}

View file

@ -1,17 +0,0 @@
<?php
declare(strict_types=1);
namespace Stancl\Tenancy\Interfaces;
interface UniqueIdentifierGenerator
{
/**
* Generate a unique identifier.
*
* @param string $domain
* @param array $data
* @return string
*/
public static function handle(string $domain, array $data = []): string;
}

View file

@ -4,14 +4,16 @@ declare(strict_types=1);
namespace Stancl\Tenancy;
use ArrayAccess;
// todo laravel events instead of custom events?
/**
* @final Class is subject to breaking changes in minor and patch versions.
* @internal Class is subject to breaking changes in minor and patch versions.
*/
final class Tenant // todo implement an interface to allow for current tenant dependency injection
class Tenant implements ArrayAccess
{
// todo specify id in data
use Traits\HasArrayAccess;
/**
* Tenant data.
@ -77,17 +79,24 @@ final class Tenant // todo implement an interface to allow for current tenant de
return $this;
}
public function save()
public function save(): self
{
if ($this->persisted) {
$this->manager->addTenant($this);
} else {
$this->manager->updateTenant($this);
}
return $this;
}
public function getDatabaseName()
{
return $this['_tenancy_database'] ?? $this->app['config']['tenancy.database.prefix'] . $this->uuid . $this->app['config']['tenancy.database.suffix'];
}
public function __get($name)
{
return $this->data[$name];
return $this->data[$name] ?? null;
}
}

View file

@ -4,8 +4,32 @@ declare(strict_types=1);
namespace Stancl\Tenancy;
final class TenantManager
use Illuminate\Foundation\Application;
/**
* @internal Class is subject to breaking changes in minor and patch versions.
*/
class TenantManagerv2
{
/**
* The current tenant.
*
* @var Tenant
*/
public $tenant;
/** @var Application */
private $app;
/** @var Contracts\StorageDriver */
private $storage;
public function __construct(Application $app, Contracts\StorageDriver $storage)
{
$this->app = $app;
$this->storage = $storage;
}
public function addTenant(Tenant $tenant): self
{
$this->storage->addTenant($tenant);
@ -19,4 +43,38 @@ final class TenantManager
return $this;
}
public function initializeTenancy(Tenant $tenant): self
{
$this->bootstrapTenancy($tenant);
$this->setTenant($tenant);
return $this;
}
public function bootstrapTenancy(Tenant $tenant): self
{
foreach($this->tenancyBootstrappers() as $bootstrapper) {
$bootstrapper::start($tenant);
}
return $this;
}
public function setTenant(Tenant $tenant): self
{
$this->app->instance(Tenant::class, $tenant);
return $this;
}
/**
* Return a list of TenancyBoostrappers.
*
* @return Contracts\TenancyBootstrapper[]
*/
public function tenancyBootstrappers(): array
{
return config('tenancy.bootstrappers');
}
}