diff --git a/src/Audit/Adapter/ClickHouse.php b/src/Audit/Adapter/ClickHouse.php index 0d598d5..2f07fe3 100644 --- a/src/Audit/Adapter/ClickHouse.php +++ b/src/Audit/Adapter/ClickHouse.php @@ -185,6 +185,30 @@ public function setDatabase(string $database): self return $this; } + /** + * Set the table name for subsequent operations. + * + * @param string $table + * @return self + * @throws Exception + */ + public function setTable(string $table): self + { + $this->validateIdentifier($table, 'Table'); + $this->table = $table; + return $this; + } + + /** + * Get the table name (without namespace prefix). + * + * @return string + */ + public function getTable(): string + { + return $this->table; + } + /** * Enable or disable HTTPS for ClickHouse HTTP interface. */ diff --git a/tests/Audit/Adapter/ClickHouseTest.php b/tests/Audit/Adapter/ClickHouseTest.php index 1374c71..17bff4d 100644 --- a/tests/Audit/Adapter/ClickHouseTest.php +++ b/tests/Audit/Adapter/ClickHouseTest.php @@ -213,6 +213,90 @@ public function testSetDatabaseWithValidIdentifier(): void $this->assertInstanceOf(ClickHouse::class, $result); } + /** + * Test setTable validates empty identifier + */ + public function testSetTableValidatesEmpty(): void + { + $this->expectException(Exception::class); + $this->expectExceptionMessage('Table cannot be empty'); + + $adapter = new ClickHouse( + host: 'clickhouse', + username: 'default', + password: 'clickhouse' + ); + + $adapter->setTable(''); + } + + /** + * Test setTable validates identifier length + */ + public function testSetTableValidatesLength(): void + { + $this->expectException(Exception::class); + $this->expectExceptionMessage('Table cannot exceed 255 characters'); + + $adapter = new ClickHouse( + host: 'clickhouse', + username: 'default', + password: 'clickhouse' + ); + + $adapter->setTable(str_repeat('a', 256)); + } + + /** + * Test setTable validates identifier format + */ + public function testSetTableValidatesFormat(): void + { + $this->expectException(Exception::class); + $this->expectExceptionMessage('Table must start with a letter or underscore'); + + $adapter = new ClickHouse( + host: 'clickhouse', + username: 'default', + password: 'clickhouse' + ); + + $adapter->setTable('123invalid'); + } + + /** + * Test setTable rejects SQL keywords + */ + public function testSetTableRejectsKeywords(): void + { + $this->expectException(Exception::class); + $this->expectExceptionMessage('Table cannot be a reserved SQL keyword'); + + $adapter = new ClickHouse( + host: 'clickhouse', + username: 'default', + password: 'clickhouse' + ); + + $adapter->setTable('SELECT'); + } + + /** + * Test setTable with valid identifier + */ + public function testSetTableWithValidIdentifier(): void + { + $adapter = new ClickHouse( + host: 'clickhouse', + username: 'default', + password: 'clickhouse' + ); + + $result = $adapter->setTable('my_audit_logs'); + $this->assertInstanceOf(ClickHouse::class, $result); + $this->assertEquals('my_audit_logs', $adapter->getTable()); + } + /** * Test setNamespace allows empty string */