MAPG-43 initial classes for DB handling
This commit is contained in:
1 parent
b821d4a045
commit
17c0ec73df
10 files changed
+881
No files matched your search
@@ -0,0 +1,114 @@
|
||||
<?php namespace MapGuesser\Database\Mysql;
|
||||
|
||||
use MapGuesser\Interfaces\Database\IConnection;
|
||||
use MapGuesser\Interfaces\Database\IResultSet;
|
||||
use MapGuesser\Interfaces\Database\IStatement;
|
||||
use mysqli;
|
||||
|
||||
class Connection implements IConnection
|
||||
{
|
||||
private mysqli $connection;
|
||||
|
||||
public function __construct(string $host, string $user, string $password, string $db, int $port = -1, string $socket = null)
|
||||
{
|
||||
if ($port < 0) {
|
||||
$port = ini_get('mysqli.default_port');
|
||||
}
|
||||
|
||||
if ($socket === null) {
|
||||
$socket = ini_get('mysqli.default_socket');
|
||||
}
|
||||
|
||||
$this->connection = new mysqli($host, $user, $password, $db, $port, $socket);
|
||||
|
||||
if ($this->connection->connect_error) {
|
||||
throw new \Exception('Connection failed: ' . $this->connection->connect_error);
|
||||
}
|
||||
|
||||
if (!$this->connection->set_charset('utf8mb4')) {
|
||||
throw new \Exception($this->connection->error);
|
||||
}
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
$this->connection->close();
|
||||
}
|
||||
|
||||
public function startTransaction(): void
|
||||
{
|
||||
if (!$this->connection->autocommit(false)) {
|
||||
throw new \Exception($this->connection->error);
|
||||
}
|
||||
}
|
||||
|
||||
public function commit(): void
|
||||
{
|
||||
if (!$this->connection->commit() || !$this->connection->autocommit(true)) {
|
||||
throw new \Exception($this->connection->error);
|
||||
}
|
||||
}
|
||||
|
||||
public function rollback(): void
|
||||
{
|
||||
if (!$this->connection->rollback() || !$this->connection->autocommit(true)) {
|
||||
throw new \Exception($this->connection->error);
|
||||
}
|
||||
}
|
||||
|
||||
public function query(string $query): ?IResultSet
|
||||
{
|
||||
if (!($result = $this->connection->query($query))) {
|
||||
throw new \Exception($this->connection->error . '. Query: ' . $query);
|
||||
}
|
||||
|
||||
if ($result !== true) {
|
||||
return new ResultSet($result);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function multiQuery(string $query): array
|
||||
{
|
||||
if (!$this->connection->multi_query($query)) {
|
||||
throw new \Exception($this->connection->error . '. Query: ' . $query);
|
||||
}
|
||||
|
||||
$ret = [];
|
||||
do {
|
||||
if ($result = $this->connection->store_result()) {
|
||||
$ret[] = new ResultSet($result);
|
||||
} else {
|
||||
$ret[] = null;
|
||||
}
|
||||
|
||||
$this->connection->more_results();
|
||||
} while ($this->connection->next_result());
|
||||
|
||||
if ($this->connection->error) {
|
||||
throw new \Exception($this->connection->error . '. Query: ' . $query);
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function prepare(string $query): IStatement
|
||||
{
|
||||
if (!($stmt = $this->connection->prepare($query))) {
|
||||
throw new \Exception($this->connection->error . '. Query: ' . $query);
|
||||
}
|
||||
|
||||
return new Statement($stmt);
|
||||
}
|
||||
|
||||
public function lastId(): int
|
||||
{
|
||||
return $this->connection->insert_id;
|
||||
}
|
||||
|
||||
public function getAffectedRows(): int
|
||||
{
|
||||
return $this->connection->affected_rows;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
<?php namespace MapGuesser\Database\Mysql;
|
||||
|
||||
use MapGuesser\Interfaces\Database\IResultSet;
|
||||
use mysqli_result;
|
||||
|
||||
class ResultSet implements IResultSet
|
||||
{
|
||||
private mysqli_result $result;
|
||||
|
||||
public function __construct(mysqli_result $result)
|
||||
{
|
||||
$this->result = $result;
|
||||
}
|
||||
|
||||
public function fetch(int $type = IResultSet::FETCH_ASSOC)
|
||||
{
|
||||
return $this->result->fetch_array($this->convertFetchType($type));
|
||||
}
|
||||
|
||||
public function fetchAll(int $type = IResultSet::FETCH_ASSOC)
|
||||
{
|
||||
return $this->result->fetch_all($this->convertFetchType($type));
|
||||
}
|
||||
|
||||
public function fetchOneColumn(string $valueName, string $keyName = null)
|
||||
{
|
||||
$array = [];
|
||||
|
||||
while ($r = $this->fetch(IResultSet::FETCH_ASSOC)) {
|
||||
if (isset($keyName)) {
|
||||
$array[$r[$keyName]] = $r[$valueName];
|
||||
} else {
|
||||
$array[] = $r[$valueName];
|
||||
}
|
||||
}
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
private function convertFetchType(int $type): int
|
||||
{
|
||||
switch ($type) {
|
||||
case IResultSet::FETCH_ASSOC:
|
||||
$internal_type = MYSQLI_ASSOC;
|
||||
break;
|
||||
|
||||
case IResultSet::FETCH_BOTH:
|
||||
$internal_type = MYSQLI_BOTH;
|
||||
break;
|
||||
|
||||
case IResultSet::FETCH_NUM:
|
||||
$internal_type = MYSQLI_NUM;
|
||||
break;
|
||||
|
||||
default:
|
||||
$internal_type = MYSQLI_BOTH;
|
||||
break;
|
||||
}
|
||||
|
||||
return $internal_type;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
<?php namespace MapGuesser\Database\Mysql;
|
||||
|
||||
use MapGuesser\Interfaces\Database\IResultSet;
|
||||
use MapGuesser\Interfaces\Database\IStatement;
|
||||
use mysqli_stmt;
|
||||
|
||||
class Statement implements IStatement
|
||||
{
|
||||
private mysqli_stmt $stmt;
|
||||
|
||||
public function __construct(mysqli_stmt $stmt)
|
||||
{
|
||||
$this->stmt = $stmt;
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
$this->stmt->close();
|
||||
}
|
||||
|
||||
public function execute(array $params = []): ?IResultSet
|
||||
{
|
||||
if ($params) {
|
||||
$ref_params = [''];
|
||||
|
||||
foreach ($params as &$param) {
|
||||
$type = gettype($param);
|
||||
|
||||
switch ($type) {
|
||||
case 'integer':
|
||||
case 'double':
|
||||
case 'string':
|
||||
$t = $type[0];
|
||||
break;
|
||||
|
||||
case 'NULL':
|
||||
$t = 's';
|
||||
break;
|
||||
|
||||
case 'boolean':
|
||||
$param = (string) (int) $param;
|
||||
$t = 's';
|
||||
break;
|
||||
|
||||
case 'array':
|
||||
$param = json_encode($param);
|
||||
$t = 's';
|
||||
break;
|
||||
}
|
||||
|
||||
if (!isset($t)) {
|
||||
throw new \Exception('Data type ' . $type . ' not supported!');
|
||||
}
|
||||
|
||||
$ref_params[] = &$param;
|
||||
$ref_params[0] .= $t;
|
||||
}
|
||||
|
||||
if (!call_user_func_array([$this->stmt, 'bind_param'], $ref_params)) {
|
||||
throw new \Exception($this->stmt->error);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$this->stmt->execute()) {
|
||||
throw new \Exception($this->stmt->error);
|
||||
}
|
||||
|
||||
if ($result_set = $this->stmt->get_result()) {
|
||||
return new ResultSet($result_set);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getAffectedRows(): int
|
||||
{
|
||||
return $this->stmt->affected_rows;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user