Add docs link, misc format tweaks
This commit is contained in:
parent
d8330d828a
commit
0659de3f99
|
@ -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
28
composer.lock
generated
|
@ -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",
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ enum FieldMatch
|
||||||
{
|
{
|
||||||
return match ($this) {
|
return match ($this) {
|
||||||
FieldMatch::All => 'AND',
|
FieldMatch::All => 'AND',
|
||||||
FieldMatch::Any => 'OR'
|
FieldMatch::Any => 'OR',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ class DocumentMapper implements Mapper
|
||||||
* @param class-string<TDoc> $className The type of class to be returned by this mapping
|
* @param class-string<TDoc> $className The type of class to be returned by this mapping
|
||||||
* @param string $fieldName The name of the field (optional; defaults to `data`)
|
* @param string $fieldName The name of the field (optional; defaults to `data`)
|
||||||
*/
|
*/
|
||||||
public function __construct(public string $className, public string $fieldName = 'data') { }
|
public function __construct(public string $className, public string $fieldName = 'data') {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Map a result to a domain class instance
|
* Map a result to a domain class instance
|
||||||
|
|
|
@ -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,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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'),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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',
|
||||||
|
|
|
@ -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)";
|
||||||
}
|
}
|
||||||
|
|
|
@ -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";
|
||||||
}
|
}
|
||||||
|
|
|
@ -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",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user