From 9275113af995e76e5586f6ac25eb94372e51fb1b Mon Sep 17 00:00:00 2001 From: Brad Cimbura Date: Fri, 16 Feb 2024 12:04:59 -0600 Subject: [PATCH] initital commit --- composer.json | 17 +++++++ src/DatabaseInterface.php | 75 +++++++++++++++++++++++++++++++ src/SqlSrvClient.php | 89 +++++++++++++++++++++++++++++++++++++ src/Sqlite3Client.php | 93 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 274 insertions(+) create mode 100644 composer.json create mode 100644 src/DatabaseInterface.php create mode 100644 src/SqlSrvClient.php create mode 100644 src/Sqlite3Client.php diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..0f8e8da --- /dev/null +++ b/composer.json @@ -0,0 +1,17 @@ +{ + "name": "bcs/databaseinterface", + "type": "library", + "license": "MIT", + "autoload": { + "psr-4": { + "Bcs\\Databaseinterface\\": "src/" + } + }, + "authors": [ + { + "name": "Brad Cimbura", + "email": "hpz937@gmail.com" + } + ], + "require": {} +} diff --git a/src/DatabaseInterface.php b/src/DatabaseInterface.php new file mode 100644 index 0000000..47e603b --- /dev/null +++ b/src/DatabaseInterface.php @@ -0,0 +1,75 @@ + $database, + "Uid" => $username, + "PWD" => $password, + "TrustServerCertificate" => "true", + ]; + $this->connection = sqlsrv_connect($serverName, $connectionOptions); + + // Check if the connection is successful + if ($this->connection === false) { + throw new \Exception("Failed to connect to the database: " . print_r(sqlsrv_errors(), true)); + } + } + + private function fetchResults($stmt): array + { + $rows = []; + while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) { + $rows[] = $row; + } + return $rows; + } + + public function query(string $sql, array $parameters = []): array + { + $stmt = sqlsrv_prepare($this->connection, $sql, $parameters); + + if (!sqlsrv_execute($stmt)) { + throw new \Exception("Query failed: " . print_r(sqlsrv_errors(), true)); + } + + $rows = $this->fetchResults($stmt); + sqlsrv_free_stmt($stmt); // Freeing the statement is important to prevent resource leaks. + + return $rows; + } + + public function executeProcedure(string $procedureName, array $parameters = []): bool + { + $sql = "EXEC $procedureName " . implode(', ', array_map(fn($p) => '?', $parameters)); + $stmt = sqlsrv_prepare($this->connection, $sql, array_values($parameters)); + + return sqlsrv_execute($stmt); + } + + public function beginTransaction(): void + { + sqlsrv_begin_transaction($this->connection); + } + + public function commit(): void + { + sqlsrv_commit($this->connection); + } + + public function rollBack(): void + { + sqlsrv_rollback($this->connection); + } + + public function execute(string $sql, array $parameters): bool + { + $stmt = sqlsrv_prepare($this->connection, $sql, $parameters); + + return sqlsrv_execute($stmt); + } + + public function insert(string $table, array $data): bool + { + $columns = implode(', ', array_keys($data)); + $values = implode(', ', array_map(fn($v) => '?', $data)); + $sql = "INSERT INTO $table ($columns) VALUES ($values)"; + + $stmt = sqlsrv_prepare($this->connection, $sql, array_values($data)); + + return sqlsrv_execute($stmt); + } +} + diff --git a/src/Sqlite3Client.php b/src/Sqlite3Client.php new file mode 100644 index 0000000..aad8f30 --- /dev/null +++ b/src/Sqlite3Client.php @@ -0,0 +1,93 @@ +connection = new \SQLite3($databasePath); + } + + private function fetchResults(\SQLite3Result $result): array + { + $rows = []; + while ($row = $result->fetchArray(SQLITE3_ASSOC)) { + $rows[] = $row; + } + return $rows; + } + + public function query(string $sql, array $parameters = []): array + { + $statement = $this->connection->prepare($sql); + + foreach ($parameters as $name => $value) { + $statement->bindValue(':' . $name, $value); + } + + $result = $statement->execute(); + if (!$result) { + throw new \Exception("Query failed: " . $this->connection->lastErrorMsg()); + } + + $rows = $this->fetchResults($result); + $result->finalize(); // It's important to finalize the statement to free the resource. + + return $rows; + } + + public function executeProcedure(string $procedureName, array $parameters = []): bool + { + // SQLite3 does not support stored procedures in the same way as SQL Server, + // so this method might not be applicable. + throw new \Exception("Stored procedures are not supported by SQLite3."); + } + + public function beginTransaction(): void + { + $this->connection->exec('BEGIN TRANSACTION'); + } + + public function commit(): void + { + $this->connection->exec('COMMIT'); + } + + public function rollBack(): void + { + $this->connection->exec('ROLLBACK'); + } + + /** + * Executes a SQL query that does not return a result set, such as an INSERT, UPDATE, DELETE, or other action query. + * + * @param string $sql The SQL query string to be executed. + * @param array $parameters the paramenters variable is not used for SQLite3 + * @return bool Returns true on successful execution of the query, false otherwise. + * @throws \Exception Throws an exception if the query execution fails. + */ + public function execute(string $sql, array $parameters = []): bool + { + $statement = $this->connection->prepare($sql); + + foreach ($parameters as $name => $value) { + $statement->bindValue(':' . $name, $value); + } + + $result = $statement->execute(); + if ($result === false) { + throw new \Exception("Error executing SQL: " . $this->connection->lastErrorMsg()); + } + + return true; // Since it's an action query, no need to return $result + } + + public function insert(string $table, array $data): bool + { + throw new \Exception("Not implemented yet"); + } +} +