initital commit

This commit is contained in:
2024-02-16 12:04:59 -06:00
parent 7b980286a9
commit 9275113af9
4 changed files with 274 additions and 0 deletions

17
composer.json Normal file
View File

@@ -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": {}
}

75
src/DatabaseInterface.php Normal file
View File

@@ -0,0 +1,75 @@
<?php
namespace Bcs\Databaseinterface;
/**
* Interface DatabaseInterface
*
* Defines the standard operations for database interactions within the application.
* This interface ensures a consistent API for executing queries, managing transactions,
* and executing stored procedures across different database implementations.
*/
interface DatabaseInterface
{
/**
* Executes a SQL query and returns the result.
*
* @param string $sql The SQL query string to be executed.
* @param array $parameters An associative array of parameters to bind to the SQL query, if any.
* @return array An array representing the result set of the query. For non-select queries, this might be an empty array.
* @throws \Exception Throws an exception if the query execution fails.
*/
public function query(string $sql, array $parameters = []): array;
/**
* Executes a stored procedure by name with optional parameters.
*
* @param string $procedureName The name of the stored procedure to execute.
* @param array $parameters An array of parameters to pass to the stored procedure. The array can be indexed or associative, depending on the database's support for named parameters.
* @return bool Returns true on successful execution of the procedure, false otherwise.
* @throws \Exception Throws an exception if the procedure execution fails or if stored procedures are not supported.
*/
public function executeProcedure(string $procedureName, array $parameters = []): bool;
/**
* Begins a database transaction.
*
* @throws \Exception Throws an exception if initiating a transaction fails.
*/
public function beginTransaction(): void;
/**
* Commits the current transaction, making all database changes permanent.
*
* @throws \Exception Throws an exception if committing the transaction fails.
*/
public function commit(): void;
/**
* Rolls back the current transaction, reverting all changes made during the transaction.
*
* @throws \Exception Throws an exception if rolling back the transaction fails.
*/
public function rollBack(): void;
/**
* 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 An associative array of parameters to bind to the SQL query, if any.
* @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;
/**
* Inserts a new record into the specified table with the provided data.
*
* @param string $table The name of the table to insert the record into.
* @param array $data An associative array of column names and values to insert into the table.
* @return bool Returns true on successful insertion of the record, false otherwise.
* @throws \Exception Throws an exception if the insertion fails.
*/
public function insert(string $table, array $data): bool;
}

89
src/SqlSrvClient.php Normal file
View File

@@ -0,0 +1,89 @@
<?php
namespace Bcs\Databaseinterface;
class SqlSrvClient implements DatabaseInterface
{
protected $connection;
public function __construct(string $serverName, string $database, string $username, string $password)
{
$connectionOptions = [
"Database" => $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);
}
}

93
src/Sqlite3Client.php Normal file
View File

@@ -0,0 +1,93 @@
<?php
namespace Bcs\Databaseinterface;
class Sqlite3Client implements DatabaseInterface
{
protected \SQLite3 $connection;
public function __construct(string $databasePath)
{
$this->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");
}
}