diff --git a/CHANGELOG-2.x.md b/CHANGELOG-2.x.md deleted file mode 100644 index 24e990d2..00000000 --- a/CHANGELOG-2.x.md +++ /dev/null @@ -1,2 +0,0 @@ -# Release Notes for 2.x - diff --git a/assets/migrations/2019_09_15_000000_create_domains_table.php b/assets/migrations/2019_09_15_000000_create_domains_table.php index 07593a25..e2c91e1a 100644 --- a/assets/migrations/2019_09_15_000000_create_domains_table.php +++ b/assets/migrations/2019_09_15_000000_create_domains_table.php @@ -17,7 +17,7 @@ class CreateDomainsTable extends Migration { Schema::create('domains', function (Blueprint $table) { $table->string('tenant_id', 36); // 36 characters is the default uuid length // todo foreign key? - $table->string('domain', 255)->index(); // don't change this + $table->string('domain', 255)->unique(); // don't change this }); } diff --git a/src/StorageDrivers/Database/DatabaseStorageDriver.php b/src/StorageDrivers/Database/DatabaseStorageDriver.php index a989400b..e51935c0 100644 --- a/src/StorageDrivers/Database/DatabaseStorageDriver.php +++ b/src/StorageDrivers/Database/DatabaseStorageDriver.php @@ -92,12 +92,20 @@ class DatabaseStorageDriver implements StorageDriver public function updateTenant(Tenant $tenant): void { Tenants::find($tenant->id)->putMany($tenant->data); - Domains::firstOrCreate(array_map(function ($domain) use ($tenant) { - return [ + + $original_domains = Domains::where('tenant_id', $tenant->id)->get()->map(function ($model) { + return $model->domain; + })->toArray(); + $deleted_domains = array_diff($original_domains, $tenant->domains); + + Domains::whereIn('domain', $deleted_domains)->delete(); + + foreach ($tenant->domains as $domain) { + Domains::firstOrCreate([ 'tenant_id' => $tenant->id, 'domain' => $domain, - ]; - }, $tenant->domains)); + ]); + } } public function deleteTenant(Tenant $tenant): void diff --git a/src/StorageDrivers/RedisStorageDriver.php b/src/StorageDrivers/RedisStorageDriver.php index 209ffa08..f7535003 100644 --- a/src/StorageDrivers/RedisStorageDriver.php +++ b/src/StorageDrivers/RedisStorageDriver.php @@ -99,28 +99,27 @@ class RedisStorageDriver implements StorageDriver public function updateTenant(Tenant $tenant): void { + $id = $tenant->id; + + $old_domains = json_decode($this->redis->hget("tenants:$id", '_tenancy_domains'), true); + $deleted_domains = array_diff($old_domains, $tenant->domains); + $domains = $tenant->domains; + $data = []; foreach ($tenant->data as $key => $value) { - $data[$key] = json_decode($value, true); + $data[$key] = json_encode($value); } - $domains = $data['_tenancy_domains']; - unset($data['_tenancy_domains']); - - $this->redis->transaction(function ($pipe) use ($data, $domains) { - $id = $data['id']; - - $old_domains = json_decode($pipe->hget("tenants:$id", 'domains'), true); - $deleted_domains = array_diff($old_domains, $domains); - + $this->redis->transaction(function ($pipe) use ($id, $data, $deleted_domains, $domains) { foreach ($deleted_domains as $deleted_domain) { $pipe->del("domains:$deleted_domain"); } - $pipe->hmset("tenants:$id", array_merge($data, ['_tenancy_domains' => json_encode($domains)])); foreach ($domains as $domain) { - $pipe->hmset("domains:$domain", 'tenant_id', $id); + $pipe->hset("domains:$domain", 'tenant_id', $id); } + + $pipe->hmset("tenants:$id", array_merge($data, ['_tenancy_domains' => json_encode($domains)])); }); } diff --git a/src/Tenant.php b/src/Tenant.php index 2b758ed5..713b9fe9 100644 --- a/src/Tenant.php +++ b/src/Tenant.php @@ -279,4 +279,9 @@ class Tenant implements ArrayAccess } $this->data[$key] = $value; } + + public function __call($name, $arguments) + { + // todo withId() + } } diff --git a/tests/TenantClassTest.php b/tests/TenantClassTest.php index 73ecb1f6..322530c9 100644 --- a/tests/TenantClassTest.php +++ b/tests/TenantClassTest.php @@ -46,4 +46,30 @@ class TenantClassTest extends TestCase $this->assertSame($tenant->id, Tenancy::findByDomain('foo.localhost')->id); $this->assertSame($tenant->id, Tenancy::findByDomain('bar.localhost')->id); } + + /** @test */ + public function updating_a_tenant_works() + { + $id = 'abc' . $this->randomString(); + $tenant = Tenant::create(['foo.localhost'], ['id' => $id]); + $tenant->foo = 'bar'; + $tenant->save(); + $this->assertEquals(['id' => $id, 'foo' => 'bar'], $tenant->data); + $this->assertEquals(['id' => $id, 'foo' => 'bar'], tenancy()->find($id)->data); + + $tenant->addDomains('abc.localhost'); + $tenant->save(); + $this->assertEqualsCanonicalizing(['foo.localhost', 'abc.localhost'], $tenant->domains); + $this->assertEqualsCanonicalizing(['foo.localhost', 'abc.localhost'], tenancy()->find($id)->domains); + + $tenant->removeDomains(['foo.localhost']); + $tenant->save(); + $this->assertEqualsCanonicalizing(['abc.localhost'], $tenant->domains); + $this->assertEqualsCanonicalizing(['abc.localhost'], tenancy()->find($id)->domains); + + $tenant->withDomains(['completely.localhost', 'different.localhost', 'domains.localhost']); + $tenant->save(); + $this->assertEqualsCanonicalizing(['completely.localhost', 'different.localhost', 'domains.localhost'], $tenant->domains); + $this->assertEqualsCanonicalizing(['completely.localhost', 'different.localhost', 'domains.localhost'], tenancy()->find($id)->domains); + } }