From c475e7a43dd051089f86f6c93b91727a0baa2db6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20=C5=A0tancl?= Date: Sat, 21 Sep 2019 13:54:02 +0200 Subject: [PATCH] Fix transactions --- src/Commands/Migrate.php | 2 +- src/DatabaseManager.php | 17 +++++++++++++++++ src/Features/TelescopeTags.php | 1 - .../Database/CentralConnection.php | 13 +++++++++++++ .../Database/DatabaseStorageDriver.php | 14 ++++++++------ src/StorageDrivers/Database/DomainModel.php | 8 ++------ src/StorageDrivers/Database/TenantModel.php | 8 ++------ .../QueueTenancyBootstrapper.php | 1 - tests/QueueTest.php | 2 +- tests/TenantAssetTest.php | 7 +++---- tests/TenantClassTest.php | 1 - 11 files changed, 47 insertions(+), 27 deletions(-) create mode 100644 src/StorageDrivers/Database/CentralConnection.php diff --git a/src/Commands/Migrate.php b/src/Commands/Migrate.php index 3eb4cf3c..7f68e37b 100644 --- a/src/Commands/Migrate.php +++ b/src/Commands/Migrate.php @@ -56,7 +56,7 @@ class Migrate extends MigrateCommand // See Illuminate\Database\Migrations\DatabaseMigrationRepository::getConnection. // Database connections are cached by Illuminate\Database\ConnectionResolver. $this->input->setOption('database', 'tenant'); - tenancy()->initialize($tenant); // todo3 test that this works with multiple tenants with MySQL + tenancy()->initialize($tenant); // todo2 test that this works with multiple tenants with MySQL // Migrate parent::handle(); diff --git a/src/DatabaseManager.php b/src/DatabaseManager.php index c36b51fa..dd41b772 100644 --- a/src/DatabaseManager.php +++ b/src/DatabaseManager.php @@ -4,8 +4,10 @@ declare(strict_types=1); namespace Stancl\Tenancy; +use Illuminate\Database\Connection; use Illuminate\Database\DatabaseManager as BaseDatabaseManager; use Illuminate\Foundation\Application; +use Illuminate\Support\Facades\DB; use Stancl\Tenancy\Contracts\TenantDatabaseManager; use Stancl\Tenancy\Exceptions\DatabaseManagerNotRegisteredException; use Stancl\Tenancy\Exceptions\TenantDatabaseAlreadyExistsException; @@ -176,4 +178,19 @@ class DatabaseManager return $this->app[$databaseManagers[$driver]]; } + + /** + * Get the central database connection. + * + * @return \Illuminate\Database\Connection + */ + public function getCentralConnection(): \Illuminate\Database\Connection + { + return DB::connection($this->getCentralConnectionName()); + } + + public function getCentralConnectionName(): string + { + return $this->app['config']['tenancy.storage.db.connection'] ?? $this->originalDefaultConnectionName; + } } diff --git a/src/Features/TelescopeTags.php b/src/Features/TelescopeTags.php index bc7235c2..89709720 100644 --- a/src/Features/TelescopeTags.php +++ b/src/Features/TelescopeTags.php @@ -26,7 +26,6 @@ class TelescopeTags implements Feature if (in_array('tenancy', optional(request()->route())->middleware() ?? [])) { $tags = array_merge($tags, [ 'tenant:' . tenant('id'), - // todo3 domain? ]); } diff --git a/src/StorageDrivers/Database/CentralConnection.php b/src/StorageDrivers/Database/CentralConnection.php new file mode 100644 index 00000000..bfb6b05f --- /dev/null +++ b/src/StorageDrivers/Database/CentralConnection.php @@ -0,0 +1,13 @@ +getCentralConnectionName(); + } +} \ No newline at end of file diff --git a/src/StorageDrivers/Database/DatabaseStorageDriver.php b/src/StorageDrivers/Database/DatabaseStorageDriver.php index b3a1bd9f..c18dbad8 100644 --- a/src/StorageDrivers/Database/DatabaseStorageDriver.php +++ b/src/StorageDrivers/Database/DatabaseStorageDriver.php @@ -5,8 +5,8 @@ declare(strict_types=1); namespace Stancl\Tenancy\StorageDrivers\Database; use Illuminate\Foundation\Application; -use Illuminate\Support\Facades\DB; use Stancl\Tenancy\Contracts\StorageDriver; +use Stancl\Tenancy\DatabaseManager; use Stancl\Tenancy\Exceptions\DomainsOccupiedByOtherTenantException; use Stancl\Tenancy\Exceptions\TenantCouldNotBeIdentifiedException; use Stancl\Tenancy\Exceptions\TenantWithThisIdAlreadyExistsException; @@ -16,17 +16,19 @@ use Stancl\Tenancy\Tenant; class DatabaseStorageDriver implements StorageDriver { - // todo4 write tests verifying that data is decoded and added to the array - /** @var Application */ protected $app; + /** @var \Illuminate\Database\Connection */ + protected $centralDatabase; + /** @var Tenant The default tenant. */ protected $tenant; public function __construct(Application $app) { $this->app = $app; + $this->centralDatabase = $app->make(DatabaseManager::class)->getCentralConnection(); } public function findByDomain(string $domain): Tenant @@ -77,7 +79,7 @@ class DatabaseStorageDriver implements StorageDriver public function createTenant(Tenant $tenant): void { - DB::transaction(function () use ($tenant) { + $this->centralDatabase->transaction(function () use ($tenant) { Tenants::create(['id' => $tenant->id, 'data' => '{}'])->toArray(); $domainData = []; @@ -90,7 +92,7 @@ class DatabaseStorageDriver implements StorageDriver public function updateTenant(Tenant $tenant): void { - DB::transaction(function () use ($tenant) { + $this->centralDatabase->transaction(function () use ($tenant) { Tenants::find($tenant->id)->putMany($tenant->data); $original_domains = Domains::where('tenant_id', $tenant->id)->get()->map(function ($model) { @@ -111,7 +113,7 @@ class DatabaseStorageDriver implements StorageDriver public function deleteTenant(Tenant $tenant): void { - DB::transacton(function () use ($tenant) { + $this->centralDatabase->transaction(function () use ($tenant) { Tenants::find($tenant->id)->delete(); Domains::where('tenant_id', $tenant->id)->delete(); }); diff --git a/src/StorageDrivers/Database/DomainModel.php b/src/StorageDrivers/Database/DomainModel.php index 17c88ca1..0017e8f6 100644 --- a/src/StorageDrivers/Database/DomainModel.php +++ b/src/StorageDrivers/Database/DomainModel.php @@ -5,13 +5,14 @@ declare(strict_types=1); namespace Stancl\Tenancy\StorageDrivers\Database; use Illuminate\Database\Eloquent\Model; -use Stancl\Tenancy\DatabaseManager; /** * @internal Class is subject to breaking changes in minor and patch versions. */ class DomainModel extends Model { + use CentralConnection; + protected $guarded = []; protected $primaryKey = 'id'; public $incrementing = false; @@ -21,9 +22,4 @@ class DomainModel extends Model { return config('tenancy.storage.db.table_names.DomainModel', 'domains'); } - - public function getConnectionName() - { - return config('tenancy.storage.db.connection') ?? app(DatabaseManager::class)->originalDefaultConnectionName; - } } diff --git a/src/StorageDrivers/Database/TenantModel.php b/src/StorageDrivers/Database/TenantModel.php index ed1b42d1..36c24b58 100644 --- a/src/StorageDrivers/Database/TenantModel.php +++ b/src/StorageDrivers/Database/TenantModel.php @@ -5,13 +5,14 @@ declare(strict_types=1); namespace Stancl\Tenancy\StorageDrivers\Database; use Illuminate\Database\Eloquent\Model; -use Stancl\Tenancy\DatabaseManager; /** * @internal Class is subject to breaking changes in minor and patch versions. */ class TenantModel extends Model { + use CentralConnection; + protected $guarded = []; protected $primaryKey = 'id'; public $incrementing = false; @@ -32,11 +33,6 @@ class TenantModel extends Model return config('tenancy.storage.db.custom_columns', []); } - public function getConnectionName() - { - return config('tenancy.storage.db.connection') ?? app(DatabaseManager::class)->originalDefaultConnectionName; - } - public static function getAllTenants(array $ids) { $tenants = $ids ? static::findMany($ids) : static::all(); diff --git a/src/TenancyBootstrappers/QueueTenancyBootstrapper.php b/src/TenancyBootstrappers/QueueTenancyBootstrapper.php index 638aa88e..8f8c0b16 100644 --- a/src/TenancyBootstrappers/QueueTenancyBootstrapper.php +++ b/src/TenancyBootstrappers/QueueTenancyBootstrapper.php @@ -50,7 +50,6 @@ class QueueTenancyBootstrapper implements TenancyBootstrapper 'tenant_id' => $id, 'tags' => [ "tenant:$id", - // todo3 domain ], ]; } diff --git a/tests/QueueTest.php b/tests/QueueTest.php index a8290791..7d24fdc3 100644 --- a/tests/QueueTest.php +++ b/tests/QueueTest.php @@ -17,7 +17,7 @@ class QueueTest extends TestCase /** @test */ public function queues_use_non_tenant_db_connection() { - // todo2 finish this test. requires using the db driver + // requires using the db driver $this->markTestIncomplete(); } diff --git a/tests/TenantAssetTest.php b/tests/TenantAssetTest.php index 45885749..259bd0c1 100644 --- a/tests/TenantAssetTest.php +++ b/tests/TenantAssetTest.php @@ -15,14 +15,13 @@ class TenantAssetTest extends TestCase // response()->file() returns BinaryFileResponse whose content is // inaccessible via getContent, so ->assertSee() can't be used - // $this->get(tenant_asset($filename))->assertSuccessful(); // todo2 commented assertions - // $this->assertFileExists($path); // todo2 commented assertions + $this->get(tenant_asset($filename))->assertSuccessful(); + $this->assertFileExists($path); $f = fopen($path, 'r'); $content = fread($f, filesize($path)); fclose($f); - // $this->assertSame('bar', $content); // todo2 commented assertions - $this->assertTrue(true); + $this->assertSame('bar', $content); } } diff --git a/tests/TenantClassTest.php b/tests/TenantClassTest.php index f7b29325..fc3965e8 100644 --- a/tests/TenantClassTest.php +++ b/tests/TenantClassTest.php @@ -17,7 +17,6 @@ class TenantClassTest extends TestCase /** @test */ public function data_cache_works_properly() { - // todo constructor dependencies // $spy = Mockery::spy(config('tenancy.storage_driver'))->makePartial(); // $this->instance(StorageDriver::class, $spy);