1
0
Fork 0
mirror of https://github.com/archtechx/tenancy.git synced 2026-02-05 07:34:03 +00:00

Merge pull request #1 from stancl/support-schema-postgres

[WIP] Some changes to Support schema postgres
This commit is contained in:
Noor Adiana 2019-12-04 09:18:40 +07:00 committed by GitHub
commit 90d04a336d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 109 additions and 35 deletions

View file

@ -60,7 +60,7 @@ return [
'sqlite' => Stancl\Tenancy\TenantDatabaseManagers\SQLiteDatabaseManager::class,
'mysql' => Stancl\Tenancy\TenantDatabaseManagers\MySQLDatabaseManager::class,
'pgsql' => Stancl\Tenancy\TenantDatabaseManagers\PostgreSQLDatabaseManager::class,
'schema' => Stancl\Tenancy\TenantDatabaseManagers\PostgreSQLSchemaManager::class
// 'pgsql' => Stancl\Tenancy\TenantDatabaseManagers\PostgreSQLSchemaManager::class, // Separate by schema instead of database
],
'database_manager_connections' => [
// Connections used by TenantDatabaseManagers. This tells, for example, the
@ -68,9 +68,8 @@ return [
'sqlite' => 'sqlite',
'mysql' => 'mysql',
'pgsql' => 'pgsql',
'schema' => 'pgsql'
],
'using_schema_connection' => false, // Only work with pgsql connection
'separate_by' => 'database', // database or schema (only supported by pgsql)
'bootstrappers' => [
// Tenancy bootstrappers are executed when tenancy is initialized.
// Their responsibility is making Laravel features tenant-aware.

View file

@ -100,12 +100,9 @@ class DatabaseManager
// Change database name.
$databaseName = $this->getDriver($connectionName) === 'sqlite' ? database_path($databaseName) : $databaseName;
$separateBy = $this->separateBy($connectionName);
if ($this->isUsingSchema($connectionName)) {
$this->app['config']["database.connections.$connectionName.schema"] = $databaseName;
} else {
$this->app['config']["database.connections.$connectionName.database"] = $databaseName;
}
$this->app['config']["database.connections.$connectionName.$separateBy"] = $databaseName;
}
/**
@ -231,7 +228,7 @@ class DatabaseManager
*/
public function getTenantDatabaseManager(Tenant $tenant): TenantDatabaseManager
{
$driver = $this->isUsingSchema($tenant->getConnectionName()) ? 'schema' : $this->getDriver($this->getBaseConnection($tenant->getConnectionName()));
$driver = $this->getDriver($this->getBaseConnection($tenant->getConnectionName()));
$databaseManagers = $this->app['config']['tenancy.database_managers'];
@ -241,15 +238,20 @@ class DatabaseManager
return $this->app[$databaseManagers[$driver]];
}
/**
* Check if using schema connection
*
* What key on the connection config should be used to separate tenants.
*
* @param string $connectionName
* @return bool
* @return string
*/
protected function isUsingSchema(string $connectionName): bool
public function separateBy(string $connectionName): string
{
return $this->getDriver($this->getBaseConnection($connectionName)) === 'pgsql' && $this->app['config']['tenancy.using_schema_connection'];
if ($this->getDriver($this->getBaseConnection($connectionName)) === 'pgsql'
&& $this->app['config']['tenancy.separate_by'] === 'schema') {
return 'schema';
}
return 'database';
}
}

View file

@ -15,7 +15,7 @@ class PostgreSQLSchemaManager implements TenantDatabaseManager
public function __construct(Repository $config, IlluminateDatabaseManager $databaseManager)
{
$this->database = $databaseManager->connection($config['tenancy.database_manager_connections.schema']);
$this->database = $databaseManager->connection($config['tenancy.database_manager_connections.pgsql']);
}
public function createDatabase(string $name): bool

View file

@ -4,48 +4,45 @@ declare(strict_types=1);
namespace Stancl\Tenancy\Tests;
use Stancl\Tenancy\DatabaseManager;
use Stancl\Tenancy\Tenant;
class DatabaseSchemaManagerTest extends TestCase
{
public $autoInitTenancy = false;
/**
* Define environment setup.
*
* @param \Illuminate\Foundation\Application $app
* @return void
*/
protected function getEnvironmentSetUp($app)
{
parent::getEnvironmentSetUp($app);
$app['config']->set('database.default', 'pgsql');
$app['config']->set('tenancy.database.based_on', null);
$app['config']->set('tenancy.database.suffix', '');
$app['config']->set('tenancy.using_schema_connection', true);
$app['config']->set([
'database.default' => 'pgsql',
'database.connections.pgsql.database' => 'main',
'database.connections.pgsql.schema' => 'public',
'tenancy.database.based_on' => null,
'tenancy.database.suffix' => '',
'tenancy.separate_by' => 'schema',
]);
}
/** @test */
public function reconnect_method_works()
{
$old_connection_name = app(\Illuminate\Database\DatabaseManager::class)->connection()->getName();
tenancy()->init('test.localhost');
app(\Stancl\Tenancy\DatabaseManager::class)->reconnect();
$new_connection_name = app(\Illuminate\Database\DatabaseManager::class)->connection()->getName();
// $this->assertSame($old_connection_name, $new_connection_name);
$this->assertNotEquals('tenant', $new_connection_name);
$this->assertSame($old_connection_name, $new_connection_name);
}
/** @test */
public function the_default_db_is_used_when_based_on_is_null()
{
config(['database.default' => 'pgsql']);
$this->assertSame('pgsql', config('database.default'));
config([
'database.connections.pgsql.foo' => 'bar',
@ -66,4 +63,79 @@ class DatabaseSchemaManagerTest extends TestCase
$this->assertSame($tenant->getDatabaseName(), config('database.connections.' . config('database.default') . '.schema'));
}
/** @test */
public function databases_are_separated_using_schema_and_not_database()
{
tenancy()->create('foo.localhost');
tenancy()->init('foo.localhost');
$this->assertSame('tenant', config('database.default'));
$this->assertSame('main', config('database.connections.tenant.database'));
$schema1 = config('database.connections.' . config('database.default') . '.schema');
$database1 = config('database.connections.' . config('database.default') . '.database');
tenancy()->create('bar.localhost');
tenancy()->init('bar.localhost');
$this->assertSame('tenant', config('database.default'));
$this->assertSame('main', config('database.connections.tenant.database'));
$schema2 = config('database.connections.' . config('database.default') . '.schema');
$database2 = config('database.connections.' . config('database.default') . '.database');
$this->assertSame($database1, $database2);
$this->assertNotSame($schema1, $schema2);
}
/** @test */
public function databases_are_separated()
{
// copied from DataSeparationTest
$tenant1 = Tenant::create('tenant1.localhost');
$tenant2 = Tenant::create('tenant2.localhost');
\Artisan::call('tenants:migrate', [
'--tenants' => [$tenant1['id'], $tenant2['id']],
]);
tenancy()->init('tenant1.localhost');
User::create([
'name' => 'foo',
'email' => 'foo@bar.com',
'email_verified_at' => now(),
'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
'remember_token' => Str::random(10),
]);
$this->assertSame('foo', User::first()->name);
tenancy()->init('tenant2.localhost');
$this->assertSame(null, User::first());
User::create([
'name' => 'xyz',
'email' => 'xyz@bar.com',
'email_verified_at' => now(),
'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
'remember_token' => Str::random(10),
]);
$this->assertSame('xyz', User::first()->name);
$this->assertSame('xyz@bar.com', User::first()->email);
tenancy()->init('tenant1.localhost');
$this->assertSame('foo', User::first()->name);
$this->assertSame('foo@bar.com', User::first()->email);
$tenant3 = Tenant::create('tenant3.localhost');
\Artisan::call('tenants:migrate', [
'--tenants' => [$tenant1['id'], $tenant3['id']],
]);
tenancy()->init('tenant3.localhost');
$this->assertSame(null, User::first());
tenancy()->init('tenant1.localhost');
DB::table('users')->where('id', 1)->update(['name' => 'xxx']);
$this->assertSame('xxx', User::first()->name);
}
}

View file

@ -10,8 +10,8 @@ use Stancl\Tenancy\Jobs\QueuedTenantDatabaseDeleter;
use Stancl\Tenancy\Tenant;
use Stancl\Tenancy\TenantDatabaseManagers\MySQLDatabaseManager;
use Stancl\Tenancy\TenantDatabaseManagers\PostgreSQLDatabaseManager;
use Stancl\Tenancy\TenantDatabaseManagers\SQLiteDatabaseManager;
use Stancl\Tenancy\TenantDatabaseManagers\PostgreSQLSchemaManager;
use Stancl\Tenancy\TenantDatabaseManagers\SQLiteDatabaseManager;
class TenantDatabaseManagerTest extends TestCase
{
@ -79,7 +79,7 @@ class TenantDatabaseManagerTest extends TestCase
['mysql', MySQLDatabaseManager::class],
['sqlite', SQLiteDatabaseManager::class],
['pgsql', PostgreSQLDatabaseManager::class],
['schema', PostgreSQLSchemaManager::class]
['pgsql', PostgreSQLSchemaManager::class],
];
}

View file

@ -24,11 +24,12 @@ abstract class TestCase extends \Orchestra\Testbench\TestCase
Redis::connection('tenancy')->flushdb();
Redis::connection('cache')->flushdb();
$originalConnection = config('database.default');
$this->loadMigrationsFrom([
'--path' => realpath(__DIR__ . '/../assets/migrations'),
'--database' => 'central',
]);
config(['database.default' => 'sqlite']); // fix issue caused by loadMigrationsFrom
config(['database.default' => $originalConnection]); // fix issue caused by loadMigrationsFrom
if ($this->autoCreateTenant) {
$this->createTenant();