HEH HEH YEAH ILIGHT HAHAHAHA WAHHH
This commit is contained in:
parent
3e7d443689
commit
44b4445664
85 changed files with 342 additions and 356 deletions
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
|||
0.2410.20136
|
||||
0.2410.20200
|
||||
|
|
|
@ -59,7 +59,7 @@ final class Bencode {
|
|||
return $output . 'e';
|
||||
|
||||
case 'object':
|
||||
if($value instanceof IBencodeSerializable)
|
||||
if($value instanceof BencodeSerializable)
|
||||
return self::encode($value->bencodeSerialize(), $depth - 1);
|
||||
|
||||
$value = get_object_vars($value);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?php
|
||||
// IBencodeSerialisable.php
|
||||
// BencodeSerializable.php
|
||||
// Created: 2022-01-13
|
||||
// Updated: 2024-10-02
|
||||
|
||||
|
@ -8,7 +8,7 @@ namespace Index\Bencode;
|
|||
/**
|
||||
* Provides an interface for serialising objects for bencoding in a controlled manner.
|
||||
*/
|
||||
interface IBencodeSerializable {
|
||||
interface BencodeSerializable {
|
||||
/**
|
||||
* Gets the data that should represent this object in a Bencode structure.
|
||||
*
|
|
@ -1,5 +1,5 @@
|
|||
<?php
|
||||
// BencodeSerialisableTrait.php
|
||||
// BencodeSerializableTrait.php
|
||||
// Created: 2024-09-29
|
||||
// Updated: 2024-10-02
|
||||
|
|
@ -1,17 +1,17 @@
|
|||
<?php
|
||||
// ArrayCacheBackend.php
|
||||
// Created: 2024-04-10
|
||||
// Updated: 2024-08-03
|
||||
// Updated: 2024-10-02
|
||||
|
||||
namespace Index\Cache\ArrayCache;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Index\Cache\{ICacheBackend,ICacheProvider,ICacheProviderInfo};
|
||||
use Index\Cache\{CacheBackend,CacheProvider,CacheProviderInfo};
|
||||
|
||||
/**
|
||||
* Information about the dummy cache backend.
|
||||
*/
|
||||
class ArrayCacheBackend implements ICacheBackend {
|
||||
class ArrayCacheBackend implements CacheBackend {
|
||||
public function isAvailable(): bool {
|
||||
return true;
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ class ArrayCacheBackend implements ICacheBackend {
|
|||
* @param ArrayCacheProviderInfo $providerInfo Dummy provider info.
|
||||
* @return ArrayCacheProvider Dummy provider instance.
|
||||
*/
|
||||
public function createProvider(ICacheProviderInfo $providerInfo): ICacheProvider {
|
||||
public function createProvider(CacheProviderInfo $providerInfo): CacheProvider {
|
||||
if(!($providerInfo instanceof ArrayCacheProviderInfo))
|
||||
throw new InvalidArgumentException('$providerInfo must by of type ArrayCacheProviderInfo');
|
||||
|
||||
|
@ -37,7 +37,7 @@ class ArrayCacheBackend implements ICacheBackend {
|
|||
* @param string|array<string, string|int> $dsn DSN with provider information.
|
||||
* @return ArrayCacheProviderInfo Dummy provider info instance.
|
||||
*/
|
||||
public function parseDsn(string|array $dsn): ICacheProviderInfo {
|
||||
public function parseDsn(string|array $dsn): CacheProviderInfo {
|
||||
return new ArrayCacheProviderInfo;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
<?php
|
||||
// ArrayCacheProvider.php
|
||||
// Created: 2024-04-10
|
||||
// Updated: 2024-08-04
|
||||
// Updated: 2024-10-02
|
||||
|
||||
namespace Index\Cache\ArrayCache;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Index\Cache\ICacheProvider;
|
||||
use Index\Cache\CacheProvider;
|
||||
|
||||
/**
|
||||
* Represents a dummy cache provider.
|
||||
*/
|
||||
class ArrayCacheProvider implements ICacheProvider {
|
||||
class ArrayCacheProvider implements CacheProvider {
|
||||
/** @var array<string, array{ttl: int, value: string}> */
|
||||
private array $items = [];
|
||||
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
<?php
|
||||
// ArrayCacheProviderInfo.php
|
||||
// Created: 2024-04-10
|
||||
// Updated: 2024-04-10
|
||||
// Updated: 2024-10-02
|
||||
|
||||
namespace Index\Cache\ArrayCache;
|
||||
|
||||
use Index\Cache\ICacheProviderInfo;
|
||||
use Index\Cache\CacheProviderInfo;
|
||||
|
||||
/**
|
||||
* Represents dummy provider info.
|
||||
*/
|
||||
class ArrayCacheProviderInfo implements ICacheProviderInfo {}
|
||||
class ArrayCacheProviderInfo implements CacheProviderInfo {}
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
<?php
|
||||
// ICacheBackend.php
|
||||
// CacheBackend.php
|
||||
// Created: 2024-04-10
|
||||
// Updated: 2024-08-03
|
||||
// Updated: 2024-10-02
|
||||
|
||||
namespace Index\Cache;
|
||||
|
||||
/**
|
||||
* Information about a cache provider. Should not have any external dependencies.
|
||||
*/
|
||||
interface ICacheBackend {
|
||||
interface CacheBackend {
|
||||
/**
|
||||
* Checks whether the driver is available and a provider can be made.
|
||||
*
|
||||
|
@ -19,18 +19,18 @@ interface ICacheBackend {
|
|||
/**
|
||||
* Creates the cache provider described in the argument.
|
||||
*
|
||||
* @param ICacheProviderInfo $providerInfo Object that describes the desired provider.
|
||||
* @throws \InvalidArgumentException An invalid implementation of ICacheProviderInfo was provided.
|
||||
* @param CacheProviderInfo $providerInfo Object that describes the desired provider.
|
||||
* @throws \InvalidArgumentException An invalid implementation of CacheProviderInfo was provided.
|
||||
* @throws \RuntimeException If you ignored the output of isAvailable and tried to create an instance anyway.
|
||||
* @return ICacheProvider The provider described in the provider info.
|
||||
* @return CacheProvider The provider described in the provider info.
|
||||
*/
|
||||
function createProvider(ICacheProviderInfo $providerInfo): ICacheProvider;
|
||||
function createProvider(CacheProviderInfo $providerInfo): CacheProvider;
|
||||
|
||||
/**
|
||||
* Constructs a cache info instance from a dsn.
|
||||
*
|
||||
* @param string|array<string, string|int> $dsn DSN with provider information.
|
||||
* @return ICacheProviderInfo Provider info based on the dsn.
|
||||
* @return CacheProviderInfo Provider info based on the dsn.
|
||||
*/
|
||||
function parseDsn(string|array $dsn): ICacheProviderInfo;
|
||||
function parseDsn(string|array $dsn): CacheProviderInfo;
|
||||
}
|
|
@ -1,16 +1,16 @@
|
|||
<?php
|
||||
// ICacheProvider.php
|
||||
// CacheProvider.php
|
||||
// Created: 2024-04-10
|
||||
// Updated: 2024-04-10
|
||||
// Updated: 2024-10-02
|
||||
|
||||
namespace Index\Cache;
|
||||
|
||||
use Index\ICloseable;
|
||||
use Index\Closeable;
|
||||
|
||||
/**
|
||||
* Represents a cache provider.
|
||||
*/
|
||||
interface ICacheProvider extends ICloseable {
|
||||
interface CacheProvider extends Closeable {
|
||||
/**
|
||||
* Retrieve an item from the cache.
|
||||
*
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
// ICacheProviderInfo.php
|
||||
// CacheProviderInfo.php
|
||||
// Created: 2024-04-10
|
||||
// Updated: 2024-04-10
|
||||
// Updated: 2024-10-02
|
||||
|
||||
namespace Index\Cache;
|
||||
|
||||
|
@ -10,4 +10,4 @@ namespace Index\Cache;
|
|||
*
|
||||
* Any cache backend should have its own implementation of this, there are no baseline requirements.
|
||||
*/
|
||||
interface ICacheProviderInfo {}
|
||||
interface CacheProviderInfo {}
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
// CacheTools.php
|
||||
// Created: 2024-04-10
|
||||
// Updated: 2024-08-04
|
||||
// Updated: 2024-10-02
|
||||
|
||||
namespace Index\Cache;
|
||||
|
||||
|
@ -16,7 +16,7 @@ use RuntimeException;
|
|||
* CacheTools only handles the scheme part of the URL,
|
||||
* the rest of the URL is described in the documentation of the parseDsn implementation of the respective backend.
|
||||
*
|
||||
* The scheme can be a PHP classpath to an implementation of ICacheBackend, or any of these aliases:
|
||||
* The scheme can be a PHP classpath to an implementation of CacheBackend, or any of these aliases:
|
||||
* - `array`, `null`: maps to `ArrayCache\ArrayCacheBackend` or `Index-Cache-ArrayCache-ArrayCacheBackend`, uses a simple array backed cache that doesn't get saved.
|
||||
* - `memcached`, `memcache`: maps to `Memcached\MemcachedBackend` or `Index-Cache-Memcached-MemcachedBackend`, provides a backend based on the memcached or memcache extension.
|
||||
* - `valkey`, `keydb`, `redis`: maps to `Valkey\ValkeyBackend` or `Index-Cache-Valkey-ValkeyBackend`, provides a backend based on the phpredis extension.
|
||||
|
@ -43,7 +43,7 @@ final class CacheTools {
|
|||
}
|
||||
|
||||
/** @param array<string, int|string> $uri */
|
||||
private static function resolveBackend(array $uri): ICacheBackend {
|
||||
private static function resolveBackend(array $uri): CacheBackend {
|
||||
static $backends = null;
|
||||
if(!is_array($backends))
|
||||
$backends = [];
|
||||
|
@ -51,7 +51,7 @@ final class CacheTools {
|
|||
$scheme = $uri['scheme'];
|
||||
$backend = $backends[$scheme] ?? null;
|
||||
|
||||
if(!($backend instanceof ICacheBackend)) {
|
||||
if(!($backend instanceof CacheBackend)) {
|
||||
$backend = null;
|
||||
|
||||
if(array_key_exists($scheme, self::CACHE_PROTOS))
|
||||
|
@ -59,7 +59,7 @@ final class CacheTools {
|
|||
else
|
||||
$name = str_replace('-', '\\', (string)$scheme);
|
||||
|
||||
if(class_exists($name) && is_subclass_of($name, ICacheBackend::class)) {
|
||||
if(class_exists($name) && is_subclass_of($name, CacheBackend::class)) {
|
||||
$backend = new $name;
|
||||
$name = get_class($backend);
|
||||
}
|
||||
|
@ -83,9 +83,9 @@ final class CacheTools {
|
|||
* @param string $dsn URL to create cache provider from.
|
||||
* @throws InvalidArgumentException if $dsn is not a valid URL.
|
||||
* @throws RuntimeException if no cache provider can be made using the URL.
|
||||
* @return ICacheBackend Cache backend instance.
|
||||
* @return CacheBackend Cache backend instance.
|
||||
*/
|
||||
public static function backend(string $dsn): ICacheBackend {
|
||||
public static function backend(string $dsn): CacheBackend {
|
||||
return self::resolveBackend(self::parseDsnUri($dsn));
|
||||
}
|
||||
|
||||
|
@ -97,9 +97,9 @@ final class CacheTools {
|
|||
* @param string $dsn URL to create cache provider from.
|
||||
* @throws InvalidArgumentException if $dsn is not a valid URL.
|
||||
* @throws RuntimeException if no cache provider can be made using the URL.
|
||||
* @return ICacheProviderInfo Cache provider info.
|
||||
* @return CacheProviderInfo Cache provider info.
|
||||
*/
|
||||
public static function parse(string $dsn): ICacheProviderInfo {
|
||||
public static function parse(string $dsn): CacheProviderInfo {
|
||||
$uri = self::parseDsnUri($dsn);
|
||||
return self::resolveBackend($uri)->parseDsn($uri);
|
||||
}
|
||||
|
@ -112,9 +112,9 @@ final class CacheTools {
|
|||
* @param string $dsn URL to create cache provider from.
|
||||
* @throws InvalidArgumentException if $dsn is not a valid URL.
|
||||
* @throws RuntimeException if no cache provider can be made using the URL.
|
||||
* @return ICacheProvider A cache provider.
|
||||
* @return CacheProvider A cache provider.
|
||||
*/
|
||||
public static function create(string $dsn): ICacheProvider {
|
||||
public static function create(string $dsn): CacheProvider {
|
||||
$uri = self::parseDsnUri($dsn);
|
||||
$backend = self::resolveBackend($uri);
|
||||
return $backend->createProvider($backend->parseDsn($uri));
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
<?php
|
||||
// MemcachedBackend.php
|
||||
// Created: 2024-04-10
|
||||
// Updated: 2024-08-04
|
||||
// Updated: 2024-10-02
|
||||
|
||||
namespace Index\Cache\Memcached;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use RuntimeException;
|
||||
use Index\Cache\{ICacheBackend,ICacheProvider,ICacheProviderInfo};
|
||||
use Index\Cache\{CacheBackend,CacheProvider,CacheProviderInfo};
|
||||
use Index\Net\{EndPoint,UnixEndPoint};
|
||||
|
||||
/**
|
||||
* Information about the memcached backend.
|
||||
*/
|
||||
class MemcachedBackend implements ICacheBackend {
|
||||
class MemcachedBackend implements CacheBackend {
|
||||
public function isAvailable(): bool {
|
||||
return extension_loaded('memcached')
|
||||
|| extension_loaded('memcache');
|
||||
|
@ -28,7 +28,7 @@ class MemcachedBackend implements ICacheBackend {
|
|||
* @param MemcachedProviderInfo $providerInfo Memcached provider info.
|
||||
* @return MemcachedProvider Memcached provider instance.
|
||||
*/
|
||||
public function createProvider(ICacheProviderInfo $providerInfo): ICacheProvider {
|
||||
public function createProvider(CacheProviderInfo $providerInfo): CacheProvider {
|
||||
if(!($providerInfo instanceof MemcachedProviderInfo))
|
||||
throw new InvalidArgumentException('$providerInfo must by of type MemcachedProviderInfo');
|
||||
|
||||
|
@ -74,7 +74,7 @@ class MemcachedBackend implements ICacheBackend {
|
|||
* @param string|array<string, string|int> $dsn DSN with provider information.
|
||||
* @return MemcachedProviderInfo Memcached provider info instance.
|
||||
*/
|
||||
public function parseDsn(string|array $dsn): ICacheProviderInfo {
|
||||
public function parseDsn(string|array $dsn): CacheProviderInfo {
|
||||
if(is_string($dsn)) {
|
||||
$dsn = parse_url($dsn);
|
||||
if($dsn === false)
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
<?php
|
||||
// MemcachedProvider.php
|
||||
// Created: 2024-04-10
|
||||
// Updated: 2024-04-10
|
||||
// Updated: 2024-10-02
|
||||
|
||||
namespace Index\Cache\Memcached;
|
||||
|
||||
use Index\Cache\ICacheProvider;
|
||||
use Index\Cache\CacheProvider;
|
||||
|
||||
/**
|
||||
* Base Memcached provider implementation.
|
||||
*/
|
||||
abstract class MemcachedProvider implements ICacheProvider {
|
||||
abstract class MemcachedProvider implements CacheProvider {
|
||||
public const MAX_TTL = 30 * 24 * 60 * 60;
|
||||
|
||||
public abstract function get(string $key): mixed;
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
<?php
|
||||
// MemcachedProviderInfo.php
|
||||
// Created: 2024-04-10
|
||||
// Updated: 2024-08-03
|
||||
// Updated: 2024-10-02
|
||||
|
||||
namespace Index\Cache\Memcached;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Index\Cache\ICacheProviderInfo;
|
||||
use Index\Cache\CacheProviderInfo;
|
||||
use Index\Net\EndPoint;
|
||||
|
||||
/**
|
||||
* Represents Memcached provider info.
|
||||
*/
|
||||
class MemcachedProviderInfo implements ICacheProviderInfo {
|
||||
class MemcachedProviderInfo implements CacheProviderInfo {
|
||||
/**
|
||||
* @param array<int, array{EndPoint, int}> $endPoints Memcached end points.
|
||||
* @param string $prefixKey Prefix to apply to keys.
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
<?php
|
||||
// ValkeyBackend.php
|
||||
// Created: 2024-04-10
|
||||
// Updated: 2024-08-03
|
||||
// Updated: 2024-10-02
|
||||
|
||||
namespace Index\Cache\Valkey;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use RuntimeException;
|
||||
use Index\Cache\{ICacheBackend,ICacheProvider,ICacheProviderInfo};
|
||||
use Index\Cache\{CacheBackend,CacheProvider,CacheProviderInfo};
|
||||
use Index\Net\{EndPoint,UnixEndPoint};
|
||||
|
||||
/**
|
||||
|
@ -15,7 +15,7 @@ use Index\Net\{EndPoint,UnixEndPoint};
|
|||
*
|
||||
* Also compatible with Redis and KeyDB.
|
||||
*/
|
||||
class ValkeyBackend implements ICacheBackend {
|
||||
class ValkeyBackend implements CacheBackend {
|
||||
public function isAvailable(): bool {
|
||||
return extension_loaded('redis');
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ class ValkeyBackend implements ICacheBackend {
|
|||
* @param ValkeyProviderInfo $providerInfo Valkey provider info.
|
||||
* @return ValkeyProvider Valkey provider instance.
|
||||
*/
|
||||
public function createProvider(ICacheProviderInfo $providerInfo): ICacheProvider {
|
||||
public function createProvider(CacheProviderInfo $providerInfo): CacheProvider {
|
||||
if(!($providerInfo instanceof ValkeyProviderInfo))
|
||||
throw new InvalidArgumentException('$providerInfo must by of type ValkeyProviderInfo');
|
||||
|
||||
|
@ -55,7 +55,7 @@ class ValkeyBackend implements ICacheBackend {
|
|||
* @param string|array<string, int|string> $dsn DSN with provider information.
|
||||
* @return ValkeyProviderInfo Valkey provider info instance.
|
||||
*/
|
||||
public function parseDsn(string|array $dsn): ICacheProviderInfo {
|
||||
public function parseDsn(string|array $dsn): CacheProviderInfo {
|
||||
if(is_string($dsn)) {
|
||||
$dsn = parse_url($dsn);
|
||||
if($dsn === false)
|
||||
|
|
|
@ -7,13 +7,13 @@ namespace Index\Cache\Valkey;
|
|||
|
||||
use InvalidArgumentException;
|
||||
use Redis;
|
||||
use Index\Cache\ICacheProvider;
|
||||
use Index\Cache\CacheProvider;
|
||||
use Index\Net\{DnsEndPoint,UnixEndPoint};
|
||||
|
||||
/**
|
||||
* Valkey provider implementation.
|
||||
*/
|
||||
class ValkeyProvider implements ICacheProvider {
|
||||
class ValkeyProvider implements CacheProvider {
|
||||
private Redis $redis;
|
||||
private bool $persist;
|
||||
|
||||
|
|
|
@ -7,13 +7,13 @@ namespace Index\Cache\Valkey;
|
|||
|
||||
use InvalidArgumentException;
|
||||
use RuntimeException;
|
||||
use Index\Cache\ICacheProviderInfo;
|
||||
use Index\Cache\CacheProviderInfo;
|
||||
use Index\Net\{DnsEndPoint,EndPoint,IpEndPoint,UnixEndPoint};
|
||||
|
||||
/**
|
||||
* Represents Valkey provider info.
|
||||
*/
|
||||
class ValkeyProviderInfo implements ICacheProviderInfo {
|
||||
class ValkeyProviderInfo implements CacheProviderInfo {
|
||||
public function __construct(
|
||||
private EndPoint $endPoint,
|
||||
private string $prefix,
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
<?php
|
||||
// ICloseable.php
|
||||
// Closeable.php
|
||||
// Created: 2021-04-30
|
||||
// Updated: 2021-05-12
|
||||
// Updated: 2024-10-02
|
||||
|
||||
namespace Index;
|
||||
|
||||
/**
|
||||
* Provides an interface for releasing unmanaged resources.
|
||||
*
|
||||
* If ICloseable is implemented __destruct() should also be added to the class and should call close in it:
|
||||
* If Closeable is implemented __destruct() should also be added to the class and should call close in it:
|
||||
*
|
||||
* <code>
|
||||
* public function close(): void {
|
||||
|
@ -22,7 +22,7 @@ namespace Index;
|
|||
*
|
||||
* However if close() is only implemented because a parent interface requires it, the __destruct() implementation may be omitted.
|
||||
*/
|
||||
interface ICloseable {
|
||||
interface Closeable {
|
||||
/**
|
||||
* Free, release or reset unmanaged resources.
|
||||
*/
|
|
@ -1,14 +1,14 @@
|
|||
<?php
|
||||
// IComparable.php
|
||||
// Comparable.php
|
||||
// Created: 2021-04-30
|
||||
// Updated: 2021-05-12
|
||||
// Updated: 2024-10-02
|
||||
|
||||
namespace Index;
|
||||
|
||||
/**
|
||||
* Provides an interface for comparison between objects. Allows for order/sorting instances.
|
||||
*/
|
||||
interface IComparable {
|
||||
interface Comparable {
|
||||
/**
|
||||
* Compares the current instance with another and returns an integer that indicates whether
|
||||
* the current object comes before or after or the same position and the other object.
|
|
@ -1,14 +1,14 @@
|
|||
<?php
|
||||
// IDbBackend.php
|
||||
// DbBackend.php
|
||||
// Created: 2021-04-30
|
||||
// Updated: 2024-08-03
|
||||
// Updated: 2024-10-02
|
||||
|
||||
namespace Index\Data;
|
||||
|
||||
/**
|
||||
* Information about a database layer. Should not have any external dependencies.
|
||||
*/
|
||||
interface IDbBackend {
|
||||
interface DbBackend {
|
||||
/**
|
||||
* Checks whether the driver is available and a connection can be made.
|
||||
*
|
||||
|
@ -19,17 +19,17 @@ interface IDbBackend {
|
|||
/**
|
||||
* Creates a connection with the database described in the argument.
|
||||
*
|
||||
* @param IDbConnectionInfo $connectionInfo Object that describes the desired connection.
|
||||
* @throws \InvalidArgumentException An invalid implementation of IDbConnectionInfo was provided.
|
||||
* @return IDbConnection A connection described in the connection info.
|
||||
* @param DbConnectionInfo $connectionInfo Object that describes the desired connection.
|
||||
* @throws \InvalidArgumentException An invalid implementation of DbConnectionInfo was provided.
|
||||
* @return DbConnection A connection described in the connection info.
|
||||
*/
|
||||
function createConnection(IDbConnectionInfo $connectionInfo): IDbConnection;
|
||||
function createConnection(DbConnectionInfo $connectionInfo): DbConnection;
|
||||
|
||||
/**
|
||||
* Constructs a connection info instance from a dsn.
|
||||
*
|
||||
* @param string|array<string, int|string> $dsn DSN with connection information.
|
||||
* @return IDbConnectionInfo Connection info based on the dsn.
|
||||
* @return DbConnectionInfo Connection info based on the dsn.
|
||||
*/
|
||||
function parseDsn(string|array $dsn): IDbConnectionInfo;
|
||||
function parseDsn(string|array $dsn): DbConnectionInfo;
|
||||
}
|
|
@ -1,16 +1,16 @@
|
|||
<?php
|
||||
// IDbConnection.php
|
||||
// DbConnection.php
|
||||
// Created: 2021-04-30
|
||||
// Updated: 2024-09-13
|
||||
// Updated: 2024-10-02
|
||||
|
||||
namespace Index\Data;
|
||||
|
||||
use Index\ICloseable;
|
||||
use Index\Closeable;
|
||||
|
||||
/**
|
||||
* Represents a connection to a database service.
|
||||
*/
|
||||
interface IDbConnection extends ICloseable {
|
||||
interface DbConnection extends Closeable {
|
||||
/**
|
||||
* Returns the ID of the last inserted row.
|
||||
*
|
||||
|
@ -31,17 +31,17 @@ interface IDbConnection extends ICloseable {
|
|||
* The statement should use question mark (?) parameters.
|
||||
*
|
||||
* @param string $query SQL query to prepare.
|
||||
* @return IDbStatement An instance of an implementation of IDbStatement.
|
||||
* @return DbStatement An instance of an implementation of DbStatement.
|
||||
*/
|
||||
function prepare(string $query): IDbStatement;
|
||||
function prepare(string $query): DbStatement;
|
||||
|
||||
/**
|
||||
* Executes a statement and returns a database result instance.
|
||||
*
|
||||
* @param string $query SQL query to execute.
|
||||
* @return IDbResult An instance of an implementation of IDbResult
|
||||
* @return DbResult An instance of an implementation of DbResult
|
||||
*/
|
||||
function query(string $query): IDbResult;
|
||||
function query(string $query): DbResult;
|
||||
|
||||
/**
|
||||
* Executes a statement and returns how many rows are affected.
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
// IDbConnectionInfo.php
|
||||
// DbConnectionInfo.php
|
||||
// Created: 2021-04-30
|
||||
// Updated: 2022-02-16
|
||||
// Updated: 2024-10-02
|
||||
|
||||
namespace Index\Data;
|
||||
|
||||
|
@ -10,4 +10,4 @@ namespace Index\Data;
|
|||
*
|
||||
* Any database backend should have its own implementation of this, there are no baseline requirements.
|
||||
*/
|
||||
interface IDbConnectionInfo {}
|
||||
interface DbConnectionInfo {}
|
|
@ -1,17 +1,17 @@
|
|||
<?php
|
||||
// IDbResult.php
|
||||
// DbResult.php
|
||||
// Created: 2021-05-02
|
||||
// Updated: 2024-10-02
|
||||
|
||||
namespace Index\Data;
|
||||
|
||||
use Index\ICloseable;
|
||||
use Index\Closeable;
|
||||
use Index\Io\Stream;
|
||||
|
||||
/**
|
||||
* Represents a database result set.
|
||||
*/
|
||||
interface IDbResult extends ICloseable {
|
||||
interface DbResult extends Closeable {
|
||||
/**
|
||||
* Fetches the next result set.
|
||||
*
|
||||
|
@ -110,7 +110,7 @@ interface IDbResult extends ICloseable {
|
|||
/**
|
||||
* Creates an iterator for this result.
|
||||
*
|
||||
* @param callable(IDbResult): object $construct Result info constructor.
|
||||
* @param callable(DbResult): object $construct Result info constructor.
|
||||
* @return DbResultIterator Result iterator.
|
||||
*/
|
||||
function getIterator(callable $construct): DbResultIterator;
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
// DbResultIterator.php
|
||||
// Created: 2024-02-06
|
||||
// Updated: 2024-08-04
|
||||
// Updated: 2024-10-02
|
||||
|
||||
namespace Index\Data;
|
||||
|
||||
|
@ -9,7 +9,7 @@ use InvalidArgumentException;
|
|||
use Iterator;
|
||||
|
||||
/**
|
||||
* Implements an iterator and constructor wrapper for IDbResult.
|
||||
* Implements an iterator and constructor wrapper for DbResult.
|
||||
*
|
||||
* @implements Iterator<int, object>
|
||||
*/
|
||||
|
@ -18,13 +18,13 @@ class DbResultIterator implements Iterator {
|
|||
private object $current;
|
||||
|
||||
/**
|
||||
* Call this through an IDbResult instance instead!
|
||||
* Call this through an DbResult instance instead!
|
||||
*
|
||||
* @param IDbResult $result Result to operate on.
|
||||
* @param callable(IDbResult): object $construct Constructor callback.
|
||||
* @param DbResult $result Result to operate on.
|
||||
* @param callable(DbResult): object $construct Constructor callback.
|
||||
*/
|
||||
public function __construct(
|
||||
private IDbResult $result,
|
||||
private DbResult $result,
|
||||
private $construct
|
||||
) {
|
||||
if(!is_callable($construct))
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
<?php
|
||||
// DbResultTrait.php
|
||||
// Created: 2023-11-09
|
||||
// Updated: 2024-08-03
|
||||
// Updated: 2024-10-02
|
||||
|
||||
namespace Index\Data;
|
||||
|
||||
/**
|
||||
* Implements common IDbResult methods.
|
||||
* Implements common DbResult methods.
|
||||
*/
|
||||
trait DbResultTrait {
|
||||
public function getString(int|string $index): string {
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
<?php
|
||||
// IDbStatement.php
|
||||
// DbStatement.php
|
||||
// Created: 2021-05-02
|
||||
// Updated: 2024-09-13
|
||||
// Updated: 2024-10-02
|
||||
|
||||
namespace Index\Data;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use RuntimeException;
|
||||
use Index\ICloseable;
|
||||
use Index\Closeable;
|
||||
|
||||
/**
|
||||
* Represents a prepared database statement.
|
||||
*/
|
||||
interface IDbStatement extends ICloseable {
|
||||
interface DbStatement extends Closeable {
|
||||
/**
|
||||
* Returns how many parameters there are.
|
||||
*
|
||||
|
@ -45,9 +45,9 @@ interface IDbStatement extends ICloseable {
|
|||
/**
|
||||
* Gets the result after execution.
|
||||
*
|
||||
* @return IDbResult Instance of an implementation of IDbResult.
|
||||
* @return DbResult Instance of an implementation of DbResult.
|
||||
*/
|
||||
function getResult(): IDbResult;
|
||||
function getResult(): DbResult;
|
||||
|
||||
/**
|
||||
* Returns the ID of the last inserted row.
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
// DbStatementCache.php
|
||||
// Created: 2023-07-21
|
||||
// Updated: 2024-08-03
|
||||
// Updated: 2024-10-02
|
||||
|
||||
namespace Index\Data;
|
||||
|
||||
|
@ -9,14 +9,14 @@ namespace Index\Data;
|
|||
* Container to avoid having many prepared instances of the same query.
|
||||
*/
|
||||
class DbStatementCache {
|
||||
/** @var array<string, IDbStatement> */
|
||||
/** @var array<string, DbStatement> */
|
||||
private array $stmts = [];
|
||||
|
||||
/**
|
||||
* @param IDbConnection $dbConn Connection to use with this cache.
|
||||
* @param DbConnection $dbConn Connection to use with this cache.
|
||||
*/
|
||||
public function __construct(
|
||||
private IDbConnection $dbConn
|
||||
private DbConnection $dbConn
|
||||
) {}
|
||||
|
||||
private static function hash(string $query): string {
|
||||
|
@ -24,12 +24,12 @@ class DbStatementCache {
|
|||
}
|
||||
|
||||
/**
|
||||
* Gets a cached or creates a new IDbStatement instance.
|
||||
* Gets a cached or creates a new DbStatement instance.
|
||||
*
|
||||
* @param string $query SQL query.
|
||||
* @return IDbStatement Statement representing the query.
|
||||
* @return DbStatement Statement representing the query.
|
||||
*/
|
||||
public function get(string $query): IDbStatement {
|
||||
public function get(string $query): DbStatement {
|
||||
$hash = self::hash($query);
|
||||
|
||||
if(array_key_exists($hash, $this->stmts)) {
|
||||
|
|
|
@ -17,7 +17,7 @@ use RuntimeException;
|
|||
* DbTools only handles the scheme part of the URL,
|
||||
* the rest of the URL is described in the documentation of the parseDsn implementation of the respective backend.
|
||||
*
|
||||
* The scheme can be a PHP classpath to an implementation of IDbBackend, or any of these aliases:
|
||||
* The scheme can be a PHP classpath to an implementation of DbBackend, or any of these aliases:
|
||||
* - `null`: maps to `NullDb\NullDbBackend` or `Index-Data-NullDb-NullDbBackend`, provides a fallback blackhole database backend.
|
||||
* - `mariadb`, `mysql`: maps to `MariaDb\MariaDbBackend` or `Index-Data-MariaDb-MariaDbBackend`, provides a backend based on the mysqli extension.
|
||||
* - `sqlite`, `sqlite3`: maps to `Sqlite\SqliteBackend` or `Index-Data-Sqlite-SqliteBackend`, provides a backend based on the sqlite3 extension.
|
||||
|
@ -42,7 +42,7 @@ final class DbTools {
|
|||
}
|
||||
|
||||
/** @param array<string, string|int> $uri */
|
||||
private static function resolveBackend(array $uri): IDbBackend {
|
||||
private static function resolveBackend(array $uri): DbBackend {
|
||||
static $backends = null;
|
||||
if(!is_array($backends))
|
||||
$backends = [];
|
||||
|
@ -50,7 +50,7 @@ final class DbTools {
|
|||
$scheme = $uri['scheme'];
|
||||
$backend = $backends[$scheme] ?? null;
|
||||
|
||||
if(!($backend instanceof IDbBackend)) {
|
||||
if(!($backend instanceof DbBackend)) {
|
||||
$backend = null;
|
||||
|
||||
if(array_key_exists($scheme, self::DB_PROTOS))
|
||||
|
@ -58,7 +58,7 @@ final class DbTools {
|
|||
else
|
||||
$name = str_replace('-', '\\', (string)$scheme);
|
||||
|
||||
if(class_exists($name) && is_subclass_of($name, IDbBackend::class)) {
|
||||
if(class_exists($name) && is_subclass_of($name, DbBackend::class)) {
|
||||
$backend = new $name;
|
||||
$name = get_class($backend);
|
||||
}
|
||||
|
@ -82,9 +82,9 @@ final class DbTools {
|
|||
* @param string $dsn URL to create database connection from.
|
||||
* @throws InvalidArgumentException if $dsn is not a valid URL.
|
||||
* @throws RuntimeException if no database connection can be made using the URL.
|
||||
* @return IDbBackend Database backend instance.
|
||||
* @return DbBackend Database backend instance.
|
||||
*/
|
||||
public static function backend(string $dsn): IDbBackend {
|
||||
public static function backend(string $dsn): DbBackend {
|
||||
return self::resolveBackend(self::parseDsnUri($dsn));
|
||||
}
|
||||
|
||||
|
@ -96,9 +96,9 @@ final class DbTools {
|
|||
* @param string $dsn URL to create database connection from.
|
||||
* @throws InvalidArgumentException if $dsn is not a valid URL.
|
||||
* @throws RuntimeException if no database connection can be made using the URL.
|
||||
* @return IDbConnectionInfo Database connection info.
|
||||
* @return DbConnectionInfo Database connection info.
|
||||
*/
|
||||
public static function parse(string $dsn): IDbConnectionInfo {
|
||||
public static function parse(string $dsn): DbConnectionInfo {
|
||||
$uri = self::parseDsnUri($dsn);
|
||||
return self::resolveBackend($uri)->parseDsn($uri);
|
||||
}
|
||||
|
@ -111,9 +111,9 @@ final class DbTools {
|
|||
* @param string $dsn URL to create database connection from.
|
||||
* @throws InvalidArgumentException if $dsn is not a valid URL.
|
||||
* @throws RuntimeException if no database connection can be made using the URL.
|
||||
* @return IDbConnection An active database connection.
|
||||
* @return DbConnection An active database connection.
|
||||
*/
|
||||
public static function create(string $dsn): IDbConnection {
|
||||
public static function create(string $dsn): DbConnection {
|
||||
$uri = self::parseDsnUri($dsn);
|
||||
$backend = self::resolveBackend($uri);
|
||||
return $backend->createConnection($backend->parseDsn($uri));
|
||||
|
@ -127,10 +127,10 @@ final class DbTools {
|
|||
* If the callable returns true, commit will be called.
|
||||
* If the callable returns false, rollback will be called.
|
||||
*
|
||||
* @param IDbTransactions $connection A database connection with transaction support.
|
||||
* @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(IDbTransactions $connection, callable $callable): void {
|
||||
public static function transaction(DbTransactions $connection, callable $callable): void {
|
||||
$connection->beginTransaction();
|
||||
$result = $callable($connection) ?? null;
|
||||
if(is_bool($result)) {
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
<?php
|
||||
// IDbTransactions.php
|
||||
// DbTransactions.php
|
||||
// Created: 2021-05-02
|
||||
// Updated: 2024-08-01
|
||||
// Updated: 2024-10-02
|
||||
|
||||
namespace Index\Data;
|
||||
|
||||
/**
|
||||
* Indicates supports for transactions in a database connection.
|
||||
*/
|
||||
interface IDbTransactions extends IDbConnection {
|
||||
interface DbTransactions extends DbConnection {
|
||||
/**
|
||||
* Sets whether changes should be applied immediately or whether commit should always be called first.
|
||||
*
|
|
@ -6,13 +6,13 @@
|
|||
namespace Index\Data\MariaDb;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Index\Data\{IDbBackend,IDbConnection,IDbConnectionInfo};
|
||||
use Index\Data\{DbBackend,DbConnection,DbConnectionInfo};
|
||||
use Index\Net\{EndPoint,UnixEndPoint};
|
||||
|
||||
/**
|
||||
* Information about the MariaDB/MySQL database layer.
|
||||
*/
|
||||
class MariaDbBackend implements IDbBackend {
|
||||
class MariaDbBackend implements DbBackend {
|
||||
public function isAvailable(): bool {
|
||||
return extension_loaded('mysqli');
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ class MariaDbBackend implements IDbBackend {
|
|||
* @param MariaDbConnectionInfo $connectionInfo Object that describes the desired connection.
|
||||
* @return MariaDbConnection A connection with a MariaDB or MySQL server.
|
||||
*/
|
||||
public function createConnection(IDbConnectionInfo $connectionInfo): IDbConnection {
|
||||
public function createConnection(DbConnectionInfo $connectionInfo): DbConnection {
|
||||
if(!($connectionInfo instanceof MariaDbConnectionInfo))
|
||||
throw new InvalidArgumentException('$connectionInfo must by of type MariaDbConnectionInfo');
|
||||
|
||||
|
@ -80,7 +80,7 @@ class MariaDbBackend implements IDbBackend {
|
|||
* @param string|array<string, int|string> $dsn DSN with connection information.
|
||||
* @return MariaDbConnectionInfo MariaDB connection info.
|
||||
*/
|
||||
public function parseDsn(string|array $dsn): IDbConnectionInfo {
|
||||
public function parseDsn(string|array $dsn): DbConnectionInfo {
|
||||
if(is_string($dsn)) {
|
||||
$dsn = parse_url($dsn);
|
||||
if($dsn === false)
|
||||
|
|
|
@ -10,12 +10,12 @@ use mysqli_sql_exception;
|
|||
use stdClass;
|
||||
use InvalidArgumentException;
|
||||
use RuntimeException;
|
||||
use Index\Data\{IDbConnection,IDbTransactions};
|
||||
use Index\Data\{DbConnection,DbTransactions};
|
||||
|
||||
/**
|
||||
* Represents a connection with a MariaDB or MySQL database server.
|
||||
*/
|
||||
class MariaDbConnection implements IDbConnection, IDbTransactions {
|
||||
class MariaDbConnection implements DbConnection, DbTransactions {
|
||||
/**
|
||||
* Refresh grant tables.
|
||||
*
|
||||
|
|
|
@ -6,13 +6,13 @@
|
|||
namespace Index\Data\MariaDb;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Index\Data\IDbConnectionInfo;
|
||||
use Index\Data\DbConnectionInfo;
|
||||
use Index\Net\{EndPoint,DnsEndPoint,IpEndPoint,UnixEndPoint};
|
||||
|
||||
/**
|
||||
* Describes a MariaDB or MySQL connection.
|
||||
*/
|
||||
class MariaDbConnectionInfo implements IDbConnectionInfo {
|
||||
class MariaDbConnectionInfo implements DbConnectionInfo {
|
||||
/**
|
||||
* Creates an instance of MariaDbConnectionInfo.
|
||||
*
|
||||
|
|
|
@ -8,13 +8,13 @@ namespace Index\Data\MariaDb;
|
|||
use mysqli_result;
|
||||
use mysqli_stmt;
|
||||
use InvalidArgumentException;
|
||||
use Index\Data\{DbResultTrait,IDbResult};
|
||||
use Index\Data\{DbResult,DbResultTrait};
|
||||
use Index\Io\{Stream,TempFileStream};
|
||||
|
||||
/**
|
||||
* Represents a MariaDB/MySQL database result.
|
||||
*/
|
||||
abstract class MariaDbResult implements IDbResult {
|
||||
abstract class MariaDbResult implements DbResult {
|
||||
use DbResultTrait;
|
||||
|
||||
/** @var array<int|string, mixed> */
|
||||
|
|
|
@ -8,13 +8,13 @@ namespace Index\Data\MariaDb;
|
|||
use mysqli_stmt;
|
||||
use InvalidArgumentException;
|
||||
use RuntimeException;
|
||||
use Index\Data\{DbType,IDbStatement};
|
||||
use Index\Data\{DbType,DbStatement};
|
||||
use Index\Io\Stream;
|
||||
|
||||
/**
|
||||
* Represents a MariaDB/MySQL prepared statement.
|
||||
*/
|
||||
class MariaDbStatement implements IDbStatement {
|
||||
class MariaDbStatement implements DbStatement {
|
||||
/** @var array<int, MariaDbParameter> */
|
||||
private array $params = [];
|
||||
|
||||
|
|
20
src/Data/Migration/DbMigration.php
Normal file
20
src/Data/Migration/DbMigration.php
Normal file
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
// DbMigration.php
|
||||
// Created: 2023-01-07
|
||||
// Updated: 2024-10-02
|
||||
|
||||
namespace Index\Data\Migration;
|
||||
|
||||
use Index\Data\DbConnection;
|
||||
|
||||
/**
|
||||
* Interface for migration classes to inherit.
|
||||
*/
|
||||
interface DbMigration {
|
||||
/**
|
||||
* Runs the migration implemented by this class. This process is irreversible!
|
||||
*
|
||||
* @param DbConnection $conn Database connection to execute this migration on.
|
||||
*/
|
||||
public function migrate(DbConnection $conn): void;
|
||||
}
|
|
@ -1,16 +1,16 @@
|
|||
<?php
|
||||
// IDbMigrationInfo.php
|
||||
// DbMigrationInfo.php
|
||||
// Created: 2023-01-07
|
||||
// Updated: 2024-08-01
|
||||
// Updated: 2024-10-02
|
||||
|
||||
namespace Index\Data\Migration;
|
||||
|
||||
use Index\Data\IDbConnection;
|
||||
use Index\Data\DbConnection;
|
||||
|
||||
/**
|
||||
* Information on a migration repository item.
|
||||
*/
|
||||
interface IDbMigrationInfo {
|
||||
interface DbMigrationInfo {
|
||||
/**
|
||||
* Returns the name of the migration.
|
||||
*
|
||||
|
@ -28,7 +28,7 @@ interface IDbMigrationInfo {
|
|||
/**
|
||||
* Creates an instance of the underlying migration and runs it. This process is irreversible!
|
||||
*
|
||||
* @param IDbConnection $conn Database connection to execute this migration on.
|
||||
* @param DbConnection $conn Database connection to execute this migration on.
|
||||
*/
|
||||
public function migrate(IDbConnection $conn): void;
|
||||
public function migrate(DbConnection $conn): void;
|
||||
}
|
|
@ -11,7 +11,7 @@ use DateTimeInterface;
|
|||
use InvalidArgumentException;
|
||||
use RuntimeException;
|
||||
use Index\XDateTime;
|
||||
use Index\Data\{IDbConnection,IDbStatement,DbType};
|
||||
use Index\Data\{DbConnection,DbStatement,DbType};
|
||||
use Index\Data\Sqlite\SqliteConnection;
|
||||
|
||||
/**
|
||||
|
@ -34,26 +34,26 @@ class DbMigrationManager {
|
|||
|
||||
private const TEMPLATE = <<<EOF
|
||||
<?php
|
||||
use Index\Data\IDbConnection;
|
||||
use Index\Data\Migration\IDbMigration;
|
||||
use Index\Data\DbConnection;
|
||||
use Index\Data\Migration\DbMigration;
|
||||
|
||||
final class %s implements IDbMigration {
|
||||
public function migrate(IDbConnection \$conn): void {
|
||||
final class %s implements DbMigration {
|
||||
public function migrate(DbConnection \$conn): void {
|
||||
\$conn->execute('CREATE TABLE ...');
|
||||
}
|
||||
}
|
||||
|
||||
EOF;
|
||||
|
||||
private ?IDbStatement $checkStmt = null;
|
||||
private ?IDbStatement $insertStmt = null;
|
||||
private ?DbStatement $checkStmt = null;
|
||||
private ?DbStatement $insertStmt = null;
|
||||
|
||||
/**
|
||||
* @param IDbConnection $conn Connection to apply to migrations to.
|
||||
* @param DbConnection $conn Connection to apply to migrations to.
|
||||
* @param string $tableName Name of the migration tracking table.
|
||||
*/
|
||||
public function __construct(
|
||||
private IDbConnection $conn,
|
||||
private DbConnection $conn,
|
||||
private string $tableName = self::DEFAULT_TABLE,
|
||||
) {}
|
||||
|
||||
|
@ -209,10 +209,10 @@ EOF;
|
|||
/**
|
||||
* Runs all migrations present in a migration repository. This process is irreversible!
|
||||
*
|
||||
* @param IDbMigrationRepo $migrations Migrations repository to fetch migrations from.
|
||||
* @param DbMigrationRepo $migrations Migrations repository to fetch migrations from.
|
||||
* @return string[] Names of migrations that have been completed.
|
||||
*/
|
||||
public function processMigrations(IDbMigrationRepo $migrations): array {
|
||||
public function processMigrations(DbMigrationRepo $migrations): array {
|
||||
$migrations = $migrations->getMigrations();
|
||||
$completed = [];
|
||||
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
<?php
|
||||
// IDbMigrationRepo.php
|
||||
// DbMigrationRepo.php
|
||||
// Created: 2023-01-07
|
||||
// Updated: 2024-08-01
|
||||
// Updated: 2024-10-02
|
||||
|
||||
namespace Index\Data\Migration;
|
||||
|
||||
/**
|
||||
* Represents a repository of migrations.
|
||||
*/
|
||||
interface IDbMigrationRepo {
|
||||
interface DbMigrationRepo {
|
||||
/**
|
||||
* Returns info on migrations contained in this repository.
|
||||
*
|
||||
* @return IDbMigrationInfo[] Collection of migration infos.
|
||||
* @return DbMigrationInfo[] Collection of migration infos.
|
||||
*/
|
||||
public function getMigrations(): array;
|
||||
}
|
|
@ -1,13 +1,13 @@
|
|||
<?php
|
||||
// FsDbMigrationInfo.php
|
||||
// Created: 2023-01-07
|
||||
// Updated: 2024-08-03
|
||||
// Updated: 2024-10-02
|
||||
|
||||
namespace Index\Data\Migration;
|
||||
|
||||
use Index\Data\IDbConnection;
|
||||
use Index\Data\DbConnection;
|
||||
|
||||
class FsDbMigrationInfo implements IDbMigrationInfo {
|
||||
class FsDbMigrationInfo implements DbMigrationInfo {
|
||||
private string $name;
|
||||
private string $className;
|
||||
|
||||
|
@ -39,11 +39,11 @@ class FsDbMigrationInfo implements IDbMigrationInfo {
|
|||
return $this->className;
|
||||
}
|
||||
|
||||
public function migrate(IDbConnection $conn): void {
|
||||
public function migrate(DbConnection $conn): void {
|
||||
require_once $this->path;
|
||||
|
||||
$migration = new $this->className;
|
||||
if($migration instanceof IDbMigration)
|
||||
if($migration instanceof DbMigration)
|
||||
$migration->migrate($conn);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
<?php
|
||||
// FsDbMigrationRepo.php
|
||||
// Created: 2023-01-07
|
||||
// Updated: 2024-08-03
|
||||
// Updated: 2024-10-02
|
||||
|
||||
namespace Index\Data\Migration;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
class FsDbMigrationRepo implements IDbMigrationRepo {
|
||||
class FsDbMigrationRepo implements DbMigrationRepo {
|
||||
/**
|
||||
* @param string $path Filesystem path to the directory containing the migration files.
|
||||
*/
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
<?php
|
||||
// IDbMigration.php
|
||||
// Created: 2023-01-07
|
||||
// Updated: 2024-08-01
|
||||
|
||||
namespace Index\Data\Migration;
|
||||
|
||||
use Index\Data\IDbConnection;
|
||||
|
||||
/**
|
||||
* Interface for migration classes to inherit.
|
||||
*/
|
||||
interface IDbMigration {
|
||||
/**
|
||||
* Runs the migration implemented by this class. This process is irreversible!
|
||||
*
|
||||
* @param IDbConnection $conn Database connection to execute this migration on.
|
||||
*/
|
||||
public function migrate(IDbConnection $conn): void;
|
||||
}
|
|
@ -1,16 +1,16 @@
|
|||
<?php
|
||||
// NullDbBackend.php
|
||||
// Created: 2021-05-02
|
||||
// Updated: 2024-08-03
|
||||
// Updated: 2024-10-02
|
||||
|
||||
namespace Index\Data\NullDb;
|
||||
|
||||
use Index\Data\{IDbBackend,IDbConnection,IDbConnectionInfo};
|
||||
use Index\Data\{DbBackend,DbConnection,DbConnectionInfo};
|
||||
|
||||
/**
|
||||
* Information about the dummy database layer.
|
||||
*/
|
||||
class NullDbBackend implements IDbBackend {
|
||||
class NullDbBackend implements DbBackend {
|
||||
public function isAvailable(): bool {
|
||||
return true;
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ class NullDbBackend implements IDbBackend {
|
|||
* @param NullDbConnectionInfo $connectionInfo Dummy connection info.
|
||||
* @return NullDbConnection Dummy connection instance.
|
||||
*/
|
||||
public function createConnection(IDbConnectionInfo $connectionInfo): IDbConnection {
|
||||
public function createConnection(DbConnectionInfo $connectionInfo): DbConnection {
|
||||
return new NullDbConnection;
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@ class NullDbBackend implements IDbBackend {
|
|||
* @param string|array<string, int|string> $dsn DSN with connection information.
|
||||
* @return NullDbConnectionInfo Dummy connection info instance.
|
||||
*/
|
||||
public function parseDsn(string|array $dsn): IDbConnectionInfo {
|
||||
public function parseDsn(string|array $dsn): DbConnectionInfo {
|
||||
return new NullDbConnectionInfo;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
<?php
|
||||
// NullDbConnection.php
|
||||
// Created: 2021-05-02
|
||||
// Updated: 2024-09-13
|
||||
// Updated: 2024-10-02
|
||||
|
||||
namespace Index\Data\NullDb;
|
||||
|
||||
use Index\Data\{IDbConnection,IDbStatement,IDbResult};
|
||||
use Index\Data\{DbConnection,DbStatement,DbResult};
|
||||
|
||||
/**
|
||||
* Represents a dummy database connection.
|
||||
*/
|
||||
class NullDbConnection implements IDbConnection {
|
||||
class NullDbConnection implements DbConnection {
|
||||
public function getLastInsertId(): int|string {
|
||||
return 0;
|
||||
}
|
||||
|
@ -19,11 +19,11 @@ class NullDbConnection implements IDbConnection {
|
|||
return 0;
|
||||
}
|
||||
|
||||
public function prepare(string $query): IDbStatement {
|
||||
public function prepare(string $query): DbStatement {
|
||||
return new NullDbStatement;
|
||||
}
|
||||
|
||||
public function query(string $query): IDbResult {
|
||||
public function query(string $query): DbResult {
|
||||
return new NullDbResult;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
<?php
|
||||
// NullDbConnectionInfo.php
|
||||
// Created: 2021-05-02
|
||||
// Updated: 2022-02-16
|
||||
// Updated: 2024-10-02
|
||||
|
||||
namespace Index\Data\NullDb;
|
||||
|
||||
use Index\Data\IDbConnectionInfo;
|
||||
use Index\Data\DbConnectionInfo;
|
||||
|
||||
/**
|
||||
* Represents dummy connection info.
|
||||
*/
|
||||
class NullDbConnectionInfo implements IDbConnectionInfo {}
|
||||
class NullDbConnectionInfo implements DbConnectionInfo {}
|
||||
|
|
|
@ -5,13 +5,13 @@
|
|||
|
||||
namespace Index\Data\NullDb;
|
||||
|
||||
use Index\Data\{IDbResult,DbResultIterator};
|
||||
use Index\Data\{DbResult,DbResultIterator};
|
||||
use Index\Io\Stream;
|
||||
|
||||
/**
|
||||
* Represents a dummy database result.
|
||||
*/
|
||||
class NullDbResult implements IDbResult {
|
||||
class NullDbResult implements DbResult {
|
||||
public function next(): bool {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
<?php
|
||||
// NullDbStatement.php
|
||||
// Created: 2021-05-02
|
||||
// Updated: 2024-09-13
|
||||
// Updated: 2024-10-02
|
||||
|
||||
namespace Index\Data\NullDb;
|
||||
|
||||
use Index\Data\{DbType,IDbResult,IDbStatement};
|
||||
use Index\Data\{DbType,DbResult,DbStatement};
|
||||
|
||||
/**
|
||||
* Represents a dummy database statement.
|
||||
*/
|
||||
class NullDbStatement implements IDbStatement {
|
||||
class NullDbStatement implements DbStatement {
|
||||
public function getParameterCount(): int {
|
||||
return 0;
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ class NullDbStatement implements IDbStatement {
|
|||
|
||||
public function nextParameter(mixed $value, int $type = DbType::AUTO): void {}
|
||||
|
||||
public function getResult(): IDbResult {
|
||||
public function getResult(): DbResult {
|
||||
return new NullDbResult;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,12 +7,12 @@ namespace Index\Data\Sqlite;
|
|||
|
||||
use SQLite3;
|
||||
use InvalidArgumentException;
|
||||
use Index\Data\{IDbBackend,IDbConnection,IDbConnectionInfo};
|
||||
use Index\Data\{DbBackend,DbConnection,DbConnectionInfo};
|
||||
|
||||
/**
|
||||
* Information about the SQLite 3 database layer.
|
||||
*/
|
||||
class SqliteBackend implements IDbBackend {
|
||||
class SqliteBackend implements DbBackend {
|
||||
public function isAvailable(): bool {
|
||||
return extension_loaded('sqlite3');
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ class SqliteBackend implements IDbBackend {
|
|||
* @param SqliteConnectionInfo $connectionInfo Object that describes the desired connection.
|
||||
* @return SqliteConnection A client for an SQLite database.
|
||||
*/
|
||||
public function createConnection(IDbConnectionInfo $connectionInfo): IDbConnection {
|
||||
public function createConnection(DbConnectionInfo $connectionInfo): DbConnection {
|
||||
if(!($connectionInfo instanceof SqliteConnectionInfo))
|
||||
throw new InvalidArgumentException('$connectionInfo must by of type SqliteConnectionInfo');
|
||||
|
||||
|
@ -56,7 +56,7 @@ class SqliteBackend implements IDbBackend {
|
|||
* @param string|array<string, int|string> $dsn DSN with connection information.
|
||||
* @return SqliteConnectionInfo SQLite connection info.
|
||||
*/
|
||||
public function parseDsn(string|array $dsn): IDbConnectionInfo {
|
||||
public function parseDsn(string|array $dsn): DbConnectionInfo {
|
||||
if(is_string($dsn)) {
|
||||
$dsn = parse_url($dsn);
|
||||
if($dsn === false)
|
||||
|
|
|
@ -7,13 +7,13 @@ namespace Index\Data\Sqlite;
|
|||
|
||||
use RuntimeException;
|
||||
use SQLite3;
|
||||
use Index\Data\{IDbConnection,IDbTransactions,IDbStatement,IDbResult};
|
||||
use Index\Data\{DbConnection,DbTransactions,DbStatement,DbResult};
|
||||
use Index\Io\{GenericStream,Stream};
|
||||
|
||||
/**
|
||||
* Represents a client for an SQLite database.
|
||||
*/
|
||||
class SqliteConnection implements IDbConnection, IDbTransactions {
|
||||
class SqliteConnection implements DbConnection, DbTransactions {
|
||||
/**
|
||||
* CREATE INDEX authorizer.
|
||||
*
|
||||
|
@ -480,14 +480,14 @@ class SqliteConnection implements IDbConnection, IDbTransactions {
|
|||
return $this->connection->lastInsertRowID();
|
||||
}
|
||||
|
||||
public function prepare(string $query): IDbStatement {
|
||||
public function prepare(string $query): DbStatement {
|
||||
$statement = $this->connection->prepare($query);
|
||||
if($statement === false)
|
||||
throw new RuntimeException((string)$this->getLastErrorString(), $this->getLastErrorCode());
|
||||
return new SqliteStatement($this, $statement);
|
||||
}
|
||||
|
||||
public function query(string $query): IDbResult {
|
||||
public function query(string $query): DbResult {
|
||||
$result = $this->connection->query($query);
|
||||
if($result === false)
|
||||
throw new RuntimeException($this->getLastErrorString(), $this->getLastErrorCode());
|
||||
|
|
|
@ -5,12 +5,12 @@
|
|||
|
||||
namespace Index\Data\Sqlite;
|
||||
|
||||
use Index\Data\IDbConnectionInfo;
|
||||
use Index\Data\DbConnectionInfo;
|
||||
|
||||
/**
|
||||
* Represents information about a SQLite Client.
|
||||
*/
|
||||
class SqliteConnectionInfo implements IDbConnectionInfo {
|
||||
class SqliteConnectionInfo implements DbConnectionInfo {
|
||||
/**
|
||||
* Creates a new SqliteConnectionInfo instance.
|
||||
*
|
||||
|
|
|
@ -7,13 +7,13 @@ namespace Index\Data\Sqlite;
|
|||
|
||||
use SQLite3Result;
|
||||
use InvalidArgumentException;
|
||||
use Index\Data\{DbResultTrait,IDbResult};
|
||||
use Index\Data\{DbResult,DbResultTrait};
|
||||
use Index\Io\{Stream,TempFileStream};
|
||||
|
||||
/**
|
||||
* Represents an SQLite result set.
|
||||
*/
|
||||
class SqliteResult implements IDbResult {
|
||||
class SqliteResult implements DbResult {
|
||||
use DbResultTrait;
|
||||
|
||||
/** @var array<int|string, mixed> */
|
||||
|
|
|
@ -9,13 +9,13 @@ use SQLite3Result;
|
|||
use SQLite3Stmt;
|
||||
use InvalidArgumentException;
|
||||
use RuntimeException;
|
||||
use Index\Data\{DbTools,DbType,IDbStatement,IDbResult};
|
||||
use Index\Data\{DbTools,DbType,DbStatement,DbResult};
|
||||
use Index\Io\Stream;
|
||||
|
||||
/**
|
||||
* Represents a prepared SQLite SQL statement.
|
||||
*/
|
||||
class SqliteStatement implements IDbStatement {
|
||||
class SqliteStatement implements DbStatement {
|
||||
private ?SQLite3Result $result = null;
|
||||
private int $lastOrdinal = 1;
|
||||
|
||||
|
@ -73,7 +73,7 @@ class SqliteStatement implements IDbStatement {
|
|||
$this->bindParameter($this->lastOrdinal, $value, $type);
|
||||
}
|
||||
|
||||
public function getResult(): IDbResult {
|
||||
public function getResult(): DbResult {
|
||||
if($this->result === null)
|
||||
throw new RuntimeException('No result is available.');
|
||||
return new SqliteResult($this->result);
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
<?php
|
||||
// IEquatable.php
|
||||
// Equatable.php
|
||||
// Created: 2021-04-26
|
||||
// Updated: 2021-05-12
|
||||
// Updated: 2024-10-02
|
||||
|
||||
namespace Index;
|
||||
|
||||
/**
|
||||
* Provides an interface for determining the value-equality of two objects.
|
||||
*/
|
||||
interface IEquatable {
|
||||
interface Equatable {
|
||||
/**
|
||||
* Checks whether the current object is equal to another.
|
||||
*
|
|
@ -5,13 +5,13 @@
|
|||
|
||||
namespace Index\Http\Content;
|
||||
|
||||
use Index\Bencode\{Bencode,IBencodeSerializable};
|
||||
use Index\Bencode\{Bencode,BencodeSerializable};
|
||||
use Index\Io\{Stream,FileStream};
|
||||
|
||||
/**
|
||||
* Represents Bencoded body content for a HTTP message.
|
||||
*/
|
||||
class BencodedContent implements IHttpContent, IBencodeSerializable {
|
||||
class BencodedContent implements BencodeSerializable, HttpContent {
|
||||
/**
|
||||
* @param mixed $content Content to be bencoded.
|
||||
*/
|
||||
|
|
|
@ -11,7 +11,7 @@ use Index\Http\HttpUploadedFile;
|
|||
/**
|
||||
* Represents form body content for a HTTP message.
|
||||
*/
|
||||
class FormContent implements IHttpContent {
|
||||
class FormContent implements HttpContent {
|
||||
/**
|
||||
* @param array<string, mixed> $postFields Form fields.
|
||||
* @param array<string, HttpUploadedFile|array<string, mixed>> $uploadedFiles Uploaded files.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
// IHttpContent.php
|
||||
// HttpContent.php
|
||||
// Created: 2022-02-08
|
||||
// Updated: 2024-08-01
|
||||
// Updated: 2024-10-02
|
||||
|
||||
namespace Index\Http\Content;
|
||||
|
||||
|
@ -10,4 +10,4 @@ use Stringable;
|
|||
/**
|
||||
* Represents the body content for a HTTP message.
|
||||
*/
|
||||
interface IHttpContent extends Stringable {}
|
||||
interface HttpContent extends Stringable {}
|
|
@ -11,7 +11,7 @@ use Index\Io\{Stream,FileStream};
|
|||
/**
|
||||
* Represents JSON body content for a HTTP message.
|
||||
*/
|
||||
class JsonContent implements IHttpContent, JsonSerializable {
|
||||
class JsonContent implements HttpContent, JsonSerializable {
|
||||
/**
|
||||
* @param mixed $content Content to be JSON encoded.
|
||||
*/
|
||||
|
|
|
@ -10,7 +10,7 @@ use Index\Io\{Stream,FileStream};
|
|||
/**
|
||||
* Represents Stream body content for a HTTP message.
|
||||
*/
|
||||
class StreamContent implements IHttpContent {
|
||||
class StreamContent implements HttpContent {
|
||||
/**
|
||||
* @param Stream $stream Stream that represents this message body.
|
||||
*/
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
// StringContent.php
|
||||
// Created: 2022-02-10
|
||||
// Updated: 2024-08-03
|
||||
// Updated: 2024-10-02
|
||||
|
||||
namespace Index\Http\Content;
|
||||
|
||||
|
@ -10,7 +10,7 @@ use Stringable;
|
|||
/**
|
||||
* Represents string body content for a HTTP message.
|
||||
*/
|
||||
class StringContent implements IHttpContent {
|
||||
class StringContent implements HttpContent {
|
||||
/**
|
||||
* @param string $string String that represents this message body.
|
||||
*/
|
||||
|
|
|
@ -5,16 +5,16 @@
|
|||
|
||||
namespace Index\Http\ContentHandling;
|
||||
|
||||
use Index\Bencode\IBencodeSerializable;
|
||||
use Index\Bencode\BencodeSerializable;
|
||||
use Index\Http\HttpResponseBuilder;
|
||||
use Index\Http\Content\BencodedContent;
|
||||
|
||||
/**
|
||||
* Represents a Bencode content handler for building HTTP response messages.
|
||||
*/
|
||||
class BencodeContentHandler implements IContentHandler {
|
||||
class BencodeContentHandler implements ContentHandler {
|
||||
public function match(mixed $content): bool {
|
||||
return $content instanceof IBencodeSerializable;
|
||||
return $content instanceof BencodeSerializable;
|
||||
}
|
||||
|
||||
public function handle(HttpResponseBuilder $response, mixed $content): void {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
// IContentHandler.php
|
||||
// ContentHandler.php
|
||||
// Created: 2024-03-28
|
||||
// Updated: 2024-08-01
|
||||
// Updated: 2024-10-02
|
||||
|
||||
namespace Index\Http\ContentHandling;
|
||||
|
||||
|
@ -10,7 +10,7 @@ use Index\Http\HttpResponseBuilder;
|
|||
/**
|
||||
* Represents a content handler for building HTTP response messages.
|
||||
*/
|
||||
interface IContentHandler {
|
||||
interface ContentHandler {
|
||||
/**
|
||||
* Determines whether this handler is suitable for the body content.
|
||||
*
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
// JsonContentHandler.php
|
||||
// Created: 2024-03-28
|
||||
// Updated: 2024-08-01
|
||||
// Updated: 2024-10-02
|
||||
|
||||
namespace Index\Http\ContentHandling;
|
||||
|
||||
|
@ -13,7 +13,7 @@ use Index\Http\Content\JsonContent;
|
|||
/**
|
||||
* Represents a JSON content handler for building HTTP response messages.
|
||||
*/
|
||||
class JsonContentHandler implements IContentHandler {
|
||||
class JsonContentHandler implements ContentHandler {
|
||||
public function match(mixed $content): bool {
|
||||
return is_array($content) || $content instanceof JsonSerializable || $content instanceof stdClass;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ use Index\Io\Stream;
|
|||
/**
|
||||
* Represents a Stream content handler for building HTTP response messages.
|
||||
*/
|
||||
class StreamContentHandler implements IContentHandler {
|
||||
class StreamContentHandler implements ContentHandler {
|
||||
public function match(mixed $content): bool {
|
||||
return $content instanceof Stream;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
// IErrorHandler.php
|
||||
// ErrorHandler.php
|
||||
// Created: 2024-03-28
|
||||
// Updated: 2024-08-01
|
||||
// Updated: 2024-10-02
|
||||
|
||||
namespace Index\Http\ErrorHandling;
|
||||
|
||||
|
@ -10,7 +10,7 @@ use Index\Http\{HttpResponseBuilder,HttpRequest};
|
|||
/**
|
||||
* Represents an error message handler for building HTTP response messages.
|
||||
*/
|
||||
interface IErrorHandler {
|
||||
interface ErrorHandler {
|
||||
/**
|
||||
* Applies an error message template to the provided HTTP response builder.
|
||||
*
|
|
@ -10,7 +10,7 @@ use Index\Http\{HttpResponseBuilder,HttpRequest};
|
|||
/**
|
||||
* Represents a basic HTML error message handler for building HTTP response messages.
|
||||
*/
|
||||
class HtmlErrorHandler implements IErrorHandler {
|
||||
class HtmlErrorHandler implements ErrorHandler {
|
||||
private const TEMPLATE = <<<HTML
|
||||
<!doctype html>
|
||||
<html>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
// PlainErrorHandler.php
|
||||
// Created: 2024-03-28
|
||||
// Updated: 2024-08-01
|
||||
// Updated: 2024-10-02
|
||||
|
||||
namespace Index\Http\ErrorHandling;
|
||||
|
||||
|
@ -10,7 +10,7 @@ use Index\Http\{HttpResponseBuilder,HttpRequest};
|
|||
/**
|
||||
* Represents a plain text error message handler for building HTTP response messages.
|
||||
*/
|
||||
class PlainErrorHandler implements IErrorHandler {
|
||||
class PlainErrorHandler implements ErrorHandler {
|
||||
public function handle(HttpResponseBuilder $response, HttpRequest $request, int $code, string $message): void {
|
||||
$response->setTypePlain();
|
||||
$response->setContent(sprintf('HTTP %03d %s', $code, $message));
|
||||
|
|
|
@ -7,7 +7,7 @@ namespace Index\Http;
|
|||
|
||||
use RuntimeException;
|
||||
use Index\Io\Stream;
|
||||
use Index\Http\Content\{IHttpContent,BencodedContent,FormContent,JsonContent,StreamContent,StringContent};
|
||||
use Index\Http\Content\{BencodedContent,FormContent,HttpContent,JsonContent,StreamContent,StringContent};
|
||||
|
||||
/**
|
||||
* Represents a base HTTP message.
|
||||
|
@ -16,12 +16,12 @@ abstract class HttpMessage {
|
|||
/**
|
||||
* @param string $version HTTP message version.
|
||||
* @param HttpHeaders $headers HTTP message headers.
|
||||
* @param ?IHttpContent $content Body contents.
|
||||
* @param ?HttpContent $content Body contents.
|
||||
*/
|
||||
public function __construct(
|
||||
private string $version,
|
||||
private HttpHeaders $headers,
|
||||
private ?IHttpContent $content
|
||||
private ?HttpContent $content
|
||||
) {}
|
||||
|
||||
/**
|
||||
|
@ -105,9 +105,9 @@ abstract class HttpMessage {
|
|||
/**
|
||||
* Retrieves message body contents, if present.
|
||||
*
|
||||
* @return ?IHttpContent Body contents, null if none present.
|
||||
* @return ?HttpContent Body contents, null if none present.
|
||||
*/
|
||||
public function getContent(): ?IHttpContent {
|
||||
public function getContent(): ?HttpContent {
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
namespace Index\Http;
|
||||
|
||||
use Index\Io\Stream;
|
||||
use Index\Http\Content\{IHttpContent,StreamContent,StringContent};
|
||||
use Index\Http\Content\{HttpContent,StreamContent,StringContent};
|
||||
|
||||
/**
|
||||
* Represents a base HTTP message builder.
|
||||
|
@ -14,7 +14,7 @@ use Index\Http\Content\{IHttpContent,StreamContent,StringContent};
|
|||
class HttpMessageBuilder {
|
||||
private ?string $version = null;
|
||||
private HttpHeadersBuilder $headers;
|
||||
private ?IHttpContent $content = null;
|
||||
private ?HttpContent $content = null;
|
||||
|
||||
public function __construct() {
|
||||
$this->headers = new HttpHeadersBuilder;
|
||||
|
@ -100,9 +100,9 @@ class HttpMessageBuilder {
|
|||
/**
|
||||
* Retrieves HTTP message body content.
|
||||
*
|
||||
* @return ?IHttpContent Body content.
|
||||
* @return ?HttpContent Body content.
|
||||
*/
|
||||
protected function getContent(): ?IHttpContent {
|
||||
protected function getContent(): ?HttpContent {
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
|
@ -119,9 +119,9 @@ class HttpMessageBuilder {
|
|||
/**
|
||||
* Sets HTTP message body contents.
|
||||
*
|
||||
* @param IHttpContent|Stream|string|null $content Body contents
|
||||
* @param HttpContent|Stream|string|null $content Body contents
|
||||
*/
|
||||
public function setContent(IHttpContent|Stream|string|null $content): void {
|
||||
public function setContent(HttpContent|Stream|string|null $content): void {
|
||||
if($content instanceof Stream)
|
||||
$content = new StreamContent($content);
|
||||
elseif(is_string($content))
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
<?php
|
||||
// HttpRequest.php
|
||||
// Created: 2022-02-08
|
||||
// Updated: 2024-08-04
|
||||
// Updated: 2024-10-02
|
||||
|
||||
namespace Index\Http;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use RuntimeException;
|
||||
use Index\MediaType;
|
||||
use Index\Http\Content\{IHttpContent,JsonContent,StreamContent,FormContent};
|
||||
use Index\Http\Content\{HttpContent,JsonContent,StreamContent,FormContent};
|
||||
|
||||
/**
|
||||
* Represents a HTTP request message.
|
||||
|
@ -21,7 +21,7 @@ class HttpRequest extends HttpMessage {
|
|||
* @param array<string, mixed> $params HTTP request query parameters.
|
||||
* @param array<string, string> $cookies HTTP request cookies.
|
||||
* @param HttpHeaders $headers HTTP message headers.
|
||||
* @param ?IHttpContent $content Body contents.
|
||||
* @param ?HttpContent $content Body contents.
|
||||
*/
|
||||
public function __construct(
|
||||
string $version,
|
||||
|
@ -30,7 +30,7 @@ class HttpRequest extends HttpMessage {
|
|||
private array $params,
|
||||
private array $cookies,
|
||||
HttpHeaders $headers,
|
||||
?IHttpContent $content
|
||||
?HttpContent $content
|
||||
) {
|
||||
parent::__construct($version, $headers, $content);
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<?php
|
||||
// HttpResponse.php
|
||||
// Created: 2022-02-08
|
||||
// Updated: 2024-08-01
|
||||
// Updated: 2024-10-02
|
||||
|
||||
namespace Index\Http;
|
||||
|
||||
use Index\Http\Content\IHttpContent;
|
||||
use Index\Http\Content\HttpContent;
|
||||
|
||||
/**
|
||||
* Represents a HTTP response message.
|
||||
|
@ -16,14 +16,14 @@ class HttpResponse extends HttpMessage {
|
|||
* @param int $statusCode HTTP response status code.
|
||||
* @param string $statusText HTTP response status text.
|
||||
* @param HttpHeaders $headers HTTP message headers.
|
||||
* @param ?IHttpContent $content Body contents.
|
||||
* @param ?HttpContent $content Body contents.
|
||||
*/
|
||||
public function __construct(
|
||||
string $version,
|
||||
private int $statusCode,
|
||||
private string $statusText,
|
||||
HttpHeaders $headers,
|
||||
?IHttpContent $content
|
||||
?HttpContent $content
|
||||
) {
|
||||
parent::__construct($version, $headers, $content);
|
||||
}
|
||||
|
|
|
@ -7,13 +7,13 @@ namespace Index\Http;
|
|||
|
||||
use InvalidArgumentException;
|
||||
use RuntimeException;
|
||||
use Index\{MediaType,ICloseable};
|
||||
use Index\{MediaType,Closeable};
|
||||
use Index\Io\{Stream,FileStream};
|
||||
|
||||
/**
|
||||
* Represents an uploaded file in a multipart/form-data request.
|
||||
*/
|
||||
class HttpUploadedFile implements ICloseable {
|
||||
class HttpUploadedFile implements Closeable {
|
||||
private bool $hasMoved = false;
|
||||
private ?Stream $stream = null;
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
// HandlerAttribute.php
|
||||
// Created: 2024-03-28
|
||||
// Updated: 2024-08-01
|
||||
// Updated: 2024-10-02
|
||||
|
||||
namespace Index\Http\Routing;
|
||||
|
||||
|
@ -29,12 +29,12 @@ abstract class HandlerAttribute {
|
|||
}
|
||||
|
||||
/**
|
||||
* Reads attributes from methods in a IRouteHandler instance and registers them to a given IRouter instance.
|
||||
* Reads attributes from methods in a RouteHandler instance and registers them to a given Router instance.
|
||||
*
|
||||
* @param IRouter $router Router instance.
|
||||
* @param IRouteHandler $handler Handler instance.
|
||||
* @param Router $router Router instance.
|
||||
* @param RouteHandler $handler Handler instance.
|
||||
*/
|
||||
public static function register(IRouter $router, IRouteHandler $handler): void {
|
||||
public static function register(Router $router, RouteHandler $handler): void {
|
||||
$objectInfo = new ReflectionObject($handler);
|
||||
$methodInfos = $objectInfo->getMethods();
|
||||
|
||||
|
|
|
@ -9,10 +9,10 @@ use stdClass;
|
|||
use InvalidArgumentException;
|
||||
use Index\Http\{HttpResponse,HttpResponseBuilder,HttpRequest};
|
||||
use Index\Http\Content\StringContent;
|
||||
use Index\Http\ContentHandling\{BencodeContentHandler,IContentHandler,JsonContentHandler,StreamContentHandler};
|
||||
use Index\Http\ErrorHandling\{HtmlErrorHandler,IErrorHandler,PlainErrorHandler};
|
||||
use Index\Http\ContentHandling\{BencodeContentHandler,ContentHandler,JsonContentHandler,StreamContentHandler};
|
||||
use Index\Http\ErrorHandling\{HtmlErrorHandler,ErrorHandler,PlainErrorHandler};
|
||||
|
||||
class HttpRouter implements IRouter {
|
||||
class HttpRouter implements Router {
|
||||
use RouterTrait;
|
||||
|
||||
/** @var array{handler: callable, match?: string, prefix?: string}[] */
|
||||
|
@ -24,19 +24,19 @@ class HttpRouter implements IRouter {
|
|||
/** @var array<string, array<string, callable>> */
|
||||
private array $dynamicRoutes = [];
|
||||
|
||||
/** @var IContentHandler[] */
|
||||
/** @var ContentHandler[] */
|
||||
private array $contentHandlers = [];
|
||||
|
||||
private IErrorHandler $errorHandler;
|
||||
private ErrorHandler $errorHandler;
|
||||
|
||||
/**
|
||||
* @param string $charSet Default character set to specify when none is present.
|
||||
* @param IErrorHandler|string $errorHandler Error handling to use for error responses with an empty body. 'html' for the default HTML implementation, 'plain' for the plaintext implementation.
|
||||
* @param ErrorHandler|string $errorHandler Error handling to use for error responses with an empty body. 'html' for the default HTML implementation, 'plain' for the plaintext implementation.
|
||||
* @param bool $registerDefaultContentHandlers true to register default content handlers for JSON, Bencode, etc.
|
||||
*/
|
||||
public function __construct(
|
||||
private string $charSet = '',
|
||||
IErrorHandler|string $errorHandler = 'html',
|
||||
ErrorHandler|string $errorHandler = 'html',
|
||||
bool $registerDefaultContentHandlers = true,
|
||||
) {
|
||||
$this->setErrorHandler($errorHandler);
|
||||
|
@ -65,19 +65,19 @@ class HttpRouter implements IRouter {
|
|||
/**
|
||||
* Retrieves the error handler instance.
|
||||
*
|
||||
* @return IErrorHandler The error handler.
|
||||
* @return ErrorHandler The error handler.
|
||||
*/
|
||||
public function getErrorHandler(): IErrorHandler {
|
||||
public function getErrorHandler(): ErrorHandler {
|
||||
return $this->errorHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the active error handler.
|
||||
*
|
||||
* @param IErrorHandler|string $handler Error handling to use for error responses with an empty body. 'html' for the default HTML implementation, 'plain' for the plaintext implementation.
|
||||
* @param ErrorHandler|string $handler Error handling to use for error responses with an empty body. 'html' for the default HTML implementation, 'plain' for the plaintext implementation.
|
||||
*/
|
||||
public function setErrorHandler(IErrorHandler|string $handler): void {
|
||||
if($handler instanceof IErrorHandler)
|
||||
public function setErrorHandler(ErrorHandler|string $handler): void {
|
||||
if($handler instanceof ErrorHandler)
|
||||
$this->errorHandler = $handler;
|
||||
elseif($handler === 'html')
|
||||
$this->setHTMLErrorHandler();
|
||||
|
@ -102,9 +102,9 @@ class HttpRouter implements IRouter {
|
|||
/**
|
||||
* Register a message body content handler.
|
||||
*
|
||||
* @param IContentHandler $contentHandler Content handler to register.
|
||||
* @param ContentHandler $contentHandler Content handler to register.
|
||||
*/
|
||||
public function registerContentHandler(IContentHandler $contentHandler): void {
|
||||
public function registerContentHandler(ContentHandler $contentHandler): void {
|
||||
if(!in_array($contentHandler, $this->contentHandlers))
|
||||
$this->contentHandlers[] = $contentHandler;
|
||||
}
|
||||
|
@ -122,9 +122,9 @@ class HttpRouter implements IRouter {
|
|||
* Retrieve a scoped router to a given path prefix.
|
||||
*
|
||||
* @param string $prefix Prefix to apply to paths within the returned router.
|
||||
* @return IRouter Scopes router proxy.
|
||||
* @return Router Scopes router proxy.
|
||||
*/
|
||||
public function scopeTo(string $prefix): IRouter {
|
||||
public function scopeTo(string $prefix): Router {
|
||||
return new ScopedRouter($this, $prefix);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
<?php
|
||||
// IRouteHandler.php
|
||||
// Created: 2024-03-28
|
||||
// Updated: 2024-03-28
|
||||
|
||||
namespace Index\Http\Routing;
|
||||
|
||||
/**
|
||||
* Provides the interface for IRouter::register().
|
||||
*/
|
||||
interface IRouteHandler {
|
||||
/**
|
||||
* Registers routes on a given IRouter instance.
|
||||
*
|
||||
* @param IRouter $router Target router.
|
||||
*/
|
||||
public function registerRoutes(IRouter $router): void;
|
||||
}
|
|
@ -1,14 +1,18 @@
|
|||
<?php
|
||||
// RouteHandler.php
|
||||
// Created: 2024-03-28
|
||||
// Updated: 2024-03-28
|
||||
// Updated: 2024-10-02
|
||||
|
||||
namespace Index\Http\Routing;
|
||||
|
||||
/**
|
||||
* Provides an abstract class version of IRouteHandler that already includes the trait as well,
|
||||
* letting you only have to use one use statement rather than two!
|
||||
* Provides the interface for Router::register().
|
||||
*/
|
||||
abstract class RouteHandler implements IRouteHandler {
|
||||
use RouteHandlerTrait;
|
||||
interface RouteHandler {
|
||||
/**
|
||||
* Registers routes on a given Router instance.
|
||||
*
|
||||
* @param Router $router Target router.
|
||||
*/
|
||||
public function registerRoutes(Router $router): void;
|
||||
}
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
<?php
|
||||
// RouteHandlerTrait.php
|
||||
// Created: 2024-03-28
|
||||
// Updated: 2024-03-28
|
||||
// Updated: 2024-10-02
|
||||
|
||||
namespace Index\Http\Routing;
|
||||
|
||||
/**
|
||||
* Provides an implementation of IRouteHandler::registerRoutes that uses the attributes.
|
||||
* Provides an implementation of RouteHandler::registerRoutes that uses the attributes.
|
||||
* For more advanced use, everything can be use'd separately and HandlerAttribute::register called manually.
|
||||
*/
|
||||
trait RouteHandlerTrait {
|
||||
public function registerRoutes(IRouter $router): void {
|
||||
public function registerRoutes(Router $router): void {
|
||||
HandlerAttribute::register($router, $this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
// IRouter.php
|
||||
// Router.php
|
||||
// Created: 2024-03-28
|
||||
// Updated: 2024-03-28
|
||||
// Updated: 2024-10-02
|
||||
|
||||
namespace Index\Http\Routing;
|
||||
|
||||
|
@ -9,14 +9,14 @@ use InvalidArgumentException;
|
|||
use RuntimeException;
|
||||
use Index\Http\HttpRequest;
|
||||
|
||||
interface IRouter {
|
||||
interface Router {
|
||||
/**
|
||||
* Creates a scoped version of this router.
|
||||
*
|
||||
* @param string $prefix Prefix path to prepend to all registered routes.
|
||||
* @return IRouter Scoped router.
|
||||
* @return Router Scoped router.
|
||||
*/
|
||||
public function scopeTo(string $prefix): IRouter;
|
||||
public function scopeTo(string $prefix): Router;
|
||||
|
||||
/**
|
||||
* Apply middleware functions to a path.
|
||||
|
@ -94,9 +94,9 @@ interface IRouter {
|
|||
public function options(string $path, callable $handler): void;
|
||||
|
||||
/**
|
||||
* Registers routes in an IRouteHandler implementation.
|
||||
* Registers routes in an RouteHandler implementation.
|
||||
*
|
||||
* @param IRouteHandler $handler Routes handler.
|
||||
* @param RouteHandler $handler Routes handler.
|
||||
*/
|
||||
public function register(IRouteHandler $handler): void;
|
||||
public function register(RouteHandler $handler): void;
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
// RouterTrait.php
|
||||
// Created: 2024-03-28
|
||||
// Updated: 2024-08-01
|
||||
// Updated: 2024-10-02
|
||||
|
||||
namespace Index\Http\Routing;
|
||||
|
||||
|
@ -33,7 +33,7 @@ trait RouterTrait {
|
|||
$this->add('OPTIONS', $path, $handler);
|
||||
}
|
||||
|
||||
public function register(IRouteHandler $handler): void {
|
||||
public function register(RouteHandler $handler): void {
|
||||
$handler->registerRoutes($this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
<?php
|
||||
// ScopedRouter.php
|
||||
// Created: 2024-03-28
|
||||
// Updated: 2024-08-01
|
||||
// Updated: 2024-10-02
|
||||
|
||||
namespace Index\Http\Routing;
|
||||
|
||||
/**
|
||||
* Provides a scoped router interface, automatically adds a prefix to any routes added.
|
||||
*/
|
||||
class ScopedRouter implements IRouter {
|
||||
class ScopedRouter implements Router {
|
||||
use RouterTrait;
|
||||
|
||||
/**
|
||||
* @param IRouter $router Underlying router.
|
||||
* @param Router $router Underlying router.
|
||||
* @param string $prefix Base path to use as a prefix.
|
||||
*/
|
||||
public function __construct(
|
||||
private IRouter $router,
|
||||
private Router $router,
|
||||
private string $prefix
|
||||
) {
|
||||
if($router instanceof ScopedRouter)
|
||||
|
@ -25,11 +25,11 @@ class ScopedRouter implements IRouter {
|
|||
// TODO: cleanup prefix
|
||||
}
|
||||
|
||||
private function getParentRouter(): IRouter {
|
||||
private function getParentRouter(): Router {
|
||||
return $this->router;
|
||||
}
|
||||
|
||||
public function scopeTo(string $prefix): IRouter {
|
||||
public function scopeTo(string $prefix): Router {
|
||||
return $this->router->scopeTo($this->prefix . $prefix);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,12 +7,12 @@ namespace Index\Io;
|
|||
|
||||
use RuntimeException;
|
||||
use Stringable;
|
||||
use Index\ICloseable;
|
||||
use Index\Closeable;
|
||||
|
||||
/**
|
||||
* Represents a generic data stream.
|
||||
*/
|
||||
abstract class Stream implements Stringable, ICloseable {
|
||||
abstract class Stream implements Stringable, Closeable {
|
||||
/**
|
||||
* Place the cursor relative to the start of the file.
|
||||
*
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
// MediaType.php
|
||||
// Created: 2022-02-10
|
||||
// Updated: 2024-08-18
|
||||
// Updated: 2024-10-02
|
||||
|
||||
namespace Index;
|
||||
|
||||
|
@ -12,7 +12,7 @@ use Stringable;
|
|||
/**
|
||||
* Implements a structure for representing and comparing media/mime types.
|
||||
*/
|
||||
class MediaType implements Stringable, IComparable, IEquatable {
|
||||
class MediaType implements Stringable, Comparable, Equatable {
|
||||
/**
|
||||
* @param string $category Media type category.
|
||||
* @param string $kind Media type kind.
|
||||
|
|
|
@ -8,12 +8,12 @@ namespace Index\Net;
|
|||
use InvalidArgumentException;
|
||||
use JsonSerializable;
|
||||
use Stringable;
|
||||
use Index\IEquatable;
|
||||
use Index\Equatable;
|
||||
|
||||
/**
|
||||
* Represents a generic network end point.
|
||||
*/
|
||||
abstract class EndPoint implements JsonSerializable, Stringable, IEquatable {
|
||||
abstract class EndPoint implements JsonSerializable, Stringable, Equatable {
|
||||
abstract public function equals(mixed $other): bool;
|
||||
abstract public function __toString(): string;
|
||||
|
||||
|
|
|
@ -8,12 +8,12 @@ namespace Index\Net;
|
|||
use InvalidArgumentException;
|
||||
use JsonSerializable;
|
||||
use Stringable;
|
||||
use Index\IEquatable;
|
||||
use Index\Equatable;
|
||||
|
||||
/**
|
||||
* Represents an IP address.
|
||||
*/
|
||||
final class IpAddress implements JsonSerializable, Stringable, IEquatable {
|
||||
final class IpAddress implements JsonSerializable, Stringable, Equatable {
|
||||
/**
|
||||
* Unknown IP version.
|
||||
*
|
||||
|
|
|
@ -8,12 +8,12 @@ namespace Index\Net;
|
|||
use InvalidArgumentException;
|
||||
use JsonSerializable;
|
||||
use Stringable;
|
||||
use Index\IEquatable;
|
||||
use Index\Equatable;
|
||||
|
||||
/**
|
||||
* Represents a CIDR range of IP addresses.
|
||||
*/
|
||||
final class IpAddressRange implements JsonSerializable, Stringable, IEquatable {
|
||||
final class IpAddressRange implements JsonSerializable, Stringable, Equatable {
|
||||
/**
|
||||
* @param IpAddress $base Base IP address.
|
||||
* @param int $mask CIDR mask.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
// XArray.php
|
||||
// Created: 2022-02-02
|
||||
// Updated: 2024-08-04
|
||||
// Updated: 2024-10-02
|
||||
|
||||
namespace Index;
|
||||
|
||||
|
@ -473,10 +473,10 @@ final class XArray {
|
|||
$c1 = $iterator1->current();
|
||||
$c2 = $iterator2->current();
|
||||
|
||||
if($c1 instanceof IEquatable) {
|
||||
if($c1 instanceof Equatable) {
|
||||
if(!$c1->equals($c2))
|
||||
return false;
|
||||
} elseif($c2 instanceof IEquatable) {
|
||||
} elseif($c2 instanceof Equatable) {
|
||||
if(!$c2->equals($c1))
|
||||
return false;
|
||||
} elseif($c1 !== $c2)
|
||||
|
|
|
@ -7,17 +7,17 @@ declare(strict_types=1);
|
|||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use PHPUnit\Framework\Attributes\{CoversClass,UsesClass};
|
||||
use Index\Bencode\{Bencode,BencodeProperty,BencodeSerializableTrait,IBencodeSerializable};
|
||||
use Index\Bencode\{Bencode,BencodeProperty,BencodeSerializable,BencodeSerializableTrait};
|
||||
|
||||
#[CoversClass(BencodeProperty::class)]
|
||||
#[CoversClass(BencodeSerializableTrait::class)]
|
||||
#[UsesClass(Bencode::class)]
|
||||
#[UsesClass(IBencodeSerializable::class)]
|
||||
#[UsesClass(BencodeSerializable::class)]
|
||||
final class BencodeSerialisableTest extends TestCase {
|
||||
private const BASIC_BENCODED_ENCODED = 'd9:stringVal12:string value6:intVali1234e9:intStrVal4:56788:floatVal5:12.3411:floatStrVal5:56.787:trueVali1e22:truePossiblyOmittedVali1e8:falseVali0e14:nullValPresent10:scalarValsli0ei1234e5:12.343:stre16:stringVal_method12:string value9:getIntVali1234e11:getFloatVal5:12.3417:getFloatStringVal5:56.7810:getTrueVali1e25:getTruePossiblyOmittedVali1e11:getFalseVali0e17:getNullValPresent13:getScalarValsli0ei1234e5:12.343:stre5:innerd3:objd3:str21:wow this is illegibleee15:getIntStringVal4:5678e';
|
||||
|
||||
public function testBasicBencodedObject(): void {
|
||||
$test = new class implements IBencodeSerializable {
|
||||
$test = new class implements BencodeSerializable {
|
||||
use BencodeSerializableTrait;
|
||||
|
||||
#[BencodeProperty]
|
||||
|
@ -118,12 +118,12 @@ final class BencodeSerialisableTest extends TestCase {
|
|||
|
||||
#[BencodeProperty('inner')]
|
||||
public function getObject(): object {
|
||||
return new class implements IBencodeSerializable {
|
||||
return new class implements BencodeSerializable {
|
||||
use BencodeSerializableTrait;
|
||||
|
||||
#[BencodeProperty('obj')]
|
||||
public function getObject(): object {
|
||||
return new class implements IBencodeSerializable {
|
||||
return new class implements BencodeSerializable {
|
||||
use BencodeSerializableTrait;
|
||||
|
||||
#[BencodeProperty('str')]
|
||||
|
@ -150,7 +150,7 @@ final class BencodeSerialisableTest extends TestCase {
|
|||
public function testDoubleBencodedProperty(): void {
|
||||
$this->expectException(RuntimeException::class);
|
||||
|
||||
$test = new class implements IBencodeSerializable {
|
||||
$test = new class implements BencodeSerializable {
|
||||
use BencodeSerializableTrait;
|
||||
|
||||
#[BencodeProperty('test1')]
|
||||
|
@ -170,7 +170,7 @@ final class BencodeSerialisableTest extends TestCase {
|
|||
public function testDuplicateBencodedProperty(): void {
|
||||
$this->expectException(RuntimeException::class);
|
||||
|
||||
$test = new class implements IBencodeSerializable {
|
||||
$test = new class implements BencodeSerializable {
|
||||
use BencodeSerializableTrait;
|
||||
|
||||
#[BencodeProperty]
|
||||
|
|
Loading…
Reference in a new issue