Compare commits
3 commits
bf7977f511
...
f137dfaab5
Author | SHA1 | Date | |
---|---|---|---|
f137dfaab5 | |||
010045b14a | |||
0dbe21683a |
33 changed files with 307 additions and 332 deletions
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
0.2410.182054
|
0.2410.191515
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
// ArrayCacheProvider.php
|
// ArrayCacheProvider.php
|
||||||
// Created: 2024-04-10
|
// Created: 2024-04-10
|
||||||
// Updated: 2024-10-02
|
// Updated: 2024-10-19
|
||||||
|
|
||||||
namespace Index\Cache\ArrayCache;
|
namespace Index\Cache\ArrayCache;
|
||||||
|
|
||||||
|
@ -74,6 +74,4 @@ class ArrayCacheProvider implements CacheProvider {
|
||||||
public function decrement(string $key, int $amount = 1): int {
|
public function decrement(string $key, int $amount = 1): int {
|
||||||
return $this->increment($key, $amount * -1);
|
return $this->increment($key, $amount * -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function close(): void {}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,14 @@
|
||||||
<?php
|
<?php
|
||||||
// CacheProvider.php
|
// CacheProvider.php
|
||||||
// Created: 2024-04-10
|
// Created: 2024-04-10
|
||||||
// Updated: 2024-10-02
|
// Updated: 2024-10-19
|
||||||
|
|
||||||
namespace Index\Cache;
|
namespace Index\Cache;
|
||||||
|
|
||||||
use Index\Closeable;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a cache provider.
|
* Represents a cache provider.
|
||||||
*/
|
*/
|
||||||
interface CacheProvider extends Closeable {
|
interface CacheProvider {
|
||||||
/**
|
/**
|
||||||
* Retrieve an item from the cache.
|
* Retrieve an item from the cache.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
// MemcachedProvider.php
|
// MemcachedProvider.php
|
||||||
// Created: 2024-04-10
|
// Created: 2024-04-10
|
||||||
// Updated: 2024-10-02
|
// Updated: 2024-10-19
|
||||||
|
|
||||||
namespace Index\Cache\Memcached;
|
namespace Index\Cache\Memcached;
|
||||||
|
|
||||||
|
@ -19,9 +19,4 @@ abstract class MemcachedProvider implements CacheProvider {
|
||||||
public abstract function touch(string $key, int $ttl = 0): void;
|
public abstract function touch(string $key, int $ttl = 0): void;
|
||||||
public abstract function increment(string $key, int $amount = 1): int;
|
public abstract function increment(string $key, int $amount = 1): int;
|
||||||
public abstract function decrement(string $key, int $amount = 1): int;
|
public abstract function decrement(string $key, int $amount = 1): int;
|
||||||
public abstract function close(): void;
|
|
||||||
|
|
||||||
public function __destruct() {
|
|
||||||
$this->close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
// MemcachedProviderLegacy.php
|
// MemcachedProviderLegacy.php
|
||||||
// Created: 2024-04-10
|
// Created: 2024-04-10
|
||||||
// Updated: 2024-10-02
|
// Updated: 2024-10-19
|
||||||
|
|
||||||
namespace Index\Cache\Memcached;
|
namespace Index\Cache\Memcached;
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ class MemcachedProviderLegacy extends MemcachedProvider {
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function close(): void {
|
public function __destruct() {
|
||||||
if(!$this->persistent)
|
if(!$this->persistent)
|
||||||
$this->memcache->close();
|
$this->memcache->close();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
// MemcachedProviderModern.php
|
// MemcachedProviderModern.php
|
||||||
// Created: 2024-04-10
|
// Created: 2024-04-10
|
||||||
// Updated: 2024-10-02
|
// Updated: 2024-10-19
|
||||||
|
|
||||||
namespace Index\Cache\Memcached;
|
namespace Index\Cache\Memcached;
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@ class MemcachedProviderModern extends MemcachedProvider {
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function close(): void {
|
public function __destruct() {
|
||||||
if(!$this->memcached->isPersistent())
|
if(!$this->memcached->isPersistent())
|
||||||
$this->memcached->quit();
|
$this->memcached->quit();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
// ValkeyProvider.php
|
// ValkeyProvider.php
|
||||||
// Created: 2024-04-10
|
// Created: 2024-04-10
|
||||||
// Updated: 2024-10-02
|
// Updated: 2024-10-19
|
||||||
|
|
||||||
namespace Index\Cache\Valkey;
|
namespace Index\Cache\Valkey;
|
||||||
|
|
||||||
|
@ -72,12 +72,8 @@ class ValkeyProvider implements CacheProvider {
|
||||||
return is_int($result) ? $result : 0;
|
return is_int($result) ? $result : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function close(): void {
|
public function __destruct() {
|
||||||
if(!$this->persist)
|
if(!$this->persist)
|
||||||
$this->redis->close();
|
$this->redis->close();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __destruct() {
|
|
||||||
$this->close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
<?php
|
|
||||||
// Closeable.php
|
|
||||||
// Created: 2021-04-30
|
|
||||||
// Updated: 2024-10-02
|
|
||||||
|
|
||||||
namespace Index;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides an interface for releasing unmanaged resources.
|
|
||||||
*
|
|
||||||
* If Closeable is implemented __destruct() should also be added to the class and should call close in it:
|
|
||||||
*
|
|
||||||
* <code>
|
|
||||||
* public function close(): void {
|
|
||||||
* fclose($this->resource);
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* public function __destruct() {
|
|
||||||
* $this->close();
|
|
||||||
* }
|
|
||||||
* </code>
|
|
||||||
*
|
|
||||||
* However if close() is only implemented because a parent interface requires it, the __destruct() implementation may be omitted.
|
|
||||||
*/
|
|
||||||
interface Closeable {
|
|
||||||
/**
|
|
||||||
* Free, release or reset unmanaged resources.
|
|
||||||
*/
|
|
||||||
function close(): void;
|
|
||||||
}
|
|
|
@ -1,16 +1,16 @@
|
||||||
<?php
|
<?php
|
||||||
// DbConnection.php
|
// DbConnection.php
|
||||||
// Created: 2021-04-30
|
// Created: 2021-04-30
|
||||||
// Updated: 2024-10-04
|
// Updated: 2024-10-19
|
||||||
|
|
||||||
namespace Index\Db;
|
namespace Index\Db;
|
||||||
|
|
||||||
use Index\Closeable;
|
use RuntimeException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a connection to a database service.
|
* Represents a connection to a database service.
|
||||||
*/
|
*/
|
||||||
interface DbConnection extends Closeable {
|
interface DbConnection {
|
||||||
/**
|
/**
|
||||||
* Returns the ID of the last inserted row.
|
* Returns the ID of the last inserted row.
|
||||||
*
|
*
|
||||||
|
@ -53,4 +53,11 @@ interface DbConnection extends Closeable {
|
||||||
* @return int|string Number of rows affected by the query.
|
* @return int|string Number of rows affected by the query.
|
||||||
*/
|
*/
|
||||||
function execute(string $query): int|string;
|
function execute(string $query): int|string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Begins a transaction.
|
||||||
|
*
|
||||||
|
* @throws RuntimeException If beginning the transaction failed.
|
||||||
|
*/
|
||||||
|
function beginTransaction(): DbTransaction;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,14 @@
|
||||||
<?php
|
<?php
|
||||||
// DbResult.php
|
// DbResult.php
|
||||||
// Created: 2021-05-02
|
// Created: 2021-05-02
|
||||||
// Updated: 2024-10-04
|
// Updated: 2024-10-19
|
||||||
|
|
||||||
namespace Index\Db;
|
namespace Index\Db;
|
||||||
|
|
||||||
use Index\Closeable;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a database result set.
|
* Represents a database result set.
|
||||||
*/
|
*/
|
||||||
interface DbResult extends Closeable {
|
interface DbResult {
|
||||||
/**
|
/**
|
||||||
* Fetches the next result set.
|
* Fetches the next result set.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,18 +1,17 @@
|
||||||
<?php
|
<?php
|
||||||
// DbStatement.php
|
// DbStatement.php
|
||||||
// Created: 2021-05-02
|
// Created: 2021-05-02
|
||||||
// Updated: 2024-10-04
|
// Updated: 2024-10-19
|
||||||
|
|
||||||
namespace Index\Db;
|
namespace Index\Db;
|
||||||
|
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
use RuntimeException;
|
use RuntimeException;
|
||||||
use Index\Closeable;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a prepared database statement.
|
* Represents a prepared database statement.
|
||||||
*/
|
*/
|
||||||
interface DbStatement extends Closeable {
|
interface DbStatement {
|
||||||
/**
|
/**
|
||||||
* Returns how many parameters there are.
|
* Returns how many parameters there are.
|
||||||
*
|
*
|
||||||
|
@ -25,7 +24,7 @@ interface DbStatement extends Closeable {
|
||||||
*
|
*
|
||||||
* @param int $ordinal Index of the target parameter.
|
* @param int $ordinal Index of the target parameter.
|
||||||
* @param mixed $value Value to assign to the parameter.
|
* @param mixed $value Value to assign to the parameter.
|
||||||
* @param int $type Type of the value, if left to DbType::AUTO DbTools::detectType will be used on $value.
|
* @param int $type Type of the value, if left to DbType::AUTO DbType::detect will be used on $value.
|
||||||
* @throws InvalidArgumentException If $ordinal exceeds bounds.
|
* @throws InvalidArgumentException If $ordinal exceeds bounds.
|
||||||
*/
|
*/
|
||||||
function addParameter(int $ordinal, mixed $value, int $type = DbType::AUTO): void;
|
function addParameter(int $ordinal, mixed $value, int $type = DbType::AUTO): void;
|
||||||
|
@ -37,7 +36,7 @@ interface DbStatement extends Closeable {
|
||||||
* Overwriting lower ordinals than the current cursor should be fine, but your mileage may vary.
|
* Overwriting lower ordinals than the current cursor should be fine, but your mileage may vary.
|
||||||
*
|
*
|
||||||
* @param mixed $value Value to assign to the parameter.
|
* @param mixed $value Value to assign to the parameter.
|
||||||
* @param int $type Type of the value, if left to DbType::AUTO DbTools::detectType will be used on $value.
|
* @param int $type Type of the value, if left to DbType::AUTO DbType::detect will be used on $value.
|
||||||
* @throws RuntimeException If all parameters have already been specified.
|
* @throws RuntimeException If all parameters have already been specified.
|
||||||
*/
|
*/
|
||||||
function nextParameter(mixed $value, int $type = DbType::AUTO): void;
|
function nextParameter(mixed $value, int $type = DbType::AUTO): void;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
// DbStatementCache.php
|
// DbStatementCache.php
|
||||||
// Created: 2023-07-21
|
// Created: 2023-07-21
|
||||||
// Updated: 2024-10-04
|
// Updated: 2024-10-19
|
||||||
|
|
||||||
namespace Index\Db;
|
namespace Index\Db;
|
||||||
|
|
||||||
|
@ -54,8 +54,6 @@ class DbStatementCache {
|
||||||
* Closes all statement instances and resets the cache.
|
* Closes all statement instances and resets the cache.
|
||||||
*/
|
*/
|
||||||
public function clear(): void {
|
public function clear(): void {
|
||||||
foreach($this->stmts as $stmt)
|
|
||||||
$stmt->close();
|
|
||||||
$this->stmts = [];
|
$this->stmts = [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
// DbTools.php
|
// DbTools.php
|
||||||
// Created: 2021-05-02
|
// Created: 2021-05-02
|
||||||
// Updated: 2024-10-16
|
// Updated: 2024-10-19
|
||||||
|
|
||||||
namespace Index\Db;
|
namespace Index\Db;
|
||||||
|
|
||||||
|
@ -11,46 +11,6 @@ use Countable;
|
||||||
* Common database actions.
|
* Common database actions.
|
||||||
*/
|
*/
|
||||||
final class DbTools {
|
final class DbTools {
|
||||||
/**
|
|
||||||
* Transaction wrapper.
|
|
||||||
*
|
|
||||||
* Takes a database connection with transaction support and a callable that may return a boolean based on the success of the actions.
|
|
||||||
* If the callable returns nothing, nothing will happen.
|
|
||||||
* If the callable returns true, commit will be called.
|
|
||||||
* If the callable returns false, rollback will be called.
|
|
||||||
*
|
|
||||||
* @param DbTransactions $connection A database connection with transaction support.
|
|
||||||
* @param callable $callable A callable that handles the transaction, may return a bool.
|
|
||||||
*/
|
|
||||||
public static function transaction(DbTransactions $connection, callable $callable): void {
|
|
||||||
$connection->beginTransaction();
|
|
||||||
$result = $callable($connection) ?? null;
|
|
||||||
if(is_bool($result)) {
|
|
||||||
if($result)
|
|
||||||
$connection->commit();
|
|
||||||
else
|
|
||||||
$connection->rollback();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Detects the DbType of the passed argument. Should be used for DbType::AUTO.
|
|
||||||
*
|
|
||||||
* @param mixed $value A value of unknown type.
|
|
||||||
* @return int DbType of the value passed in the argument.
|
|
||||||
*/
|
|
||||||
public static function detectType(mixed $value): int {
|
|
||||||
if(is_null($value))
|
|
||||||
return DbType::NULL;
|
|
||||||
if(is_float($value))
|
|
||||||
return DbType::FLOAT;
|
|
||||||
if(is_int($value))
|
|
||||||
return DbType::INTEGER;
|
|
||||||
if(is_resource($value))
|
|
||||||
return DbType::BLOB;
|
|
||||||
return DbType::STRING;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a partial query for prepared statements of lists.
|
* Constructs a partial query for prepared statements of lists.
|
||||||
*
|
*
|
||||||
|
|
46
src/Db/DbTransaction.php
Normal file
46
src/Db/DbTransaction.php
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
<?php
|
||||||
|
// DbTransaction.php
|
||||||
|
// Created: 2024-10-19
|
||||||
|
// Updated: 2024-10-19
|
||||||
|
|
||||||
|
namespace Index\Db;
|
||||||
|
|
||||||
|
use RuntimeException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a transaction to be performed on the database.
|
||||||
|
*/
|
||||||
|
interface DbTransaction {
|
||||||
|
/**
|
||||||
|
* Commits the actions done during a transaction and ends the transaction.
|
||||||
|
* A new transaction will be started if auto-commit is disabled.
|
||||||
|
*
|
||||||
|
* @throws RuntimeException If the commit failed.
|
||||||
|
*/
|
||||||
|
function commit(): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a save point in the transaction that can be rolled back to.
|
||||||
|
*
|
||||||
|
* @param string $name Name for the save point.
|
||||||
|
* @throws RuntimeException If save point creation failed.
|
||||||
|
*/
|
||||||
|
function save(string $name): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Releases a specified save point.
|
||||||
|
*
|
||||||
|
* @param string $name Name of the save point.
|
||||||
|
* @throws RuntimeException If save points are not supported by this implementation.
|
||||||
|
*/
|
||||||
|
function release(string $name): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rolls back to the state before a transaction start or to a specified save point.
|
||||||
|
*
|
||||||
|
* @param ?string $name Name of the save point, null for the entire transaction.
|
||||||
|
* @throws RuntimeException If rollback failed.
|
||||||
|
* @throws RuntimeException If save points are not supported by this implementation and $name was non-null.
|
||||||
|
*/
|
||||||
|
function rollback(?string $name = null): void;
|
||||||
|
}
|
|
@ -1,57 +0,0 @@
|
||||||
<?php
|
|
||||||
// DbTransactions.php
|
|
||||||
// Created: 2021-05-02
|
|
||||||
// Updated: 2024-10-04
|
|
||||||
|
|
||||||
namespace Index\Db;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates supports for transactions in a database connection.
|
|
||||||
*/
|
|
||||||
interface DbTransactions extends DbConnection {
|
|
||||||
/**
|
|
||||||
* Sets whether changes should be applied immediately or whether commit should always be called first.
|
|
||||||
*
|
|
||||||
* @param bool $state true if things should automatically be committed, false if not.
|
|
||||||
*/
|
|
||||||
function setAutoCommit(bool $state): void;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enters a transaction.
|
|
||||||
*
|
|
||||||
* @throws \RuntimeException If the creation of the transaction failed.
|
|
||||||
*/
|
|
||||||
function beginTransaction(): void;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Commits the actions done during a transaction and ends the transaction.
|
|
||||||
* A new transaction will be started if auto-commit is disabled.
|
|
||||||
*
|
|
||||||
* @throws \RuntimeException If the commit failed.
|
|
||||||
*/
|
|
||||||
function commit(): void;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Rolls back to the state before a transaction start or to a specified save point.
|
|
||||||
*
|
|
||||||
* @param ?string $name Name of the save point, null for the entire transaction.
|
|
||||||
* @throws \RuntimeException If rollback failed.
|
|
||||||
*/
|
|
||||||
function rollback(?string $name = null): void;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a save point in the transaction that can be rolled back to.
|
|
||||||
*
|
|
||||||
* @param string $name Name for the save point.
|
|
||||||
* @throws \RuntimeException If save point creation failed.
|
|
||||||
*/
|
|
||||||
function savePoint(string $name): void;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Releases a save point.
|
|
||||||
*
|
|
||||||
* @param string $name Name of the save point.
|
|
||||||
* @throws \RuntimeException If releasing the save point failed.
|
|
||||||
*/
|
|
||||||
function releaseSavePoint(string $name): void;
|
|
||||||
}
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
// DbType.php
|
// DbType.php
|
||||||
// Created: 2021-05-02
|
// Created: 2021-05-02
|
||||||
// Updated: 2024-10-04
|
// Updated: 2024-10-19
|
||||||
|
|
||||||
namespace Index\Db;
|
namespace Index\Db;
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ namespace Index\Db;
|
||||||
*/
|
*/
|
||||||
final class DbType {
|
final class DbType {
|
||||||
/**
|
/**
|
||||||
* Automatically detect the type. Should be used in combination with DbTools::detectType.
|
* Automatically detect the type. Should be used in combination with DbType::detect.
|
||||||
*
|
*
|
||||||
* @var int
|
* @var int
|
||||||
*/
|
*/
|
||||||
|
@ -50,4 +50,22 @@ final class DbType {
|
||||||
* @var int
|
* @var int
|
||||||
*/
|
*/
|
||||||
public const BLOB = 5;
|
public const BLOB = 5;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detects the DbType of the passed argument. Should be used for DbType::AUTO.
|
||||||
|
*
|
||||||
|
* @param mixed $value A value of unknown type.
|
||||||
|
* @return int DbType of the value passed in the argument.
|
||||||
|
*/
|
||||||
|
public static function detect(mixed $value): int {
|
||||||
|
if(is_null($value))
|
||||||
|
return self::NULL;
|
||||||
|
if(is_float($value))
|
||||||
|
return self::FLOAT;
|
||||||
|
if(is_int($value))
|
||||||
|
return self::INTEGER;
|
||||||
|
if(is_resource($value))
|
||||||
|
return self::BLOB;
|
||||||
|
return self::STRING;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
// MariaDbConnection.php
|
// MariaDbConnection.php
|
||||||
// Created: 2021-04-30
|
// Created: 2021-04-30
|
||||||
// Updated: 2024-10-04
|
// Updated: 2024-10-19
|
||||||
|
|
||||||
namespace Index\Db\MariaDb;
|
namespace Index\Db\MariaDb;
|
||||||
|
|
||||||
|
@ -10,12 +10,12 @@ use mysqli_sql_exception;
|
||||||
use stdClass;
|
use stdClass;
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
use RuntimeException;
|
use RuntimeException;
|
||||||
use Index\Db\{DbConnection,DbTransactions};
|
use Index\Db\{DbConnection,DbTransaction};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a connection with a MariaDB or MySQL database server.
|
* Represents a connection with a MariaDB or MySQL database server.
|
||||||
*/
|
*/
|
||||||
class MariaDbConnection implements DbConnection, DbTransactions {
|
class MariaDbConnection implements DbConnection {
|
||||||
/**
|
/**
|
||||||
* Refresh grant tables.
|
* Refresh grant tables.
|
||||||
*
|
*
|
||||||
|
@ -144,6 +144,8 @@ class MariaDbConnection implements DbConnection, DbTransactions {
|
||||||
} catch(mysqli_sql_exception $ex) {
|
} catch(mysqli_sql_exception $ex) {
|
||||||
throw new RuntimeException($ex->getMessage(), $ex->getCode(), $ex);
|
throw new RuntimeException($ex->getMessage(), $ex->getCode(), $ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->connection->autocommit(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getAffectedRows(): int|string {
|
public function getAffectedRows(): int|string {
|
||||||
|
@ -189,7 +191,7 @@ class MariaDbConnection implements DbConnection, DbTransactions {
|
||||||
*/
|
*/
|
||||||
public function switchUser(string $userName, string $password, string|null $database = null): void {
|
public function switchUser(string $userName, string $password, string|null $database = null): void {
|
||||||
if(!$this->connection->change_user($userName, $password, $database === null ? null : $database))
|
if(!$this->connection->change_user($userName, $password, $database === null ? null : $database))
|
||||||
throw new RuntimeException($this->getLastErrorString(), $this->getLastErrorCode());
|
$this->throwLastError();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -200,7 +202,7 @@ class MariaDbConnection implements DbConnection, DbTransactions {
|
||||||
*/
|
*/
|
||||||
public function switchDatabase(string $database): void {
|
public function switchDatabase(string $database): void {
|
||||||
if(!$this->connection->select_db($database))
|
if(!$this->connection->select_db($database))
|
||||||
throw new RuntimeException($this->getLastErrorString(), $this->getLastErrorCode());
|
$this->throwLastError();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -230,6 +232,15 @@ class MariaDbConnection implements DbConnection, DbTransactions {
|
||||||
return $this->connection->error;
|
return $this->connection->error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Throws the last error as a RuntimeException.
|
||||||
|
*
|
||||||
|
* @throws RuntimeException Based on the last error code and string.
|
||||||
|
*/
|
||||||
|
public function throwLastError(): never {
|
||||||
|
throw new RuntimeException((string)$this->getLastErrorString(), $this->getLastErrorCode());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the current SQL State of the connection.
|
* Gets the current SQL State of the connection.
|
||||||
*
|
*
|
||||||
|
@ -302,33 +313,11 @@ class MariaDbConnection implements DbConnection, DbTransactions {
|
||||||
$this->connection->refresh($flags);
|
$this->connection->refresh($flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setAutoCommit(bool $state): void {
|
public function beginTransaction(): DbTransaction {
|
||||||
$this->connection->autocommit($state);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function beginTransaction(): void {
|
|
||||||
if(!$this->connection->begin_transaction())
|
if(!$this->connection->begin_transaction())
|
||||||
throw new RuntimeException((string)$this->getLastErrorString(), $this->getLastErrorCode());
|
$this->throwLastError();
|
||||||
}
|
|
||||||
|
|
||||||
public function commit(): void {
|
return new MariaDbTransaction($this, $this->connection);
|
||||||
if(!$this->connection->commit())
|
|
||||||
throw new RuntimeException((string)$this->getLastErrorString(), $this->getLastErrorCode());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function rollback(?string $name = null): void {
|
|
||||||
if(!$this->connection->rollback(0, $name))
|
|
||||||
throw new RuntimeException((string)$this->getLastErrorString(), $this->getLastErrorCode());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function savePoint(string $name): void {
|
|
||||||
if(!$this->connection->savepoint($name))
|
|
||||||
throw new RuntimeException((string)$this->getLastErrorString(), $this->getLastErrorCode());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function releaseSavePoint(string $name): void {
|
|
||||||
if(!$this->connection->release_savepoint($name))
|
|
||||||
throw new RuntimeException((string)$this->getLastErrorString(), $this->getLastErrorCode());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -360,7 +349,7 @@ class MariaDbConnection implements DbConnection, DbTransactions {
|
||||||
throw new RuntimeException($ex->getMessage(), $ex->getCode(), $ex);
|
throw new RuntimeException($ex->getMessage(), $ex->getCode(), $ex);
|
||||||
}
|
}
|
||||||
if($statement === false)
|
if($statement === false)
|
||||||
throw new RuntimeException($this->getLastErrorString(), $this->getLastErrorCode());
|
$this->throwLastError();
|
||||||
return new MariaDbStatement($statement);
|
return new MariaDbStatement($statement);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -375,7 +364,7 @@ class MariaDbConnection implements DbConnection, DbTransactions {
|
||||||
}
|
}
|
||||||
|
|
||||||
if($result === false)
|
if($result === false)
|
||||||
throw new RuntimeException($this->getLastErrorString(), $this->getLastErrorCode());
|
$this->throwLastError();
|
||||||
|
|
||||||
// the mysql library is very adorable
|
// the mysql library is very adorable
|
||||||
if($result === true)
|
if($result === true)
|
||||||
|
@ -388,7 +377,7 @@ class MariaDbConnection implements DbConnection, DbTransactions {
|
||||||
public function execute(string $query): int|string {
|
public function execute(string $query): int|string {
|
||||||
try {
|
try {
|
||||||
if(!$this->connection->real_query($query))
|
if(!$this->connection->real_query($query))
|
||||||
throw new RuntimeException($this->getLastErrorString(), $this->getLastErrorCode());
|
$this->throwLastError();
|
||||||
} catch(mysqli_sql_exception $ex) {
|
} catch(mysqli_sql_exception $ex) {
|
||||||
throw new RuntimeException($ex->getMessage(), $ex->getCode(), $ex);
|
throw new RuntimeException($ex->getMessage(), $ex->getCode(), $ex);
|
||||||
}
|
}
|
||||||
|
@ -398,16 +387,9 @@ class MariaDbConnection implements DbConnection, DbTransactions {
|
||||||
/**
|
/**
|
||||||
* Closes the connection and associated resources.
|
* Closes the connection and associated resources.
|
||||||
*/
|
*/
|
||||||
public function close(): void {
|
public function __destruct() {
|
||||||
try {
|
try {
|
||||||
$this->connection->close();
|
$this->connection->close();
|
||||||
} catch(\Error $ex) {}
|
} catch(\Error $ex) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Closes the connection and associated resources.
|
|
||||||
*/
|
|
||||||
public function __destruct() {
|
|
||||||
$this->close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
<?php
|
<?php
|
||||||
// MariaDbParameter.php
|
// MariaDbParameter.php
|
||||||
// Created: 2021-05-02
|
// Created: 2021-05-02
|
||||||
// Updated: 2024-10-04
|
// Updated: 2024-10-19
|
||||||
|
|
||||||
namespace Index\Db\MariaDb;
|
namespace Index\Db\MariaDb;
|
||||||
|
|
||||||
use Index\Db\{DbTools,DbType};
|
use Index\Db\DbType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a bound parameter.
|
* Represents a bound parameter.
|
||||||
|
@ -25,7 +25,7 @@ class MariaDbParameter {
|
||||||
private mixed $value
|
private mixed $value
|
||||||
) {
|
) {
|
||||||
if($type == DbType::AUTO)
|
if($type == DbType::AUTO)
|
||||||
$type = DbTools::detectType($value);
|
$type = DbType::detect($value);
|
||||||
if($type === DbType::NULL)
|
if($type === DbType::NULL)
|
||||||
$value = null;
|
$value = null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
// MariaDbResult.php
|
// MariaDbResult.php
|
||||||
// Created: 2021-05-02
|
// Created: 2021-05-02
|
||||||
// Updated: 2024-10-04
|
// Updated: 2024-10-19
|
||||||
|
|
||||||
namespace Index\Db\MariaDb;
|
namespace Index\Db\MariaDb;
|
||||||
|
|
||||||
|
@ -66,10 +66,4 @@ abstract class MariaDbResult implements DbResult {
|
||||||
public function getValue(int|string $index): mixed {
|
public function getValue(int|string $index): mixed {
|
||||||
return $this->currentRow[$index] ?? null;
|
return $this->currentRow[$index] ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract function close(): void;
|
|
||||||
|
|
||||||
public function __destruct() {
|
|
||||||
$this->close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
// MariaDbResultLib.php
|
// MariaDbResultLib.php
|
||||||
// Created: 2021-05-02
|
// Created: 2021-05-02
|
||||||
// Updated: 2024-10-04
|
// Updated: 2024-10-19
|
||||||
|
|
||||||
namespace Index\Db\MariaDb;
|
namespace Index\Db\MariaDb;
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ class MariaDbResultLib extends MariaDbResult {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function close(): void {
|
public function __destruct() {
|
||||||
try {
|
try {
|
||||||
$this->result->free_result();
|
$this->result->free_result();
|
||||||
} catch(\Error $ex) {}
|
} catch(\Error $ex) {}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
// MariaDbResultNative.php
|
// MariaDbResultNative.php
|
||||||
// Created: 2021-05-02
|
// Created: 2021-05-02
|
||||||
// Updated: 2024-10-04
|
// Updated: 2024-10-19
|
||||||
|
|
||||||
namespace Index\Db\MariaDb;
|
namespace Index\Db\MariaDb;
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ class MariaDbResultNative extends MariaDbResult {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function close(): void {
|
public function __destruct() {
|
||||||
try {
|
try {
|
||||||
$this->result->close();
|
$this->result->close();
|
||||||
} catch(\Error $ex) {}
|
} catch(\Error $ex) {}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
// MariaDbStatement.php
|
// MariaDbStatement.php
|
||||||
// Created: 2021-05-02
|
// Created: 2021-05-02
|
||||||
// Updated: 2024-10-04
|
// Updated: 2024-10-19
|
||||||
|
|
||||||
namespace Index\Db\MariaDb;
|
namespace Index\Db\MariaDb;
|
||||||
|
|
||||||
|
@ -159,12 +159,8 @@ class MariaDbStatement implements DbStatement {
|
||||||
throw new RuntimeException($this->getLastErrorString(), $this->getLastErrorCode());
|
throw new RuntimeException($this->getLastErrorString(), $this->getLastErrorCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function close(): void {
|
|
||||||
$this->statement->close();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function __destruct() {
|
public function __destruct() {
|
||||||
$this->close();
|
$this->statement->close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
43
src/Db/MariaDb/MariaDbTransaction.php
Normal file
43
src/Db/MariaDb/MariaDbTransaction.php
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
<?php
|
||||||
|
// MariaDbTransaction.php
|
||||||
|
// Created: 2024-10-19
|
||||||
|
// Updated: 2024-10-19
|
||||||
|
|
||||||
|
namespace Index\Db\MariaDb;
|
||||||
|
|
||||||
|
use mysqli;
|
||||||
|
use Index\Db\DbTransaction;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a MariaDB transaction.
|
||||||
|
*/
|
||||||
|
class MariaDbTransaction implements DbTransaction {
|
||||||
|
/**
|
||||||
|
* @param MariaDbConnection $conn Underlying connection
|
||||||
|
* @param mysqli $connRaw Underlying connection (off vocal)
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
private MariaDbConnection $conn,
|
||||||
|
private mysqli $connRaw
|
||||||
|
) {}
|
||||||
|
|
||||||
|
public function commit(): void {
|
||||||
|
if(!$this->connRaw->commit())
|
||||||
|
$this->conn->throwLastError();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function save(string $name): void {
|
||||||
|
if(!$this->connRaw->savepoint($name))
|
||||||
|
$this->conn->throwLastError();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function release(string $name): void {
|
||||||
|
if(!$this->connRaw->release_savepoint($name))
|
||||||
|
$this->conn->throwLastError();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function rollback(?string $name = null): void {
|
||||||
|
if(!$this->connRaw->rollback(0, $name))
|
||||||
|
$this->conn->throwLastError();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,11 +1,11 @@
|
||||||
<?php
|
<?php
|
||||||
// NullDbConnection.php
|
// NullDbConnection.php
|
||||||
// Created: 2021-05-02
|
// Created: 2021-05-02
|
||||||
// Updated: 2024-10-04
|
// Updated: 2024-10-19
|
||||||
|
|
||||||
namespace Index\Db\NullDb;
|
namespace Index\Db\NullDb;
|
||||||
|
|
||||||
use Index\Db\{DbConnection,DbStatement,DbResult};
|
use Index\Db\{DbConnection,DbResult,DbStatement,DbTransaction};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a dummy database connection.
|
* Represents a dummy database connection.
|
||||||
|
@ -31,5 +31,7 @@ class NullDbConnection implements DbConnection {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function close(): void {}
|
public function beginTransaction(): DbTransaction {
|
||||||
|
return new NullDbTransaction;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
// NullDbResult.php
|
// NullDbResult.php
|
||||||
// Created: 2021-05-02
|
// Created: 2021-05-02
|
||||||
// Updated: 2024-10-04
|
// Updated: 2024-10-19
|
||||||
|
|
||||||
namespace Index\Db\NullDb;
|
namespace Index\Db\NullDb;
|
||||||
|
|
||||||
|
@ -58,6 +58,4 @@ class NullDbResult implements DbResult {
|
||||||
public function getIterator(callable $construct): DbResultIterator {
|
public function getIterator(callable $construct): DbResultIterator {
|
||||||
return new DbResultIterator($this, $construct);
|
return new DbResultIterator($this, $construct);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function close(): void {}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
// NullDbStatement.php
|
// NullDbStatement.php
|
||||||
// Created: 2021-05-02
|
// Created: 2021-05-02
|
||||||
// Updated: 2024-10-04
|
// Updated: 2024-10-19
|
||||||
|
|
||||||
namespace Index\Db\NullDb;
|
namespace Index\Db\NullDb;
|
||||||
|
|
||||||
|
@ -32,6 +32,4 @@ class NullDbStatement implements DbStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function reset(): void {}
|
public function reset(): void {}
|
||||||
|
|
||||||
public function close(): void {}
|
|
||||||
}
|
}
|
||||||
|
|
20
src/Db/NullDb/NullDbTransaction.php
Normal file
20
src/Db/NullDb/NullDbTransaction.php
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
<?php
|
||||||
|
// NullDbTransaction.php
|
||||||
|
// Created: 2024-10-19
|
||||||
|
// Updated: 2024-10-19
|
||||||
|
|
||||||
|
namespace Index\Db\NullDb;
|
||||||
|
|
||||||
|
use Index\Db\{DbConnection,DbTransaction};
|
||||||
|
/**
|
||||||
|
* Represents a dummy database transaction.
|
||||||
|
*/
|
||||||
|
class NullDbTransaction implements DbTransaction {
|
||||||
|
public function commit(): void {}
|
||||||
|
|
||||||
|
public function save(string $name): void {}
|
||||||
|
|
||||||
|
public function release(string $name): void {}
|
||||||
|
|
||||||
|
public function rollback(?string $name = null): void {}
|
||||||
|
}
|
|
@ -1,18 +1,18 @@
|
||||||
<?php
|
<?php
|
||||||
// SqliteConnection.php
|
// SqliteConnection.php
|
||||||
// Created: 2021-05-02
|
// Created: 2021-05-02
|
||||||
// Updated: 2024-10-04
|
// Updated: 2024-10-19
|
||||||
|
|
||||||
namespace Index\Db\Sqlite;
|
namespace Index\Db\Sqlite;
|
||||||
|
|
||||||
use RuntimeException;
|
use RuntimeException;
|
||||||
use SQLite3;
|
use SQLite3;
|
||||||
use Index\Db\{DbConnection,DbTransactions,DbStatement,DbResult};
|
use Index\Db\{DbConnection,DbResult,DbStatement,DbTransaction};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a client for an SQLite database.
|
* Represents a client for an SQLite database.
|
||||||
*/
|
*/
|
||||||
class SqliteConnection implements DbConnection, DbTransactions {
|
class SqliteConnection implements DbConnection {
|
||||||
/**
|
/**
|
||||||
* CREATE INDEX authorizer.
|
* CREATE INDEX authorizer.
|
||||||
*
|
*
|
||||||
|
@ -352,7 +352,6 @@ class SqliteConnection implements DbConnection, DbTransactions {
|
||||||
public const IGNORE = SQLite3::IGNORE;
|
public const IGNORE = SQLite3::IGNORE;
|
||||||
|
|
||||||
private SQLite3 $connection;
|
private SQLite3 $connection;
|
||||||
private bool $autoCommit = true;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new SQLite client.
|
* Creates a new SQLite client.
|
||||||
|
@ -456,6 +455,15 @@ class SqliteConnection implements DbConnection, DbTransactions {
|
||||||
return $this->connection->lastErrorCode();
|
return $this->connection->lastErrorCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Throws the last error as a RuntimeException.
|
||||||
|
*
|
||||||
|
* @throws RuntimeException Based on the last error code and string.
|
||||||
|
*/
|
||||||
|
public function throwLastError(): never {
|
||||||
|
throw new RuntimeException((string)$this->getLastErrorString(), $this->getLastErrorCode());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens a BLOB field as a resource.
|
* Opens a BLOB field as a resource.
|
||||||
*
|
*
|
||||||
|
@ -468,7 +476,7 @@ class SqliteConnection implements DbConnection, DbTransactions {
|
||||||
public function getBlobStream(string $table, string $column, int $rowId): mixed {
|
public function getBlobStream(string $table, string $column, int $rowId): mixed {
|
||||||
$handle = $this->connection->openBlob($table, $column, $rowId);
|
$handle = $this->connection->openBlob($table, $column, $rowId);
|
||||||
if(!is_resource($handle))
|
if(!is_resource($handle))
|
||||||
throw new RuntimeException((string)$this->getLastErrorString(), $this->getLastErrorCode());
|
$this->throwLastError();
|
||||||
|
|
||||||
return $handle;
|
return $handle;
|
||||||
}
|
}
|
||||||
|
@ -480,73 +488,45 @@ class SqliteConnection implements DbConnection, DbTransactions {
|
||||||
public function prepare(string $query): DbStatement {
|
public function prepare(string $query): DbStatement {
|
||||||
$statement = $this->connection->prepare($query);
|
$statement = $this->connection->prepare($query);
|
||||||
if($statement === false)
|
if($statement === false)
|
||||||
throw new RuntimeException((string)$this->getLastErrorString(), $this->getLastErrorCode());
|
$this->throwLastError();
|
||||||
|
|
||||||
return new SqliteStatement($this, $statement);
|
return new SqliteStatement($this, $statement);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function query(string $query): DbResult {
|
public function query(string $query): DbResult {
|
||||||
$result = $this->connection->query($query);
|
$result = $this->connection->query($query);
|
||||||
if($result === false)
|
if($result === false)
|
||||||
throw new RuntimeException($this->getLastErrorString(), $this->getLastErrorCode());
|
$this->throwLastError();
|
||||||
|
|
||||||
return new SqliteResult($result);
|
return new SqliteResult($result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tries to execute a query but throws an exception if it fails.
|
||||||
|
*
|
||||||
|
* @param string $query Command to execute.
|
||||||
|
* @throws RuntimeException If the command failed to execute.
|
||||||
|
*/
|
||||||
|
public function executeThrow(string $query): void {
|
||||||
|
if(!$this->connection->exec($query))
|
||||||
|
$this->throwLastError();
|
||||||
|
}
|
||||||
|
|
||||||
public function execute(string $query): int|string {
|
public function execute(string $query): int|string {
|
||||||
if(!$this->connection->exec($query))
|
if(!$this->connection->exec($query))
|
||||||
throw new RuntimeException($this->getLastErrorString(), $this->getLastErrorCode());
|
$this->throwLastError();
|
||||||
|
|
||||||
return $this->connection->changes();
|
return $this->connection->changes();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setAutoCommit(bool $state): void {
|
public function beginTransaction(): DbTransaction {
|
||||||
// there's not really a completely reliable way to set a persistent auto commit disable state
|
|
||||||
if($state === $this->autoCommit)
|
|
||||||
return;
|
|
||||||
$this->autoCommit = $state;
|
|
||||||
|
|
||||||
if($state) {
|
|
||||||
$this->commit();
|
|
||||||
} else {
|
|
||||||
$this->beginTransaction();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function beginTransaction(): void {
|
|
||||||
if(!$this->connection->exec('BEGIN;'))
|
if(!$this->connection->exec('BEGIN;'))
|
||||||
throw new RuntimeException((string)$this->getLastErrorString(), $this->getLastErrorCode());
|
$this->throwLastError();
|
||||||
|
|
||||||
|
return new SqliteTransaction($this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function commit(): void {
|
public function __destruct() {
|
||||||
if(!$this->connection->exec('COMMIT;'))
|
|
||||||
throw new RuntimeException((string)$this->getLastErrorString(), $this->getLastErrorCode());
|
|
||||||
if(!$this->autoCommit)
|
|
||||||
$this->beginTransaction();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function rollback(?string $name = null): void {
|
|
||||||
if(!$this->connection->exec(empty($name) ? 'ROLLBACK;' : "ROLLBACK TO {$name};"))
|
|
||||||
throw new RuntimeException((string)$this->getLastErrorString(), $this->getLastErrorCode());
|
|
||||||
if(!$this->autoCommit)
|
|
||||||
$this->beginTransaction();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function savePoint(string $name): void {
|
|
||||||
if(!$this->connection->exec("SAVEPOINT {$name};"))
|
|
||||||
throw new RuntimeException((string)$this->getLastErrorString(), $this->getLastErrorCode());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function releaseSavePoint(string $name): void {
|
|
||||||
if(!$this->connection->exec("RELEASE SAVEPOINT {$name};"))
|
|
||||||
throw new RuntimeException((string)$this->getLastErrorString(), $this->getLastErrorCode());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function close(): void {
|
|
||||||
$this->connection->close();
|
$this->connection->close();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Closes the connection and associated resources.
|
|
||||||
*/
|
|
||||||
public function __destruct() {
|
|
||||||
$this->close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
// SqliteResult.php
|
// SqliteResult.php
|
||||||
// Created: 2021-05-02
|
// Created: 2021-05-02
|
||||||
// Updated: 2024-10-04
|
// Updated: 2024-10-19
|
||||||
|
|
||||||
namespace Index\Db\Sqlite;
|
namespace Index\Db\Sqlite;
|
||||||
|
|
||||||
|
@ -52,6 +52,4 @@ class SqliteResult implements DbResult {
|
||||||
public function getValue(int|string $index): mixed {
|
public function getValue(int|string $index): mixed {
|
||||||
return $this->currentRow[$index] ?? null;
|
return $this->currentRow[$index] ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function close(): void {}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
// SqliteStatement.php
|
// SqliteStatement.php
|
||||||
// Created: 2021-05-02
|
// Created: 2021-05-02
|
||||||
// Updated: 2024-10-04
|
// Updated: 2024-10-19
|
||||||
|
|
||||||
namespace Index\Db\Sqlite;
|
namespace Index\Db\Sqlite;
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ use SQLite3Result;
|
||||||
use SQLite3Stmt;
|
use SQLite3Stmt;
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
use RuntimeException;
|
use RuntimeException;
|
||||||
use Index\Db\{DbTools,DbType,DbStatement,DbResult};
|
use Index\Db\{DbType,DbStatement,DbResult};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a prepared SQLite SQL statement.
|
* Represents a prepared SQLite SQL statement.
|
||||||
|
@ -47,7 +47,7 @@ class SqliteStatement implements DbStatement {
|
||||||
|
|
||||||
private function bindParameter(int $ordinal, mixed $value, int $type): void {
|
private function bindParameter(int $ordinal, mixed $value, int $type): void {
|
||||||
if($type === DbType::AUTO)
|
if($type === DbType::AUTO)
|
||||||
$type = DbTools::detectType($value);
|
$type = DbType::detect($value);
|
||||||
if($type === DbType::NULL)
|
if($type === DbType::NULL)
|
||||||
$value = null;
|
$value = null;
|
||||||
|
|
||||||
|
@ -99,6 +99,4 @@ class SqliteStatement implements DbStatement {
|
||||||
if(!$this->statement->reset())
|
if(!$this->statement->reset())
|
||||||
throw new RuntimeException((string)$this->connection->getLastErrorString(), $this->connection->getLastErrorCode());
|
throw new RuntimeException((string)$this->connection->getLastErrorString(), $this->connection->getLastErrorCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function close(): void {}
|
|
||||||
}
|
}
|
||||||
|
|
41
src/Db/Sqlite/SqliteTransaction.php
Normal file
41
src/Db/Sqlite/SqliteTransaction.php
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
<?php
|
||||||
|
// SqliteTransaction.php
|
||||||
|
// Created: 2024-10-19
|
||||||
|
// Updated: 2024-10-19
|
||||||
|
|
||||||
|
namespace Index\Db\Sqlite;
|
||||||
|
|
||||||
|
use SQLite3;
|
||||||
|
use Index\Db\DbTransaction;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an SQLite transaction.
|
||||||
|
*/
|
||||||
|
class SqliteTransaction implements DbTransaction {
|
||||||
|
/**
|
||||||
|
* @param SqliteConnection $conn Underlying connection.
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
private SqliteConnection $conn
|
||||||
|
) {}
|
||||||
|
|
||||||
|
public function commit(): void {
|
||||||
|
$this->conn->executeThrow('COMMIT;');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function save(string $name): void {
|
||||||
|
$this->conn->executeThrow(sprintf('SAVEPOINT %s;', SQLite3::escapeString($name)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function release(string $name): void {
|
||||||
|
$this->conn->executeThrow(sprintf('RELEASE SAVEPOINT %s;', SQLite3::escapeString($name)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function rollback(?string $name = null): void {
|
||||||
|
$this->conn->executeThrow(
|
||||||
|
$name === null
|
||||||
|
? 'ROLLBACK;'
|
||||||
|
: sprintf('ROLLBACK TO SAVEPOINT %s;', SQLite3::escapeString($name))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,30 +0,0 @@
|
||||||
<?php
|
|
||||||
// DbToolsTest.php
|
|
||||||
// Created: 2021-04-28
|
|
||||||
// Updated: 2024-10-16
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
|
||||||
use PHPUnit\Framework\Attributes\CoversClass;
|
|
||||||
use Index\Db\{DbTools,DbType};
|
|
||||||
|
|
||||||
#[CoversClass(DbTools::class)]
|
|
||||||
#[CoversClass(DbType::class)]
|
|
||||||
final class DbToolsTest extends TestCase {
|
|
||||||
public function testDetectType(): void {
|
|
||||||
$this->assertEquals(DbType::NULL, DbTools::detectType(null));
|
|
||||||
$this->assertEquals(DbType::INTEGER, DbTools::detectType(12345));
|
|
||||||
$this->assertEquals(DbType::FLOAT, DbTools::detectType(123.45));
|
|
||||||
$this->assertEquals(DbType::STRING, DbTools::detectType('This is a string.'));
|
|
||||||
|
|
||||||
$blob = fopen('php://memory', 'r+b');
|
|
||||||
if($blob === false)
|
|
||||||
throw new RuntimeException('failed to fopen a memory stream');
|
|
||||||
|
|
||||||
fwrite($blob, 'This is a string inside a memory stream.');
|
|
||||||
fseek($blob, 0);
|
|
||||||
|
|
||||||
$this->assertEquals(DbType::BLOB, DbTools::detectType($blob));
|
|
||||||
}
|
|
||||||
}
|
|
29
tests/DbTypeTest.php
Normal file
29
tests/DbTypeTest.php
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
<?php
|
||||||
|
// DbTypeTest.php
|
||||||
|
// Created: 2021-04-28
|
||||||
|
// Updated: 2024-10-19
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use PHPUnit\Framework\Attributes\CoversClass;
|
||||||
|
use Index\Db\DbType;
|
||||||
|
|
||||||
|
#[CoversClass(DbType::class)]
|
||||||
|
final class DbTypeTest extends TestCase {
|
||||||
|
public function testDetectType(): void {
|
||||||
|
$this->assertEquals(DbType::NULL, DbType::detect(null));
|
||||||
|
$this->assertEquals(DbType::INTEGER, DbType::detect(12345));
|
||||||
|
$this->assertEquals(DbType::FLOAT, DbType::detect(123.45));
|
||||||
|
$this->assertEquals(DbType::STRING, DbType::detect('This is a string.'));
|
||||||
|
|
||||||
|
$blob = fopen('php://memory', 'r+b');
|
||||||
|
if($blob === false)
|
||||||
|
throw new RuntimeException('failed to fopen a memory stream');
|
||||||
|
|
||||||
|
fwrite($blob, 'This is a string inside a memory stream.');
|
||||||
|
fseek($blob, 0);
|
||||||
|
|
||||||
|
$this->assertEquals(DbType::BLOB, DbType::detect($blob));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue