mirror of
https://github.com/archtechx/tenancy.git
synced 2025-12-12 17:24:03 +00:00
DatabaseManager WIP
This commit is contained in:
parent
798df54d76
commit
41d8bb7e09
8 changed files with 125 additions and 78 deletions
|
|
@ -57,6 +57,5 @@ return [
|
|||
],
|
||||
'queue_database_creation' => false,
|
||||
'queue_database_deletion' => false,
|
||||
'database_name_key' => null,
|
||||
'unique_id_generator' => 'Stancl\Tenancy\UUIDGenerator',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -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
51
src/DatabaseManagerv2.php
Normal 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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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');
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue