2024-07-21 01:47:21 +00:00
|
|
|
<?php
|
|
|
|
/**
|
|
|
|
* @author Daniel J. Summers <daniel@bitbadger.solutions>
|
|
|
|
* @license MIT
|
|
|
|
*/
|
|
|
|
|
|
|
|
declare(strict_types=1);
|
2024-06-08 23:58:45 +00:00
|
|
|
|
|
|
|
namespace BitBadger\PDODocument;
|
|
|
|
|
2024-07-28 23:21:37 +00:00
|
|
|
use BitBadger\InspiredByFSharp\Option;
|
2024-07-21 01:47:21 +00:00
|
|
|
use Exception;
|
2024-06-08 23:58:45 +00:00
|
|
|
use PDO;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Common configuration for the document library
|
|
|
|
*/
|
|
|
|
class Configuration
|
|
|
|
{
|
|
|
|
/** @var string The name of the ID field used in the database (will be treated as the primary key) */
|
|
|
|
public static string $idField = 'id';
|
|
|
|
|
2024-06-11 11:07:56 +00:00
|
|
|
/** @var AutoId The automatic ID generation process to use */
|
|
|
|
public static AutoId $autoId = AutoId::None;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var int The number of characters a string generated by `AutoId::RandomString` will have (must be an even number)
|
|
|
|
*/
|
|
|
|
public static int $idStringLength = 16;
|
|
|
|
|
2024-06-08 23:58:45 +00:00
|
|
|
/** @var string|null The username to use to establish a data connection (use env PDO_DOC_USERNAME if possible) */
|
|
|
|
public static ?string $username = null;
|
|
|
|
|
|
|
|
/** @var string|null The password to use to establish a data connection (use env PDO_DOC_PASSWORD if possible) */
|
|
|
|
public static ?string $password = null;
|
|
|
|
|
|
|
|
/** @var array|null Options to use for connections (driver-specific) */
|
|
|
|
public static ?array $options = null;
|
|
|
|
|
2024-07-21 01:47:21 +00:00
|
|
|
/** @var Option<Mode> The mode in which the library is operating */
|
2024-07-22 02:02:16 +00:00
|
|
|
public static Option $mode;
|
2024-07-21 01:47:21 +00:00
|
|
|
|
|
|
|
/** @var Option<string> The data source name (DSN) of the connection string */
|
2024-07-22 02:02:16 +00:00
|
|
|
private static Option $pdoDSN;
|
2024-06-08 23:58:45 +00:00
|
|
|
|
|
|
|
/** @var PDO|null The PDO instance to use for database commands */
|
2024-07-22 02:02:16 +00:00
|
|
|
private static ?PDO $pdo = null;
|
2024-06-08 23:58:45 +00:00
|
|
|
|
2024-07-21 01:47:21 +00:00
|
|
|
/**
|
|
|
|
* Use a Data Source Name (DSN)
|
|
|
|
*
|
|
|
|
* @param string $dsn The data source name to use (driver:[parameters])
|
|
|
|
* @throws DocumentException If a DSN does not start with `pgsql:` or `sqlite:`
|
|
|
|
*/
|
|
|
|
public static function useDSN(string $dsn): void
|
|
|
|
{
|
|
|
|
if (empty($dsn)) {
|
2024-07-28 23:21:37 +00:00
|
|
|
self::$mode = self::$pdoDSN = Option::None();
|
2024-07-21 01:47:21 +00:00
|
|
|
} else {
|
2024-07-28 23:21:37 +00:00
|
|
|
self::$mode = Option::Some(Mode::deriveFromDSN($dsn));
|
|
|
|
self::$pdoDSN = Option::Some($dsn);
|
2024-07-21 01:47:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-06-08 23:58:45 +00:00
|
|
|
/**
|
|
|
|
* Retrieve a new connection to the database
|
|
|
|
*
|
|
|
|
* @return PDO A new connection to the SQLite database with foreign key support enabled
|
2024-07-28 23:21:37 +00:00
|
|
|
* @throws DocumentException If this is called before a connection string is set
|
2024-06-08 23:58:45 +00:00
|
|
|
*/
|
|
|
|
public static function dbConn(): PDO
|
|
|
|
{
|
2024-07-22 02:02:16 +00:00
|
|
|
if (is_null(self::$pdo)) {
|
2024-07-28 23:21:37 +00:00
|
|
|
if (self::$pdoDSN->isNone()) {
|
|
|
|
throw new DocumentException('Please provide a data source name (DSN) before attempting data access');
|
|
|
|
}
|
|
|
|
self::$pdo = new PDO(self::$pdoDSN->get(), $_ENV['PDO_DOC_USERNAME'] ?? self::$username,
|
2024-06-08 23:58:45 +00:00
|
|
|
$_ENV['PDO_DOC_PASSWORD'] ?? self::$password, self::$options);
|
|
|
|
}
|
|
|
|
|
2024-07-22 02:02:16 +00:00
|
|
|
return self::$pdo;
|
2024-06-08 23:58:45 +00:00
|
|
|
}
|
|
|
|
|
2024-07-21 01:47:21 +00:00
|
|
|
/**
|
|
|
|
* Retrieve the mode for the current database connection
|
|
|
|
*
|
|
|
|
* @return Mode The mode for the current database connection
|
|
|
|
* @throws Exception If the database mode has not been set
|
|
|
|
*/
|
|
|
|
public static function mode(?string $process = null): Mode
|
|
|
|
{
|
2024-07-28 23:21:37 +00:00
|
|
|
if (self::$mode->isNone()) {
|
|
|
|
throw new DocumentException('Database mode not set' . (is_null($process) ? '' : "; cannot $process"));
|
|
|
|
}
|
|
|
|
return self::$mode->get();
|
2024-07-21 01:47:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* You probably don't mean to be calling this; it is here for testing only
|
|
|
|
*
|
|
|
|
* @param Mode|null $mode The mode to set
|
|
|
|
*/
|
|
|
|
public static function overrideMode(?Mode $mode): void
|
|
|
|
{
|
2024-07-28 23:21:37 +00:00
|
|
|
self::$mode = Option::of($mode);
|
2024-07-21 01:47:21 +00:00
|
|
|
}
|
|
|
|
|
2024-06-11 11:07:56 +00:00
|
|
|
/**
|
|
|
|
* Clear the current PDO instance
|
|
|
|
*/
|
2024-06-08 23:58:45 +00:00
|
|
|
public static function resetPDO(): void
|
|
|
|
{
|
2024-07-22 02:02:16 +00:00
|
|
|
self::$pdo = null;
|
2024-06-08 23:58:45 +00:00
|
|
|
}
|
|
|
|
}
|