connectSqlite($options); break; case 'mysql': case 'mariadb': $this->connectMysql($options); break; default: $this->pdo = null; } } /** * Establishes a connection to a SQLite database. * * @param array $options An associative array with SQLite connection options: * - dbFile: The path to the SQLite database file. * * @throws Exception If the SQLite PDO extension is not loaded or the database file is missing. */ private function connectSqlite($options) { // pdo_sqlite extension is needed if (!extension_loaded('pdo_sqlite')) { throw new Exception('PDO extension for SQLite not loaded.'); } // SQLite options if (empty($options['dbFile'])) { throw new Exception('SQLite database file path is missing.'); } // For in-memory database (especially for the tests), skip file check if ($options['dbFile'] !== ':memory:' && !file_exists($options['dbFile'])) { throw new Exception("SQLite database file \"{$options['dbFile']}\" not found."); } // connect to SQLite try { $this->pdo = new PDO("sqlite:" . $options['dbFile']); $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // enable foreign key constraints (not ON by default in SQLite3) $this->pdo->exec('PRAGMA foreign_keys = ON;'); } catch (PDOException $e) { throw new Exception('SQLite connection failed: ' . $e->getMessage()); } } /** * Establishes a connection to a MySQL (or MariaDB) database. * * @param array $options An associative array with MySQL connection options: * - host: The database host. * - port: The database port (default: 3306). * - dbname: The name of the database. * - user: The database username. * - password: The database password (optional). * * @throws Exception If the MySQL PDO extension is not loaded or required options are missing. */ private function connectMysql($options) { // pdo_mysql extension is needed if (!extension_loaded('pdo_mysql')) { throw new Exception('PDO extension for MySQL not loaded.'); } // MySQL options if (empty($options['host']) || empty($options['dbname']) || empty($options['user'])) { throw new Exception('MySQL connection data is missing.'); } // Connect to MySQL try { $port = $options['port'] ?? 3306; $dsn = "mysql:host={$options['host']};port={$port};dbname={$options['dbname']};charset=utf8"; $this->pdo = new PDO($dsn, $options['user'], $options['password'] ?? ''); $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch (PDOException $e) { $this->pdo = null; } } /** * Retrieves the current PDO connection instance. * * @return PDO|null The PDO instance or null if no connection is established. */ public function getConnection() { return $this->pdo; } /** * Executes an SQL query with optional parameters. * * @param string $query The SQL query to execute * @param array $params Optional parameters for the query * @return PDOStatement|false The result of the query execution * @throws Exception If the query fails */ public function execute($query, $params = []) { if (!$this->pdo) { throw new Exception('No database connection.'); } try { $stmt = $this->pdo->prepare($query); $stmt->execute($params); return $stmt; } catch (PDOException $e) { throw new Exception('Query execution failed: ' . $e->getMessage()); } } /** * Prepares an SQL statement for execution. * * @param string $query The SQL query to prepare * @return PDOStatement The prepared statement * @throws Exception If the preparation fails */ public function prepare($query) { if (!$this->pdo) { throw new Exception('No database connection.'); } try { return $this->pdo->prepare($query); } catch (PDOException $e) { throw new Exception('Statement preparation failed: ' . $e->getMessage()); } } /** * Begins a database transaction. * * @throws Exception If starting the transaction fails */ public function beginTransaction() { if (!$this->pdo) { throw new Exception('No database connection.'); } try { return $this->pdo->beginTransaction(); } catch (PDOException $e) { throw new Exception('Failed to start transaction: ' . $e->getMessage()); } } /** * Commits the current database transaction. * * @throws Exception If committing the transaction fails */ public function commit() { if (!$this->pdo) { throw new Exception('No database connection.'); } try { return $this->pdo->commit(); } catch (PDOException $e) { throw new Exception('Failed to commit transaction: ' . $e->getMessage()); } } /** * Rolls back the current database transaction. * * @throws Exception If rolling back the transaction fails */ public function rollBack() { if (!$this->pdo) { throw new Exception('No database connection.'); } try { return $this->pdo->rollBack(); } catch (PDOException $e) { throw new Exception('Failed to rollback transaction: ' . $e->getMessage()); } } } ?>