diff --git a/src/Audit/Adapter/ClickHouse.php b/src/Audit/Adapter/ClickHouse.php index 0d598d5..1ebd7b7 100644 --- a/src/Audit/Adapter/ClickHouse.php +++ b/src/Audit/Adapter/ClickHouse.php @@ -42,7 +42,7 @@ class ClickHouse extends SQL protected string $namespace = ''; - protected ?int $tenant = null; + protected int|string|null $tenant = null; protected bool $sharedTables = false; @@ -208,10 +208,10 @@ public function getNamespace(): string * Set the tenant ID for multi-tenant support. * Tenant is used to isolate audit logs by tenant. * - * @param int|null $tenant + * @param int|string|null $tenant * @return self */ - public function setTenant(?int $tenant): self + public function setTenant(int|string|null $tenant): self { $this->tenant = $tenant; return $this; @@ -220,9 +220,9 @@ public function setTenant(?int $tenant): self /** * Get the tenant ID. * - * @return int|null + * @return int|string|null */ - public function getTenant(): ?int + public function getTenant(): int|string|null { return $this->tenant; } @@ -631,7 +631,7 @@ public function setup(): void // Add tenant column only if tables are shared across tenants if ($this->sharedTables) { - $columns[] = 'tenant Nullable(UInt64)'; // Supports 11-digit MySQL auto-increment IDs + $columns[] = 'tenant Nullable(String)'; } // Build indexes from base adapter schema @@ -799,7 +799,7 @@ public function getById(string $id): ?Log FORMAT JSON "; - $result = $this->query($sql, ['id' => $id]); + $result = $this->query($sql, array_merge(['id' => $id], $this->getTenantParams())); $logs = $this->parseJsonResults($result); return $logs[0] ?? null; @@ -850,7 +850,7 @@ public function find(array $queries = []): array FORMAT JSON "; - $result = $this->query($sql, $parsed['params']); + $result = $this->query($sql, array_merge($parsed['params'], $this->getTenantParams())); return $this->parseJsonResults($result); } @@ -890,7 +890,7 @@ public function count(array $queries = []): int FORMAT TabSeparated "; - $result = $this->query($sql, $params); + $result = $this->query($sql, array_merge($params, $this->getTenantParams())); $trimmed = trim($result); return $trimmed !== '' ? (int) $trimmed : 0; @@ -1197,11 +1197,13 @@ private function parseJsonResults(string $result): array $document[$columnName] = $value ?? []; } } elseif ($columnName === 'tenant') { - // Parse tenant as integer or null + // Parse tenant as int, string, or null if ($value === null || $value === '') { $document[$columnName] = null; } elseif (is_numeric($value)) { $document[$columnName] = (int) $value; + } elseif (is_scalar($value)) { + $document[$columnName] = (string) $value; } else { $document[$columnName] = null; } @@ -1279,7 +1281,21 @@ private function getTenantFilter(): string } $escapedTenant = $this->escapeIdentifier('tenant'); - return " AND {$escapedTenant} = {$this->tenant}"; + return " AND {$escapedTenant} = {_tenant:String}"; + } + + /** + * Get query parameters for tenant filtering. + * + * @return array + */ + private function getTenantParams(): array + { + if (!$this->sharedTables || $this->tenant === null) { + return []; + } + + return ['_tenant' => (string) $this->tenant]; } /** @@ -1570,7 +1586,7 @@ public function cleanup(\DateTime $datetime): bool WHERE time < {datetime:String}{$tenantFilter} "; - $this->query($sql, ['datetime' => $datetimeString]); + $this->query($sql, array_merge(['datetime' => $datetimeString], $this->getTenantParams())); return true; } diff --git a/src/Audit/Log.php b/src/Audit/Log.php index ffbf197..6708008 100644 --- a/src/Audit/Log.php +++ b/src/Audit/Log.php @@ -126,9 +126,9 @@ public function getData(): array /** * Get the tenant ID (for multi-tenant setups). * - * @return int|null + * @return int|string|null */ - public function getTenant(): ?int + public function getTenant(): int|string|null { $tenant = $this->getAttribute('tenant'); @@ -140,8 +140,8 @@ public function getTenant(): ?int return $tenant; } - if (is_numeric($tenant)) { - return (int) $tenant; + if (is_string($tenant)) { + return $tenant; } return null; diff --git a/tests/Audit/Adapter/ClickHouseTest.php b/tests/Audit/Adapter/ClickHouseTest.php index 1374c71..f252833 100644 --- a/tests/Audit/Adapter/ClickHouseTest.php +++ b/tests/Audit/Adapter/ClickHouseTest.php @@ -299,11 +299,15 @@ public function testSharedTablesConfiguration(): void $this->assertInstanceOf(ClickHouse::class, $result); $this->assertTrue($adapter->isSharedTables()); - // Test setting tenant + // Test setting tenant to int $result2 = $adapter->setTenant(12345); $this->assertInstanceOf(ClickHouse::class, $result2); $this->assertEquals(12345, $adapter->getTenant()); + // Test setting tenant to string + $adapter->setTenant('tenant_abc'); + $this->assertSame('tenant_abc', $adapter->getTenant()); + // Test setting tenant to null $adapter->setTenant(null); $this->assertNull($adapter->getTenant());