mirror of
https://github.com/archtechx/tenancy.git
synced 2025-12-12 19:14:04 +00:00
Tenant-specific connections, some work to get tests running
This commit is contained in:
parent
e25a01a997
commit
c65b6839ff
13 changed files with 162 additions and 67 deletions
|
|
@ -3,9 +3,9 @@
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'storage_driver' => 'Stancl\Tenancy\StorageDrivers\DatabaseStorageDriver',
|
'storage_driver' => 'Stancl\Tenancy\StorageDrivers\Database\DatabaseStorageDriver',
|
||||||
'storage' => [
|
'storage' => [
|
||||||
'db' => [ // Stancl\Tenancy\StorageDrivers\DatabaseStorageDriver
|
'db' => [ // Stancl\Tenancy\StorageDrivers\Database\DatabaseStorageDriver
|
||||||
'data_column' => 'data',
|
'data_column' => 'data',
|
||||||
'custom_columns' => [
|
'custom_columns' => [
|
||||||
// 'plan',
|
// 'plan',
|
||||||
|
|
@ -60,6 +60,7 @@ return [
|
||||||
'cache' => 'Stancl\Tenancy\TenancyBootstrappers\CacheTenancyBootstrapper',
|
'cache' => 'Stancl\Tenancy\TenancyBootstrappers\CacheTenancyBootstrapper',
|
||||||
'filesystem' => 'Stancl\Tenancy\TenancyBootstrappers\FilesystemTenancyBootstrapper',
|
'filesystem' => 'Stancl\Tenancy\TenancyBootstrappers\FilesystemTenancyBootstrapper',
|
||||||
'redis' => 'Stancl\Tenancy\TenancyBootstrappers\RedisTenancyBootstrapper',
|
'redis' => 'Stancl\Tenancy\TenancyBootstrappers\RedisTenancyBootstrapper',
|
||||||
|
'queue' => 'Stancl\Tenancy\TenancyBoostrappers\QueueTenancyBootstrapper',
|
||||||
],
|
],
|
||||||
'features' => [
|
'features' => [
|
||||||
// Features are classes that provide additional functionality
|
// Features are classes that provide additional functionality
|
||||||
|
|
|
||||||
|
|
@ -16,10 +16,8 @@ class CreateTenantsTable extends Migration
|
||||||
public function up()
|
public function up()
|
||||||
{
|
{
|
||||||
Schema::create('tenants', function (Blueprint $table) {
|
Schema::create('tenants', function (Blueprint $table) {
|
||||||
$table->string('uuid', 36)->primary(); // don't change this
|
$table->string('id', 36)->primary(); // 36 characters is the default uuid length
|
||||||
$table->string('domain', 255)->index(); // don't change this
|
// your custom, indexed columns go here
|
||||||
|
|
||||||
// your indexed columns go here
|
|
||||||
|
|
||||||
$table->json('data');
|
$table->json('data');
|
||||||
});
|
});
|
||||||
|
|
|
||||||
33
assets/migrations/2019_09_15_000000_create_domains_table.php
Normal file
33
assets/migrations/2019_09_15_000000_create_domains_table.php
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class CreateDomainsTable extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::create('domains', function (Blueprint $table) {
|
||||||
|
$table->string('tenant_id', 36)->primary(); // 36 characters is the default uuid length
|
||||||
|
$table->string('domain', 255)->index(); // don't change this
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::drop('domains');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -48,6 +48,14 @@ interface StorageDriver
|
||||||
*/
|
*/
|
||||||
public function ensureTenantCanBeCreated(Tenant $tenant): void;
|
public function ensureTenantCanBeCreated(Tenant $tenant): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set default tenant (will be used for get/put when no tenant is supplied).
|
||||||
|
*
|
||||||
|
* @param Tenant $tenant
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
public function withDefaultTenant(Tenant $tenant);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a value from storage.
|
* Get a value from storage.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ namespace Stancl\Tenancy;
|
||||||
|
|
||||||
use Illuminate\Database\DatabaseManager as BaseDatabaseManager;
|
use Illuminate\Database\DatabaseManager as BaseDatabaseManager;
|
||||||
use Illuminate\Foundation\Application;
|
use Illuminate\Foundation\Application;
|
||||||
|
use Stancl\Tenancy\Contracts\TenantDatabaseManager;
|
||||||
use Stancl\Tenancy\Exceptions\DatabaseManagerNotRegisteredException;
|
use Stancl\Tenancy\Exceptions\DatabaseManagerNotRegisteredException;
|
||||||
use Stancl\Tenancy\Exceptions\TenantDatabaseAlreadyExistsException;
|
use Stancl\Tenancy\Exceptions\TenantDatabaseAlreadyExistsException;
|
||||||
use Stancl\Tenancy\Jobs\QueuedTenantDatabaseCreator;
|
use Stancl\Tenancy\Jobs\QueuedTenantDatabaseCreator;
|
||||||
|
|
@ -23,6 +24,7 @@ class DatabaseManager
|
||||||
|
|
||||||
public function __construct(Application $app, BaseDatabaseManager $database)
|
public function __construct(Application $app, BaseDatabaseManager $database)
|
||||||
{
|
{
|
||||||
|
$this->app = $app;
|
||||||
$this->database = $database;
|
$this->database = $database;
|
||||||
$this->originalDefaultConnectionName = $app['config']['database.default'];
|
$this->originalDefaultConnectionName = $app['config']['database.default'];
|
||||||
}
|
}
|
||||||
|
|
@ -35,9 +37,8 @@ class DatabaseManager
|
||||||
*/
|
*/
|
||||||
public function connect(Tenant $tenant)
|
public function connect(Tenant $tenant)
|
||||||
{
|
{
|
||||||
$connection = 'tenant'; // todo tenant-specific connections
|
$this->createTenantConnection($tenant);
|
||||||
$this->createTenantConnection($tenant->getDatabaseName(), $connection);
|
$this->switchConnection($tenant->getConnectionName());
|
||||||
$this->switchConnection($connection);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -53,13 +54,13 @@ class DatabaseManager
|
||||||
/**
|
/**
|
||||||
* Create the tenant database connection.
|
* Create the tenant database connection.
|
||||||
*
|
*
|
||||||
* @param string $databaseName
|
* @param Tenant $tenant
|
||||||
* @param string $connectionName
|
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function createTenantConnection(string $databaseName, string $connectionName = null)
|
public function createTenantConnection(Tenant $tenant)
|
||||||
{
|
{
|
||||||
$connectionName = $connectionName ?? 'tenant'; // todo
|
$databaseName = $tenant->getDatabaseName();
|
||||||
|
$connectionName = $tenant->getConnectionName();
|
||||||
|
|
||||||
// Create the database connection.
|
// Create the database connection.
|
||||||
$based_on = $this->app['config']['tenancy.database.based_on'] ?? $this->originalDefaultConnectionName;
|
$based_on = $this->app['config']['tenancy.database.based_on'] ?? $this->originalDefaultConnectionName;
|
||||||
|
|
@ -108,9 +109,9 @@ class DatabaseManager
|
||||||
$manager = $this->getTenantDatabaseManager($tenant);
|
$manager = $this->getTenantDatabaseManager($tenant);
|
||||||
|
|
||||||
if ($this->app['config']['tenancy.queue_database_creation'] ?? false) {
|
if ($this->app['config']['tenancy.queue_database_creation'] ?? false) {
|
||||||
QueuedTenantDatabaseCreator::dispatch($this->app[$manager], $database, 'create');
|
QueuedTenantDatabaseCreator::dispatch($manager, $database, 'create');
|
||||||
} else {
|
} else {
|
||||||
return $this->app[$manager]->createDatabase($database);
|
return $manager->createDatabase($database);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -120,16 +121,16 @@ class DatabaseManager
|
||||||
$manager = $this->getTenantDatabaseManager($tenant);
|
$manager = $this->getTenantDatabaseManager($tenant);
|
||||||
|
|
||||||
if ($this->app['config']['tenancy.queue_database_creation'] ?? false) {
|
if ($this->app['config']['tenancy.queue_database_creation'] ?? false) {
|
||||||
QueuedTenantDatabaseCreator::dispatch($this->app[$manager], $database, 'delete');
|
QueuedTenantDatabaseCreator::dispatch($manager, $database, 'delete');
|
||||||
} else {
|
} else {
|
||||||
return $this->app[$manager]->deleteDatabase($database);
|
return $manager->deleteDatabase($database);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getTenantDatabaseManager(Tenant $tenant)
|
protected function getTenantDatabaseManager(Tenant $tenant): TenantDatabaseManager
|
||||||
{
|
{
|
||||||
$connection = $tenant->getConnectionName(); // todo
|
$this->createTenantConnection($tenant);
|
||||||
$driver = $this->getDriver($connection);
|
$driver = $this->getDriver($tenant->getConnectionName());
|
||||||
|
|
||||||
$databaseManagers = $this->app['config']['tenancy.database_managers'];
|
$databaseManagers = $this->app['config']['tenancy.database_managers'];
|
||||||
|
|
||||||
|
|
@ -137,6 +138,6 @@ class DatabaseManager
|
||||||
throw new DatabaseManagerNotRegisteredException($driver);
|
throw new DatabaseManagerNotRegisteredException($driver);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $databaseManagers[$driver];
|
return $this->app[$databaseManagers[$driver]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,18 +4,31 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace Stancl\Tenancy\StorageDrivers\Database;
|
namespace Stancl\Tenancy\StorageDrivers\Database;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Application;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
use Stancl\Tenancy\Contracts\StorageDriver;
|
use Stancl\Tenancy\Contracts\StorageDriver;
|
||||||
use Stancl\Tenancy\Exceptions\DomainOccupiedByOtherTenantException;
|
use Stancl\Tenancy\Exceptions\DomainOccupiedByOtherTenantException;
|
||||||
use Stancl\Tenancy\Exceptions\TenantCouldNotBeIdentifiedException;
|
use Stancl\Tenancy\Exceptions\TenantCouldNotBeIdentifiedException;
|
||||||
use Stancl\Tenancy\Exceptions\TenantWithThisIdAlreadyExistsException;
|
use Stancl\Tenancy\Exceptions\TenantWithThisIdAlreadyExistsException;
|
||||||
use Stancl\Tenancy\StorageDrivers\Database\DomainModel as Domains;
|
use Stancl\Tenancy\StorageDrivers\Database\DomainModel as Domains;
|
||||||
use Stancl\Tenancy\StorageDrivers\Database\Tenants as Tenants;
|
use Stancl\Tenancy\StorageDrivers\Database\TenantModel as Tenants;
|
||||||
use Stancl\Tenancy\Tenant;
|
use Stancl\Tenancy\Tenant;
|
||||||
|
|
||||||
class DatabaseStorageDriver implements StorageDriver
|
class DatabaseStorageDriver implements StorageDriver
|
||||||
{
|
{
|
||||||
// todo write tests verifying that data is decoded and added to the array
|
// todo write tests verifying that data is decoded and added to the array
|
||||||
|
|
||||||
|
/** @var Application */
|
||||||
|
protected $app;
|
||||||
|
|
||||||
|
/** @var Tenant The default tenant. */
|
||||||
|
protected $tenant;
|
||||||
|
|
||||||
|
public function __construct(Application $app)
|
||||||
|
{
|
||||||
|
$this->app = $app;
|
||||||
|
}
|
||||||
|
|
||||||
public function findByDomain(string $domain): Tenant
|
public function findByDomain(string $domain): Tenant
|
||||||
{
|
{
|
||||||
$id = $this->getTenantIdByDomain($domain);
|
$id = $this->getTenantIdByDomain($domain);
|
||||||
|
|
@ -23,16 +36,16 @@ class DatabaseStorageDriver implements StorageDriver
|
||||||
throw new TenantCouldNotBeIdentifiedException($domain);
|
throw new TenantCouldNotBeIdentifiedException($domain);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->find($id);
|
return $this->findById($id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function findById(string $id): Tenant
|
public function findById(string $id): Tenant
|
||||||
{
|
{
|
||||||
return Tenant::fromStorage(Tenants::find($id)->decoded())
|
return Tenant::fromStorage(Tenants::find($id)->decoded())
|
||||||
->withDomains(Domains::where('tenant_id', $id)->all()->only('domain')->toArray());
|
->withDomains(Domains::where('tenant_id', $id)->get()->only('domain')->toArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function ensureTenantCanBeCreated(Tenant $tenant)
|
public function ensureTenantCanBeCreated(Tenant $tenant): void
|
||||||
{
|
{
|
||||||
// todo test this
|
// todo test this
|
||||||
if (Tenants::find($tenant->id)) {
|
if (Tenants::find($tenant->id)) {
|
||||||
|
|
@ -44,6 +57,13 @@ class DatabaseStorageDriver implements StorageDriver
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function withDefaultTenant(Tenant $tenant): self
|
||||||
|
{
|
||||||
|
$this->tenant = $tenant;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function getTenantIdByDomain(string $domain): ?string
|
public function getTenantIdByDomain(string $domain): ?string
|
||||||
{
|
{
|
||||||
return Domains::where('domain', $domain)->first()->tenant_id ?? null;
|
return Domains::where('domain', $domain)->first()->tenant_id ?? null;
|
||||||
|
|
@ -64,9 +84,8 @@ class DatabaseStorageDriver implements StorageDriver
|
||||||
|
|
||||||
public function updateTenant(Tenant $tenant): void
|
public function updateTenant(Tenant $tenant): void
|
||||||
{
|
{
|
||||||
// todo
|
Tenant::find($tenant->id)->putMany($tenant->data);
|
||||||
// 1. update storage
|
// todo update domains
|
||||||
// 2. update domains
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function deleteTenant(Tenant $tenant): void
|
public function deleteTenant(Tenant $tenant): void
|
||||||
|
|
@ -93,7 +112,7 @@ class DatabaseStorageDriver implements StorageDriver
|
||||||
*/
|
*/
|
||||||
protected function tenant()
|
protected function tenant()
|
||||||
{
|
{
|
||||||
return $this->app[Tenant::class];
|
return $this->tenant ?? $this->app[Tenant::class];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function get(string $key, Tenant $tenant = null)
|
public function get(string $key, Tenant $tenant = null)
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ class DomainModel extends Model
|
||||||
protected $primaryKey = 'id';
|
protected $primaryKey = 'id';
|
||||||
public $incrementing = false;
|
public $incrementing = false;
|
||||||
public $timestamps = false;
|
public $timestamps = false;
|
||||||
|
public $table = 'domains';
|
||||||
|
|
||||||
public function getConnectionName()
|
public function getConnectionName()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ class TenantModel extends Model
|
||||||
protected $primaryKey = 'id';
|
protected $primaryKey = 'id';
|
||||||
public $incrementing = false;
|
public $incrementing = false;
|
||||||
public $timestamps = false;
|
public $timestamps = false;
|
||||||
|
public $table = 'tenants';
|
||||||
|
|
||||||
public static function dataColumn()
|
public static function dataColumn()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,9 @@ class RedisStorageDriver implements StorageDriver
|
||||||
/** @var Redis */
|
/** @var Redis */
|
||||||
protected $redis;
|
protected $redis;
|
||||||
|
|
||||||
|
/** @var Tenant The default tenant. */
|
||||||
|
protected $tenant;
|
||||||
|
|
||||||
public function __construct(Application $app, Redis $redis)
|
public function __construct(Application $app, Redis $redis)
|
||||||
{
|
{
|
||||||
$this->app = $app;
|
$this->app = $app;
|
||||||
|
|
@ -34,10 +37,17 @@ class RedisStorageDriver implements StorageDriver
|
||||||
*/
|
*/
|
||||||
protected function tenant()
|
protected function tenant()
|
||||||
{
|
{
|
||||||
return $this->app[Tenant::class];
|
return $this->tenant ?? $this->app[Tenant::class];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function ensureTenantCanBeCreated(Tenant $tenant)
|
public function withDefaultTenant(Tenant $tenant): self
|
||||||
|
{
|
||||||
|
$this->tenant = $tenant;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function ensureTenantCanBeCreated(Tenant $tenant): void
|
||||||
{
|
{
|
||||||
// todo
|
// todo
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -64,14 +64,13 @@ class TenancyServiceProvider extends ServiceProvider
|
||||||
$this->app->singleton($bootstrapper);
|
$this->app->singleton($bootstrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo are these necessary?
|
$this->app->singleton(Commands\Migrate::class, function ($app) {
|
||||||
$this->app->singleton(Migrate::class, function ($app) {
|
|
||||||
return new Commands\Migrate($app['migrator'], $app[DatabaseManager::class]);
|
return new Commands\Migrate($app['migrator'], $app[DatabaseManager::class]);
|
||||||
});
|
});
|
||||||
$this->app->singleton(Rollback::class, function ($app) {
|
$this->app->singleton(Commands\Rollback::class, function ($app) {
|
||||||
return new Commands\Rollback($app['migrator'], $app[DatabaseManager::class]);
|
return new Commands\Rollback($app['migrator'], $app[DatabaseManager::class]);
|
||||||
});
|
});
|
||||||
$this->app->singleton(Seed::class, function ($app) {
|
$this->app->singleton(Commands\Seed::class, function ($app) {
|
||||||
return new Commands\Seed($app['db'], $app[DatabaseManager::class]);
|
return new Commands\Seed($app['db'], $app[DatabaseManager::class]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,13 @@ declare(strict_types=1);
|
||||||
namespace Stancl\Tenancy;
|
namespace Stancl\Tenancy;
|
||||||
|
|
||||||
use ArrayAccess;
|
use ArrayAccess;
|
||||||
|
use Illuminate\Foundation\Application;
|
||||||
use Stancl\Tenancy\Contracts\StorageDriver;
|
use Stancl\Tenancy\Contracts\StorageDriver;
|
||||||
use Stancl\Tenancy\Contracts\UniqueIdentifierGenerator;
|
use Stancl\Tenancy\Contracts\UniqueIdentifierGenerator;
|
||||||
use Stancl\Tenancy\Exceptions\TenantStorageException;
|
use Stancl\Tenancy\Exceptions\TenantStorageException;
|
||||||
|
|
||||||
|
// todo write tests for updating the tenant
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @internal Class is subject to breaking changes in minor and patch versions.
|
* @internal Class is subject to breaking changes in minor and patch versions.
|
||||||
*/
|
*/
|
||||||
|
|
@ -30,6 +33,9 @@ class Tenant implements ArrayAccess
|
||||||
*/
|
*/
|
||||||
public $domains = [];
|
public $domains = [];
|
||||||
|
|
||||||
|
/** @var Application */
|
||||||
|
protected $app;
|
||||||
|
|
||||||
/** @var StorageDriver */
|
/** @var StorageDriver */
|
||||||
protected $storage;
|
protected $storage;
|
||||||
|
|
||||||
|
|
@ -46,16 +52,24 @@ class Tenant implements ArrayAccess
|
||||||
*/
|
*/
|
||||||
protected $persisted = false;
|
protected $persisted = false;
|
||||||
|
|
||||||
public function __construct(StorageDriver $storage, TenantManager $tenantManager, UniqueIdentifierGenerator $idGenerator)
|
public function __construct(Application $app, StorageDriver $storage, TenantManager $tenantManager, UniqueIdentifierGenerator $idGenerator)
|
||||||
{
|
{
|
||||||
$this->storage = $storage;
|
$this->app = $app;
|
||||||
|
$this->storage = $storage->withDefaultTenant($this);
|
||||||
$this->manager = $tenantManager;
|
$this->manager = $tenantManager;
|
||||||
$this->idGenerator = $idGenerator;
|
$this->idGenerator = $idGenerator;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function new(): self
|
public static function new(Application $app = null): self
|
||||||
{
|
{
|
||||||
return app(static::class);
|
$app = $app ?? app();
|
||||||
|
|
||||||
|
return new static(
|
||||||
|
$app,
|
||||||
|
$app[StorageDriver::class],
|
||||||
|
$app[TenantManager::class],
|
||||||
|
$app[UniqueIdentifierGenerator::class]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function fromStorage(array $data): self
|
public static function fromStorage(array $data): self
|
||||||
|
|
@ -132,14 +146,14 @@ class Tenant implements ArrayAccess
|
||||||
|
|
||||||
public function save(): self
|
public function save(): self
|
||||||
{
|
{
|
||||||
if (! $this->id) {
|
if (! isset($this->data['id'])) {
|
||||||
$this->generateId();
|
$this->generateId();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->persisted) {
|
if ($this->persisted) {
|
||||||
$this->manager->createTenant($this);
|
|
||||||
} else {
|
|
||||||
$this->manager->updateTenant($this);
|
$this->manager->updateTenant($this);
|
||||||
|
} else {
|
||||||
|
$this->manager->createTenant($this);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->persisted = true;
|
$this->persisted = true;
|
||||||
|
|
@ -178,7 +192,12 @@ class Tenant implements ArrayAccess
|
||||||
|
|
||||||
public function getDatabaseName()
|
public function getDatabaseName()
|
||||||
{
|
{
|
||||||
return $this['_tenancy_db_name'] ?? $this->app['config']['tenancy.database.prefix'] . $this->uuid . $this->app['config']['tenancy.database.suffix'];
|
return $this['_tenancy_db_name'] ?? ($this->app['config']['tenancy.database.prefix'] . $this->id . $this->app['config']['tenancy.database.suffix']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getConnectionName()
|
||||||
|
{
|
||||||
|
return $this['_tenancy_db_connection'] ?? 'tenant';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -190,9 +209,11 @@ class Tenant implements ArrayAccess
|
||||||
public function get($keys)
|
public function get($keys)
|
||||||
{
|
{
|
||||||
if (is_array($keys)) {
|
if (is_array($keys)) {
|
||||||
if (array_intersect(array_keys($this->data), $keys)) { // if all keys are present in cache
|
if ((array_intersect(array_keys($this->data), $keys) === $keys) ||
|
||||||
|
! $this->persisted) { // if all keys are present in cache
|
||||||
|
|
||||||
return array_reduce($keys, function ($pairs, $key) {
|
return array_reduce($keys, function ($pairs, $key) {
|
||||||
$pairs[$key] = $this->data[$key];
|
$pairs[$key] = $this->data[$key] ?? null;
|
||||||
|
|
||||||
return $pairs;
|
return $pairs;
|
||||||
}, []);
|
}, []);
|
||||||
|
|
@ -201,11 +222,14 @@ class Tenant implements ArrayAccess
|
||||||
return $this->storage->getMany($keys);
|
return $this->storage->getMany($keys);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! isset($this->data[$keys])) {
|
// single key
|
||||||
$this->data[$keys] = $this->storage->get($keys);
|
$key = $keys;
|
||||||
|
|
||||||
|
if (! isset($this->data[$key]) && $this->persisted) {
|
||||||
|
$this->data[$key] = $this->storage->get($key);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->data[$keys];
|
return $this->data[$key];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function put($key, $value = null): self
|
public function put($key, $value = null): self
|
||||||
|
|
@ -227,8 +251,13 @@ class Tenant implements ArrayAccess
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __get($name)
|
public function __get($key)
|
||||||
{
|
{
|
||||||
return $this->get($name);
|
return $this->get($key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __set($key, $value)
|
||||||
|
{
|
||||||
|
$this->data[$key] = $value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -210,9 +210,10 @@ class TenantManager
|
||||||
|
|
||||||
protected function bootstrapFeatures(): self
|
protected function bootstrapFeatures(): self
|
||||||
{
|
{
|
||||||
foreach ($this->app['config']['tenancy.features'] as $feature) {
|
// todo this doesn't work
|
||||||
$this->app[$feature]->bootstrap($this);
|
// foreach ($this->app['config']['tenancy.features'] as $feature) {
|
||||||
}
|
// $this->app[$feature]->bootstrap($this);
|
||||||
|
// }
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
@ -225,7 +226,7 @@ class TenantManager
|
||||||
*/
|
*/
|
||||||
public function tenancyBootstrappers($except = []): array
|
public function tenancyBootstrappers($except = []): array
|
||||||
{
|
{
|
||||||
return array_key_diff($this->app['config']['tenancy.bootstrappers'], $except);
|
return array_diff_key($this->app['config']['tenancy.bootstrappers'], $except);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function shouldMigrateAfterCreation(): bool
|
public function shouldMigrateAfterCreation(): bool
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,9 @@ declare(strict_types=1);
|
||||||
namespace Stancl\Tenancy\Tests;
|
namespace Stancl\Tenancy\Tests;
|
||||||
|
|
||||||
use Illuminate\Support\Facades\Redis;
|
use Illuminate\Support\Facades\Redis;
|
||||||
use Stancl\Tenancy\StorageDrivers\DatabaseStorageDriver;
|
use Stancl\Tenancy\StorageDrivers\Database\DatabaseStorageDriver;
|
||||||
use Stancl\Tenancy\StorageDrivers\RedisStorageDriver;
|
use Stancl\Tenancy\StorageDrivers\RedisStorageDriver;
|
||||||
|
use Stancl\Tenancy\Tenant;
|
||||||
|
|
||||||
abstract class TestCase extends \Orchestra\Testbench\TestCase
|
abstract class TestCase extends \Orchestra\Testbench\TestCase
|
||||||
{
|
{
|
||||||
|
|
@ -40,19 +41,12 @@ abstract class TestCase extends \Orchestra\Testbench\TestCase
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function tearDown(): void
|
public function createTenant($domains = ['test.localhost'])
|
||||||
{
|
{
|
||||||
// config(['database.default' => 'central']);
|
Tenant::new()->withDomains($domains)->save();
|
||||||
|
|
||||||
parent::tearDown();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function createTenant($domain = 'localhost')
|
public function initTenancy($domain = 'test.localhost')
|
||||||
{
|
|
||||||
tenant()->create($domain);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function initTenancy($domain = 'localhost')
|
|
||||||
{
|
{
|
||||||
return tenancy()->init($domain);
|
return tenancy()->init($domain);
|
||||||
}
|
}
|
||||||
|
|
@ -112,13 +106,13 @@ abstract class TestCase extends \Orchestra\Testbench\TestCase
|
||||||
'tenancy.storage_driver' => RedisStorageDriver::class,
|
'tenancy.storage_driver' => RedisStorageDriver::class,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
tenancy()->storage = $app->make(RedisStorageDriver::class);
|
// tenancy()->storage = $app->make(RedisStorageDriver::class); // todo this shouldn't be necessary
|
||||||
} elseif (env('TENANCY_TEST_STORAGE_DRIVER', 'redis') === 'db') {
|
} elseif (env('TENANCY_TEST_STORAGE_DRIVER', 'redis') === 'db') {
|
||||||
$app['config']->set([
|
$app['config']->set([
|
||||||
'tenancy.storage_driver' => DatabaseStorageDriver::class,
|
'tenancy.storage_driver' => DatabaseStorageDriver::class,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
tenancy()->storage = $app->make(DatabaseStorageDriver::class);
|
// tenancy()->storage = $app->make(DatabaseStorageDriver::class); // todo this shouldn't be necessary
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue