Add docs link, misc format tweaks

This commit is contained in:
Daniel J. Summers 2024-07-21 22:02:16 -04:00
parent d8330d828a
commit 0659de3f99
16 changed files with 49 additions and 48 deletions

View File

@ -14,7 +14,8 @@
"support": { "support": {
"email": "daniel@bitbadger.solutions", "email": "daniel@bitbadger.solutions",
"source": "https://git.bitbadger.solutions/bit-badger/pdo-document", "source": "https://git.bitbadger.solutions/bit-badger/pdo-document",
"rss": "https://git.bitbadger.solutions/bit-badger/pdo-document.rss" "rss": "https://git.bitbadger.solutions/bit-badger/pdo-document.rss",
"docs": "https://bitbadger.solutions/open-source/pdo-document/"
}, },
"require": { "require": {
"php": ">=8.2", "php": ">=8.2",

28
composer.lock generated
View File

@ -59,16 +59,16 @@
}, },
{ {
"name": "phpoption/phpoption", "name": "phpoption/phpoption",
"version": "1.9.2", "version": "1.9.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/schmittjoh/php-option.git", "url": "https://github.com/schmittjoh/php-option.git",
"reference": "80735db690fe4fc5c76dfa7f9b770634285fa820" "reference": "e3fac8b24f56113f7cb96af14958c0dd16330f54"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/schmittjoh/php-option/zipball/80735db690fe4fc5c76dfa7f9b770634285fa820", "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/e3fac8b24f56113f7cb96af14958c0dd16330f54",
"reference": "80735db690fe4fc5c76dfa7f9b770634285fa820", "reference": "e3fac8b24f56113f7cb96af14958c0dd16330f54",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -76,13 +76,13 @@
}, },
"require-dev": { "require-dev": {
"bamarni/composer-bin-plugin": "^1.8.2", "bamarni/composer-bin-plugin": "^1.8.2",
"phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2" "phpunit/phpunit": "^8.5.39 || ^9.6.20 || ^10.5.28"
}, },
"type": "library", "type": "library",
"extra": { "extra": {
"bamarni-bin": { "bamarni-bin": {
"bin-links": true, "bin-links": true,
"forward-command": true "forward-command": false
}, },
"branch-alias": { "branch-alias": {
"dev-master": "1.9-dev" "dev-master": "1.9-dev"
@ -118,7 +118,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/schmittjoh/php-option/issues", "issues": "https://github.com/schmittjoh/php-option/issues",
"source": "https://github.com/schmittjoh/php-option/tree/1.9.2" "source": "https://github.com/schmittjoh/php-option/tree/1.9.3"
}, },
"funding": [ "funding": [
{ {
@ -130,7 +130,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2023-11-12T21:59:55+00:00" "time": "2024-07-20T21:41:07+00:00"
} }
], ],
"packages-dev": [ "packages-dev": [
@ -695,16 +695,16 @@
}, },
{ {
"name": "phpunit/phpunit", "name": "phpunit/phpunit",
"version": "11.2.7", "version": "11.2.8",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git", "url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "15c7e69dec4a8f246840859e6b430bd2abeb5039" "reference": "a7a29e8d3113806f18f99d670f580a30e8ffff39"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/15c7e69dec4a8f246840859e6b430bd2abeb5039", "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a7a29e8d3113806f18f99d670f580a30e8ffff39",
"reference": "15c7e69dec4a8f246840859e6b430bd2abeb5039", "reference": "a7a29e8d3113806f18f99d670f580a30e8ffff39",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -775,7 +775,7 @@
"support": { "support": {
"issues": "https://github.com/sebastianbergmann/phpunit/issues", "issues": "https://github.com/sebastianbergmann/phpunit/issues",
"security": "https://github.com/sebastianbergmann/phpunit/security/policy", "security": "https://github.com/sebastianbergmann/phpunit/security/policy",
"source": "https://github.com/sebastianbergmann/phpunit/tree/11.2.7" "source": "https://github.com/sebastianbergmann/phpunit/tree/11.2.8"
}, },
"funding": [ "funding": [
{ {
@ -791,7 +791,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2024-07-10T11:50:09+00:00" "time": "2024-07-18T14:56:37+00:00"
}, },
{ {
"name": "sebastian/cli-parser", "name": "sebastian/cli-parser",

View File

@ -38,13 +38,13 @@ class Configuration
public static ?array $options = null; public static ?array $options = null;
/** @var Option<Mode> The mode in which the library is operating */ /** @var Option<Mode> The mode in which the library is operating */
public static Option $_mode; public static Option $mode;
/** @var Option<string> The data source name (DSN) of the connection string */ /** @var Option<string> The data source name (DSN) of the connection string */
private static Option $_pdoDSN; private static Option $pdoDSN;
/** @var PDO|null The PDO instance to use for database commands */ /** @var PDO|null The PDO instance to use for database commands */
private static ?PDO $_pdo = null; private static ?PDO $pdo = null;
/** /**
* Use a Data Source Name (DSN) * Use a Data Source Name (DSN)
@ -55,10 +55,10 @@ class Configuration
public static function useDSN(string $dsn): void public static function useDSN(string $dsn): void
{ {
if (empty($dsn)) { if (empty($dsn)) {
self::$_mode = self::$_pdoDSN = None::create(); self::$mode = self::$pdoDSN = None::create();
} else { } else {
self::$_mode = Some::create(Mode::deriveFromDSN($dsn)); self::$mode = Some::create(Mode::deriveFromDSN($dsn));
self::$_pdoDSN = Some::create($dsn); self::$pdoDSN = Some::create($dsn);
} }
} }
@ -70,14 +70,14 @@ class Configuration
*/ */
public static function dbConn(): PDO public static function dbConn(): PDO
{ {
if (is_null(self::$_pdo)) { if (is_null(self::$pdo)) {
$dsn = (self::$_pdoDSN ?? None::create())->getOrThrow( $dsn = (self::$pdoDSN ?? None::create())->getOrThrow(
new DocumentException('Please provide a data source name (DSN) before attempting data access')); new DocumentException('Please provide a data source name (DSN) before attempting data access'));
self::$_pdo = new PDO($dsn, $_ENV['PDO_DOC_USERNAME'] ?? self::$username, self::$pdo = new PDO($dsn, $_ENV['PDO_DOC_USERNAME'] ?? self::$username,
$_ENV['PDO_DOC_PASSWORD'] ?? self::$password, self::$options); $_ENV['PDO_DOC_PASSWORD'] ?? self::$password, self::$options);
} }
return self::$_pdo; return self::$pdo;
} }
/** /**
@ -88,7 +88,7 @@ class Configuration
*/ */
public static function mode(?string $process = null): Mode public static function mode(?string $process = null): Mode
{ {
return self::$_mode->getOrThrow( return self::$mode->getOrThrow(
new DocumentException('Database mode not set' . (is_null($process) ? '' : "; cannot $process"))); new DocumentException('Database mode not set' . (is_null($process) ? '' : "; cannot $process")));
} }
@ -99,7 +99,7 @@ class Configuration
*/ */
public static function overrideMode(?Mode $mode): void public static function overrideMode(?Mode $mode): void
{ {
self::$_mode = Option::fromValue($mode); self::$mode = Option::fromValue($mode);
} }
/** /**
@ -107,6 +107,6 @@ class Configuration
*/ */
public static function resetPDO(): void public static function resetPDO(): void
{ {
self::$_pdo = null; self::$pdo = null;
} }
} }

View File

@ -45,7 +45,7 @@ class Custom
is_bool($value) => PDO::PARAM_BOOL, is_bool($value) => PDO::PARAM_BOOL,
is_int($value) => PDO::PARAM_INT, is_int($value) => PDO::PARAM_INT,
is_null($value) => PDO::PARAM_NULL, is_null($value) => PDO::PARAM_NULL,
default => PDO::PARAM_STR default => PDO::PARAM_STR,
}; };
$stmt->bindValue($key, $value, $dataType); $stmt->bindValue($key, $value, $dataType);
} }

View File

@ -21,8 +21,8 @@ use PDOStatement;
*/ */
class DocumentList class DocumentList
{ {
/** @var TDoc|null $_first The first item from the results */ /** @var TDoc|null $first The first item from the results */
private mixed $_first = null; private mixed $first = null;
/** /**
* Constructor * Constructor
@ -33,7 +33,7 @@ class DocumentList
private function __construct(private ?PDOStatement &$result, private readonly Mapper $mapper) private function __construct(private ?PDOStatement &$result, private readonly Mapper $mapper)
{ {
if ($row = $this->result->fetch(PDO::FETCH_ASSOC)) { if ($row = $this->result->fetch(PDO::FETCH_ASSOC)) {
$this->_first = $this->mapper->map($row); $this->first = $this->mapper->map($row);
} else { } else {
$this->result = null; $this->result = null;
} }
@ -62,7 +62,7 @@ class DocumentList
public function items(): Generator public function items(): Generator
{ {
if (!$this->result) return; if (!$this->result) return;
yield $this->_first; yield $this->first;
while ($row = $this->result->fetch(PDO::FETCH_ASSOC)) { while ($row = $this->result->fetch(PDO::FETCH_ASSOC)) {
yield $this->mapper->map($row); yield $this->mapper->map($row);
} }

View File

@ -64,20 +64,20 @@ class Field
$fieldName = (empty($this->qualifier) ? '' : "$this->qualifier.") . 'data' . match (true) { $fieldName = (empty($this->qualifier) ? '' : "$this->qualifier.") . 'data' . match (true) {
!str_contains($this->fieldName, '.') => "->>'$this->fieldName'", !str_contains($this->fieldName, '.') => "->>'$this->fieldName'",
$mode === Mode::PgSQL => "#>>'{" . implode(',', explode('.', $this->fieldName)) . "}'", $mode === Mode::PgSQL => "#>>'{" . implode(',', explode('.', $this->fieldName)) . "}'",
$mode === Mode::SQLite => "->>'" . implode("'->>'", explode('.', $this->fieldName)) . "'" $mode === Mode::SQLite => "->>'" . implode("'->>'", explode('.', $this->fieldName)) . "'",
}; };
$fieldPath = match ($mode) { $fieldPath = match ($mode) {
Mode::PgSQL => match (true) { Mode::PgSQL => match (true) {
$this->op === Op::BT => is_numeric($this->value[0]) ? "($fieldName)::numeric" : $fieldName, $this->op === Op::BT => is_numeric($this->value[0]) ? "($fieldName)::numeric" : $fieldName,
is_numeric($this->value) => "($fieldName)::numeric", is_numeric($this->value) => "($fieldName)::numeric",
default => $fieldName default => $fieldName,
}, },
default => $fieldName default => $fieldName,
}; };
$criteria = match ($this->op) { $criteria = match ($this->op) {
Op::EX, Op::NEX => '', Op::EX, Op::NEX => '',
Op::BT => " {$this->paramName}min AND {$this->paramName}max", Op::BT => " {$this->paramName}min AND {$this->paramName}max",
default => " $this->paramName" default => " $this->paramName",
}; };
return $fieldPath . ' ' . $this->op->toSQL() . $criteria; return $fieldPath . ' ' . $this->op->toSQL() . $criteria;
} }

View File

@ -28,7 +28,7 @@ enum FieldMatch
{ {
return match ($this) { return match ($this) {
FieldMatch::All => 'AND', FieldMatch::All => 'AND',
FieldMatch::Any => 'OR' FieldMatch::Any => 'OR',
}; };
} }
} }

View File

@ -24,7 +24,7 @@ class ExistsMapper implements Mapper
{ {
return match (Configuration::mode('map existence result')) { return match (Configuration::mode('map existence result')) {
Mode::PgSQL => (bool)$result[0], Mode::PgSQL => (bool)$result[0],
Mode::SQLite => (int)$result[0] > 0 Mode::SQLite => (int)$result[0] > 0,
}; };
} }
} }

View File

@ -30,7 +30,7 @@ class StringMapper implements Mapper
return match (false) { return match (false) {
key_exists($this->fieldName, $result) => null, key_exists($this->fieldName, $result) => null,
is_string($result[$this->fieldName]) => "{$result[$this->fieldName]}", is_string($result[$this->fieldName]) => "{$result[$this->fieldName]}",
default => $result[$this->fieldName] default => $result[$this->fieldName],
}; };
} }
} }

View File

@ -30,7 +30,7 @@ enum Mode
return match (true) { return match (true) {
str_starts_with($dsn, 'pgsql:') => Mode::PgSQL, str_starts_with($dsn, 'pgsql:') => Mode::PgSQL,
str_starts_with($dsn, 'sqlite:') => Mode::SQLite, str_starts_with($dsn, 'sqlite:') => Mode::SQLite,
default => throw new DocumentException('This library currently supports PostgreSQL and SQLite') default => throw new DocumentException('This library currently supports PostgreSQL and SQLite'),
}; };
} }
} }

View File

@ -48,7 +48,7 @@ enum Op
Op::NE => "<>", Op::NE => "<>",
Op::BT => "BETWEEN", Op::BT => "BETWEEN",
Op::EX => "IS NOT NULL", Op::EX => "IS NOT NULL",
Op::NEX => "IS NULL" Op::NEX => "IS NULL",
}; };
} }
} }

View File

@ -102,7 +102,7 @@ class Query
AutoId::Number => "json_set(:data, '$.$id', " AutoId::Number => "json_set(:data, '$.$id', "
. "(SELECT coalesce(max(data->>'$id'), 0) + 1 FROM $tableName))", . "(SELECT coalesce(max(data->>'$id'), 0) + 1 FROM $tableName))",
AutoId::UUID => "json_set(:data, '$.$id', '" . AutoId::generateUUID() . "')", AutoId::UUID => "json_set(:data, '$.$id', '" . AutoId::generateUUID() . "')",
AutoId::RandomString => "json_set(:data, '$.$id', '" . AutoId::generateRandom() ."')" AutoId::RandomString => "json_set(:data, '$.$id', '" . AutoId::generateRandom() ."')",
}, },
Mode::PgSQL => match ($autoId ?? AutoId::None) { Mode::PgSQL => match ($autoId ?? AutoId::None) {
AutoId::None => ':data', AutoId::None => ':data',

View File

@ -27,7 +27,7 @@ class Definition
{ {
$dataType = match (Configuration::mode('make create table statement')) { $dataType = match (Configuration::mode('make create table statement')) {
Mode::PgSQL => 'JSONB', Mode::PgSQL => 'JSONB',
Mode::SQLite => 'TEXT' Mode::SQLite => 'TEXT',
}; };
return "CREATE TABLE IF NOT EXISTS $name (data $dataType NOT NULL)"; return "CREATE TABLE IF NOT EXISTS $name (data $dataType NOT NULL)";
} }
@ -91,7 +91,7 @@ class Definition
[, $tbl] = self::splitSchemaAndTable($tableName); [, $tbl] = self::splitSchemaAndTable($tableName);
$extraOps = match ($indexType) { $extraOps = match ($indexType) {
DocumentIndex::Full => '', DocumentIndex::Full => '',
DocumentIndex::Optimized => ' jsonb_path_ops' DocumentIndex::Optimized => ' jsonb_path_ops',
}; };
return "CREATE INDEX IF NOT EXISTS idx_{$tbl}_document ON $tableName USING GIN (data$extraOps)"; return "CREATE INDEX IF NOT EXISTS idx_{$tbl}_document ON $tableName USING GIN (data$extraOps)";
} }

View File

@ -28,7 +28,7 @@ class Patch
{ {
$setValue = match (Configuration::mode('make patch statement')) { $setValue = match (Configuration::mode('make patch statement')) {
Mode::PgSQL => 'data || :data', Mode::PgSQL => 'data || :data',
Mode::SQLite => 'json_patch(data, json(:data))' Mode::SQLite => 'json_patch(data, json(:data))',
}; };
return "UPDATE $tableName SET data = $setValue WHERE $whereClause"; return "UPDATE $tableName SET data = $setValue WHERE $whereClause";
} }

View File

@ -35,7 +35,7 @@ class RemoveFields
Mode::PgSQL => "UPDATE $tableName SET data = data - " . array_keys($parameters)[0] Mode::PgSQL => "UPDATE $tableName SET data = data - " . array_keys($parameters)[0]
. "::text[] WHERE $whereClause", . "::text[] WHERE $whereClause",
Mode::SQLite => "UPDATE $tableName SET data = json_remove(data, " . implode(', ', array_keys($parameters)) Mode::SQLite => "UPDATE $tableName SET data = json_remove(data, " . implode(', ', array_keys($parameters))
. ") WHERE $whereClause" . ") WHERE $whereClause",
}; };
} }