diff --git a/README.md b/README.md
index 880b50a..e894347 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,8 @@
# catalogs-php
A PHP framework to talk to Catalogs. Part of the [CloudFest 2024 Hackathon](https://hackathon.cloudfest.com/project/integrating-mariadb-catalogs-with-php-platforms/).
+![Build status](https://github.com/MariaDB/catalogs-php/actions/workflows/test.yml/badge.svg?branch=main)
+
# Installation
Include the catalog-php with composer:
@@ -15,8 +17,12 @@ Include autoloader in your project.
create('wp_1');
-$cat->createAdminUserForCatalog('wp_1', 'admin', 'adminpassword', '%');
+$cat = new CatalogManager('127.0.0.1', 3306, 'root', 'rootpassword');
+$catPort = $cat->create('wp_2');
+$cat->createAdminUserForCatalog('wp_2', 'admin', 'adminpassword', '%');
// Using PDO, Create a DB and user in the collection using the $catPort.
// Set DB_NAME with the "name:$catPort"
diff --git a/phpcs.xml.dist b/phpcs.xml.dist
index 8ed79a5..b58f901 100644
--- a/phpcs.xml.dist
+++ b/phpcs.xml.dist
@@ -14,6 +14,12 @@
+
+
+
+
+
+
diff --git a/src/Catalog.php b/src/CatalogManager.php
similarity index 76%
rename from src/Catalog.php
rename to src/CatalogManager.php
index d4f5850..0877943 100644
--- a/src/Catalog.php
+++ b/src/CatalogManager.php
@@ -9,7 +9,7 @@
*
* @package Mariadb\CatalogsPHP
*/
-class Catalog
+class CatalogManager
{
/**
* The connection to the MariaDB server.
@@ -18,6 +18,15 @@ class Catalog
*/
private $connection;
+ // Prepared statements with the USE CATALOG command are not working as expected.
+ // This method is used to check the catalog name before using it in a query.
+ private function checkCatalogName($catalogName): void
+ {
+ if (preg_match('/[^a-zA-Z0-9_]/', $catalogName) === 1) {
+ throw new CatalogManagerException('Invalid catalog name');
+ }
+ }
+
// This is too low, because this is a beta version we are developing for.
public const MINIMAL_MARIA_VERSION = '11.0.2';
@@ -39,7 +48,7 @@ class Catalog
* @param \PDO|null $pdo Optional. An existing PDO connection to use. Default is null.
*
* @throws PDOException If a PDO error occurs during the connection attempt.
- * @throws Exception If a general error occurs during instantiation.
+ * @throws CatalogManagerException If a general error occurs during instantiation.
*/
public function __construct(
protected string $dbHost = 'localhost',
@@ -71,7 +80,7 @@ public function __construct(
$version = $versionQuery->fetchColumn();
if (version_compare($version, self::MINIMAL_MARIA_VERSION, '<') === true) {
- throw new Exception(
+ throw new CatalogManagerException(
'The MariaDB version is too low. The minimal version is ' . self::MINIMAL_MARIA_VERSION
);
}
@@ -86,28 +95,29 @@ public function __construct(
/**
* Create a new catalog
*
- * @param string $catName The new Catalog name.
+ * @param string $catalogName The new Catalog name.
*
* @return int
*/
- public function create(string $catName): int
+ public function create(string $catalogName): int
{
// Check if the Catalog name is valid.
- if (in_array($catName, array_keys($this->list())) === true) {
- throw new Exception('Catalog name already exists.');
+ if (in_array($catalogName, array_keys($this->list())) === true) {
+ throw new CatalogManagerException('Catalog name already exists.');
}
$rootPrivileges = $this->connection->query("SELECT * FROM mysql.global_priv WHERE User='{$this->dbUser}' AND Host='%';");
$scripts = [
- 'src/create_catalog_sql/mysql_system_tables.sql',
- 'src/create_catalog_sql/mysql_performance_tables.sql',
- 'src/create_catalog_sql/mysql_system_tables_data.sql',
- 'src/create_catalog_sql/maria_add_gis_sp.sql',
- 'src/create_catalog_sql/mysql_sys_schema.sql',
+ __DIR__ . '/create_catalog_sql/mysql_system_tables.sql',
+ __DIR__ . '/create_catalog_sql/mysql_performance_tables.sql',
+ __DIR__ . '/create_catalog_sql/mysql_system_tables_data.sql',
+ __DIR__ . '/create_catalog_sql/maria_add_gis_sp.sql',
+ __DIR__ . '/create_catalog_sql/mysql_sys_schema.sql',
];
- $this->connection->exec('CREATE CATALOG IF NOT EXISTS ' . $catName);
- $this->connection->exec('USE CATALOG ' . $catName);
+ $this->checkCatalogName($catalogName);
+ $this->connection->exec('CREATE CATALOG IF NOT EXISTS ' . $catalogName);
+ $this->connection->exec('USE CATALOG ' . $catalogName);
$this->connection->exec('CREATE DATABASE IF NOT EXISTS mysql');
$this->connection->exec('USE mysql');
@@ -139,18 +149,18 @@ public function create(string $catName): int
}
}
- return $this->getPort($catName);
+ return $this->getPort($catalogName);
}
/**
* Get the port of a catalog.
*
- * @param string $catName The catalog name.
+ * @param string $catalogName The catalog name.
*
* @return int
*/
- public function getPort(string $catName): int
+ public function getPort(string $catalogName): int
{
// TODO: wait for the functionality to be implemented in the server.
return ($this->dbPort ?? 0);
@@ -179,24 +189,25 @@ public function list(): array
/**
* Drop a catalog.
*
- * @param string $catName The catalog name.
+ * @param string $catalogName The catalog name.
*
* @return void
*
* @throws PDOException If a PDO error occurs during the catalog drop attempt.
- * @throws Exception If a general error occurs during catalog drop.
+ * @throws CatalogManagerException If a general error occurs during catalog drop.
*/
- public function drop(string $catName): bool
+ public function drop(string $catalogName): bool
{
try {
// Enter the catalog.
- $this->connection->exec('USE CATALOG ' . $catName);
+ $this->checkCatalogName($catalogName);
+ $this->connection->exec('USE CATALOG ' . $catalogName);
// Check if there are any tables besides mysql, sys, performance_schema and information_schema.
$tables = $this->connection->query('SHOW DATABASES');
foreach ($tables as $table) {
if (in_array($table['Database'], ['mysql', 'sys', 'performance_schema', 'information_schema']) === false) {
- throw new \Exception('Catalog is not empty');
+ throw new CatalogManagerException('Catalog is not empty');
}
}
@@ -206,9 +217,9 @@ public function drop(string $catName): bool
$this->connection->exec('DROP DATABASE IF EXISTS performance_schema');
// Drop the catalog.
- $this->connection->exec('DROP CATALOG ' . $catName);
+ $this->connection->exec('DROP CATALOG ' . $catalogName);
} catch (\PDOException $e) {
- throw new \Exception('Error dropping catalog: ' . $e->getMessage());
+ throw new CatalogManagerException('Error dropping catalog: ' . $e->getMessage());
}
return true;
@@ -231,7 +242,7 @@ private function alter()
/**
* Create admin user for a catalog
*
- * @param string $catalog The catalog name
+ * @param string $catalogName The catalog name
* @param string $userName The user name
* @param string $password The user password
* @param string $authHost The database host
@@ -239,16 +250,17 @@ private function alter()
* @return void
*/
public function createAdminUserForCatalog(
- string $catalog,
+ string $catalogName,
string $userName,
string $password,
string $authHost = 'localhost'
): void {
- $this->connection->exec("USE CATALOG {$catalog}");
+ $this->checkCatalogName($catalogName);
+ $this->connection->exec("USE CATALOG {$catalogName}");
$this->connection->exec("USE mysql");
$this->connection = new \PDO(
- "mysql:host={$this->dbHost};port={$this->dbPort};dbname={$catalog}.mysql",
+ "mysql:host={$this->dbHost};port={$this->dbPort};dbname={$catalogName}.mysql",
$this->dbUser,
$this->dbPass,
$this->dbOptions
diff --git a/src/Exception.php b/src/CatalogManagerException.php
similarity index 96%
rename from src/Exception.php
rename to src/CatalogManagerException.php
index b56f340..4d9a0f2 100644
--- a/src/Exception.php
+++ b/src/CatalogManagerException.php
@@ -12,7 +12,7 @@
*
* @package Mariadb\CatalogsPHP
*/
-class Exception extends \Exception
+class CatalogManagerException extends \Exception
{
/**
* Constructs the Exception.
diff --git a/tests/CatalogTest.php b/tests/CatalogTest.php
index e86afa9..8633c7e 100644
--- a/tests/CatalogTest.php
+++ b/tests/CatalogTest.php
@@ -2,23 +2,41 @@
namespace Mariadb\CatalogsPHP\Tests;
-use Mariadb\CatalogsPHP\Catalog;
+use Mariadb\CatalogsPHP\CatalogManager;
use PHPUnit\Framework\TestCase;
+/**
+ * Class PDOStatementMock
+ *
+ * A mock for the PDOStatement class
+ */
class CatalogTest extends TestCase
{
+ /**
+ * @var CatalogManager $catalog The Catalog instance to test
+ */
private $catalog;
+
+ /**
+ * @var \PDO $pdoMock The PDO mock to inject into the Catalog instance
+ */
private $pdoMock;
+ /**
+ * Set up the test
+ */
protected function setUp(): void
{
// Create a mock for the PDO class
$this->pdoMock = $this->createMock(\PDO::class);
// Inject the PDO mock into your Catalog class
- $this->catalog = new Catalog('localhost', 3306, 'root', '', null, $this->pdoMock);
+ $this->catalog = new CatalogManager('localhost', 3306, 'root', '', null, $this->pdoMock);
}
+ /**
+ * Test the list method
+ */
public function testList()
{
// Mock the PDOStatement for the 'SHOW CATALOGS' query
@@ -42,12 +60,18 @@ public function testList()
], $catalogs);
}
+ /**
+ * Test the getPort method
+ */
public function testGetPort()
{
$port = $this->catalog->getPort('test');
$this->assertEquals(3306, $port);
}
+ /**
+ * Test the create method
+ */
public function testCreate()
{
// Configure the PDO mock to return the PDOStatement mock for the 'SHOW CATALOGS' query