Use PDO singleton

This commit is contained in:
Daniel J. Summers 2024-06-07 20:57:12 -04:00
parent bcca9f5ace
commit d9ffc36fe6
10 changed files with 61 additions and 95 deletions

View File

@ -27,6 +27,9 @@ class Configuration
/** @var Mode|null The mode in which the library is operating (filled after first connection if not configured) */ /** @var Mode|null The mode in which the library is operating (filled after first connection if not configured) */
public static ?Mode $mode = null; public static ?Mode $mode = null;
/** @var PDO|null The PDO instance to use for database commands */
private static ?PDO $_pdo = null;
/** /**
* Retrieve a new connection to the database * Retrieve a new connection to the database
* *
@ -35,21 +38,24 @@ class Configuration
*/ */
public static function dbConn(): PDO public static function dbConn(): PDO
{ {
if (empty(self::$pdoDSN)) { if (is_null(self::$_pdo)) {
throw new DocumentException('Please provide a data source name (DSN) before attempting data access'); if (empty(self::$pdoDSN)) {
} throw new DocumentException('Please provide a data source name (DSN) before attempting data access');
$db = new PDO(self::$pdoDSN, $_ENV['PDO_DOC_USERNAME'] ?? self::$username, }
$_ENV['PDO_DOC_PASSWORD'] ?? self::$password, self::$options); self::$_pdo = new PDO(self::$pdoDSN, $_ENV['PDO_DOC_USERNAME'] ?? self::$username,
$_ENV['PDO_DOC_PASSWORD'] ?? self::$password, self::$options);
if (is_null(self::$mode)) { if (is_null(self::$mode)) {
$driver = $db->getAttribute(PDO::ATTR_DRIVER_NAME); $driver = self::$_pdo->getAttribute(PDO::ATTR_DRIVER_NAME);
self::$mode = match ($driver) { self::$mode = match ($driver) {
'pgsql' => Mode::PgSQL, 'pgsql' => Mode::PgSQL,
'sqlite' => Mode::SQLite, 'sqlite' => Mode::SQLite,
default => throw new DocumentException( default => throw new DocumentException(
"Unsupported driver $driver: this library currently supports PostgreSQL and SQLite") "Unsupported driver $driver: this library currently supports PostgreSQL and SQLite")
}; };
}
} }
return $db;
return self::$_pdo;
} }
} }

View File

@ -3,7 +3,6 @@
namespace BitBadger\PDODocument; namespace BitBadger\PDODocument;
use BitBadger\PDODocument\Mapper\CountMapper; use BitBadger\PDODocument\Mapper\CountMapper;
use PDO;
/** /**
* Functions to count documents * Functions to count documents
@ -14,13 +13,12 @@ class Count
* Count all documents in a table * Count all documents in a table
* *
* @param string $tableName The name of the table in which documents should be counted * @param string $tableName The name of the table in which documents should be counted
* @param PDO|null $pdo The database connection to use (optional; will obtain one if not provided)
* @return int The count of documents in the table * @return int The count of documents in the table
* @throws DocumentException If one is encountered * @throws DocumentException If one is encountered
*/ */
public static function all(string $tableName, ?PDO $pdo = null): int public static function all(string $tableName): int
{ {
return Custom::scalar(Query\Count::all($tableName), [], new CountMapper(), $pdo); return Custom::scalar(Query\Count::all($tableName), [], new CountMapper());
} }
/** /**
@ -28,16 +26,14 @@ class Count
* *
* @param string $tableName The name of the table in which documents should be counted * @param string $tableName The name of the table in which documents should be counted
* @param array|Field[] $fields The field comparison to match * @param array|Field[] $fields The field comparison to match
* @param PDO|null $pdo The database connection to use (optional; will obtain one if not provided)
* @param string $conjunction How to handle multiple conditions (optional; defaults to `AND`) * @param string $conjunction How to handle multiple conditions (optional; defaults to `AND`)
* @return int The count of documents matching the field comparison * @return int The count of documents matching the field comparison
* @throws DocumentException If one is encountered * @throws DocumentException If one is encountered
*/ */
public static function byFields(string $tableName, array $fields, ?PDO $pdo = null, public static function byFields(string $tableName, array $fields, string $conjunction = 'AND'): int
string $conjunction = 'AND'): int
{ {
$namedFields = Parameters::nameFields($fields); $namedFields = Parameters::nameFields($fields);
return Custom::scalar(Query\Count::byFields($tableName, $namedFields, $conjunction), return Custom::scalar(Query\Count::byFields($tableName, $namedFields, $conjunction),
Parameters::addFields($namedFields, []), new CountMapper(), $pdo); Parameters::addFields($namedFields, []), new CountMapper());
} }
} }

View File

@ -16,14 +16,13 @@ class Custom
* *
* @param string $query The query to be run * @param string $query The query to be run
* @param array $parameters The parameters for the query * @param array $parameters The parameters for the query
* @param PDO $pdo The database connection on which the query should be run
* @return PDOStatement The result of executing the query * @return PDOStatement The result of executing the query
* @throws DocumentException If the query execution is unsuccessful * @throws DocumentException If the query execution is unsuccessful
*/ */
public static function runQuery(string $query, array $parameters, PDO $pdo): PDOStatement public static function &runQuery(string $query, array $parameters): PDOStatement
{ {
$debug = defined('PDO_DOC_DEBUG_SQL'); $debug = defined('PDO_DOC_DEBUG_SQL');
$stmt = $pdo->prepare($query); $stmt = Configuration::dbConn()->prepare($query);
foreach ($parameters as $key => $value) { foreach ($parameters as $key => $value) {
if ($debug) echo "<pre>Binding $value to $key\n</pre>"; if ($debug) echo "<pre>Binding $value to $key\n</pre>";
$dataType = match (true) { $dataType = match (true) {
@ -77,19 +76,16 @@ class Custom
* @param string $query The query to be executed (will have "LIMIT 1" appended) * @param string $query The query to be executed (will have "LIMIT 1" appended)
* @param array $parameters Parameters to use in executing the query * @param array $parameters Parameters to use in executing the query
* @param Mapper<TDoc> $mapper Mapper to deserialize the result * @param Mapper<TDoc> $mapper Mapper to deserialize the result
* @param PDO|null $pdo The database connection to use (optional; will obtain one if not provided)
* @return false|TDoc The item if it is found, false if not * @return false|TDoc The item if it is found, false if not
* @throws DocumentException If any is encountered * @throws DocumentException If any is encountered
*/ */
public static function single(string $query, array $parameters, Mapper $mapper, ?PDO $pdo = null): mixed public static function single(string $query, array $parameters, Mapper $mapper): mixed
{ {
try { try {
$stmt = self::runQuery("$query LIMIT 1", $parameters, $stmt = &self::runQuery("$query LIMIT 1", $parameters);
is_null($pdo) ? $actualPDO = Configuration::dbConn() : $pdo);
return ($first = $stmt->fetch(PDO::FETCH_ASSOC)) ? $mapper->map($first) : false; return ($first = $stmt->fetch(PDO::FETCH_ASSOC)) ? $mapper->map($first) : false;
} finally { } finally {
$stmt = null; $stmt = null;
if (isset($actualPDO)) $actualPDO = null;
} }
} }
@ -98,16 +94,14 @@ class Custom
* *
* @param string $query The query to execute * @param string $query The query to execute
* @param array $parameters Parameters to use in executing the query * @param array $parameters Parameters to use in executing the query
* @param PDO|null $pdo The database connection to use (optional; will obtain one if not provided)
* @throws DocumentException If any is encountered * @throws DocumentException If any is encountered
*/ */
public static function nonQuery(string $query, array $parameters, ?PDO $pdo = null): void public static function nonQuery(string $query, array $parameters): void
{ {
try { try {
$stmt = self::runQuery($query, $parameters, is_null($pdo) ? $actualPDO = Configuration::dbConn() : $pdo); $stmt = &self::runQuery($query, $parameters);
} finally { } finally {
$stmt = null; $stmt = null;
if (isset($actualPDO)) $actualPDO = null;
} }
} }
@ -118,18 +112,16 @@ class Custom
* @param string $query The query to retrieve the value * @param string $query The query to retrieve the value
* @param array $parameters Parameters to use in executing the query * @param array $parameters Parameters to use in executing the query
* @param Mapper<T> $mapper The mapper to obtain the result * @param Mapper<T> $mapper The mapper to obtain the result
* @param PDO|null $pdo The database connection to use (optional; will obtain one if not provided)
* @return mixed|false|T The scalar value if found, false if not * @return mixed|false|T The scalar value if found, false if not
* @throws DocumentException If any is encountered * @throws DocumentException If any is encountered
*/ */
public static function scalar(string $query, array $parameters, Mapper $mapper, ?PDO $pdo = null): mixed public static function scalar(string $query, array $parameters, Mapper $mapper, ?PDO $pdo = null): mixed
{ {
try { try {
$stmt = self::runQuery($query, $parameters, is_null($pdo) ? $actualPDO = Configuration::dbConn() : $pdo); $stmt = &self::runQuery($query, $parameters);
return ($first = $stmt->fetch(PDO::FETCH_NUM)) ? $mapper->map($first) : false; return ($first = $stmt->fetch(PDO::FETCH_NUM)) ? $mapper->map($first) : false;
} finally { } finally {
$stmt = null; $stmt = null;
if (isset($actualPDO)) $actualPDO = null;
} }
} }
} }

View File

@ -2,8 +2,6 @@
namespace BitBadger\PDODocument; namespace BitBadger\PDODocument;
use PDO;
/** /**
* Functions to create tables and indexes * Functions to create tables and indexes
*/ */
@ -13,13 +11,12 @@ class Definition
* Ensure a document table exists * Ensure a document table exists
* *
* @param string $name The name of the table to be created if it does not exist * @param string $name The name of the table to be created if it does not exist
* @param PDO|null $pdo The database connection to use (optional; will obtain one if not provided)
* @throws DocumentException If any is encountered * @throws DocumentException If any is encountered
*/ */
public static function ensureTable(string $name, ?PDO $pdo = null): void public static function ensureTable(string $name): void
{ {
Custom::nonQuery(Query\Definition::ensureTable($name), [], $pdo); Custom::nonQuery(Query\Definition::ensureTable($name), []);
Custom::nonQuery(Query\Definition::ensureKey($name), [], $pdo); Custom::nonQuery(Query\Definition::ensureKey($name), []);
} }
/** /**
@ -28,11 +25,10 @@ class Definition
* @param string $tableName The name of the table which should be indexed * @param string $tableName The name of the table which should be indexed
* @param string $indexName The name of the index * @param string $indexName The name of the index
* @param array $fields Fields which should be a part of this index * @param array $fields Fields which should be a part of this index
* @param PDO|null $pdo The database connection to use (optional; will obtain one if not provided)
* @throws DocumentException If any is encountered * @throws DocumentException If any is encountered
*/ */
public static function ensureFieldIndex(string $tableName, string $indexName, array $fields, ?PDO $pdo = null): void public static function ensureFieldIndex(string $tableName, string $indexName, array $fields): void
{ {
Custom::nonQuery(Query\Definition::ensureIndexOn($tableName, $indexName, $fields), [], $pdo); Custom::nonQuery(Query\Definition::ensureIndexOn($tableName, $indexName, $fields), []);
} }
} }

View File

@ -2,8 +2,6 @@
namespace BitBadger\PDODocument; namespace BitBadger\PDODocument;
use PDO;
/** /**
* Functions to delete documents * Functions to delete documents
*/ */
@ -14,12 +12,11 @@ class Delete
* *
* @param string $tableName The table from which the document should be deleted * @param string $tableName The table from which the document should be deleted
* @param mixed $docId The ID of the document to be deleted * @param mixed $docId The ID of the document to be deleted
* @param PDO|null $pdo The database connection to use (optional; will obtain one if not provided)
* @throws DocumentException If any is encountered * @throws DocumentException If any is encountered
*/ */
public static function byId(string $tableName, mixed $docId, ?PDO $pdo = null): void public static function byId(string $tableName, mixed $docId): void
{ {
Custom::nonQuery(Query\Delete::byId($tableName), Parameters::id($docId), $pdo); Custom::nonQuery(Query\Delete::byId($tableName), Parameters::id($docId));
} }
/** /**
@ -27,15 +24,13 @@ class Delete
* *
* @param string $tableName The table from which documents should be deleted * @param string $tableName The table from which documents should be deleted
* @param array|Field[] $fields The field comparison to match * @param array|Field[] $fields The field comparison to match
* @param PDO|null $pdo The database connection to use (optional; will obtain one if not provided)
* @param string $conjunction How to handle multiple conditions (optional; defaults to `AND`) * @param string $conjunction How to handle multiple conditions (optional; defaults to `AND`)
* @throws DocumentException If any is encountered * @throws DocumentException If any is encountered
*/ */
public static function byFields(string $tableName, array $fields, ?PDO $pdo = null, public static function byFields(string $tableName, array $fields, string $conjunction = 'AND'): void
string $conjunction = 'AND'): void
{ {
$namedFields = Parameters::nameFields($fields); $namedFields = Parameters::nameFields($fields);
Custom::nonQuery(Query\Delete::byFields($tableName, $namedFields, $conjunction), Custom::nonQuery(Query\Delete::byFields($tableName, $namedFields, $conjunction),
Parameters::addFields($namedFields, []), $pdo); Parameters::addFields($namedFields, []));
} }
} }

View File

@ -2,8 +2,6 @@
namespace BitBadger\PDODocument; namespace BitBadger\PDODocument;
use PDO;
/** /**
* Functions that apply at a whole document level * Functions that apply at a whole document level
*/ */
@ -14,12 +12,11 @@ class Document
* *
* @param string $tableName The name of the table into which the document should be inserted * @param string $tableName The name of the table into which the document should be inserted
* @param array|object $document The document to be inserted * @param array|object $document The document to be inserted
* @param PDO|null $pdo The database connection to use (optional; will obtain one if not provided)
* @throws DocumentException If any is encountered * @throws DocumentException If any is encountered
*/ */
public static function insert(string $tableName, array|object $document, ?PDO $pdo = null): void public static function insert(string $tableName, array|object $document): void
{ {
Custom::nonQuery(Query::insert($tableName), Parameters::json(':data', $document), $pdo); Custom::nonQuery(Query::insert($tableName), Parameters::json(':data', $document));
} }
/** /**
@ -27,12 +24,11 @@ class Document
* *
* @param string $tableName The name of the table to which the document should be saved * @param string $tableName The name of the table to which the document should be saved
* @param array|object $document The document to be saved * @param array|object $document The document to be saved
* @param PDO|null $pdo The database connection to use (optional; will obtain one if not provided)
* @throws DocumentException If any is encountered * @throws DocumentException If any is encountered
*/ */
public static function save(string $tableName, array|object $document, ?PDO $pdo = null): void public static function save(string $tableName, array|object $document): void
{ {
Custom::nonQuery(Query::save($tableName), Parameters::json(':data', $document), $pdo); Custom::nonQuery(Query::save($tableName), Parameters::json(':data', $document));
} }
/** /**
@ -41,12 +37,11 @@ class Document
* @param string $tableName The table in which the document should be updated * @param string $tableName The table in which the document should be updated
* @param mixed $docId The ID of the document to be updated * @param mixed $docId The ID of the document to be updated
* @param array|object $document The document to be updated * @param array|object $document The document to be updated
* @param PDO|null $pdo The database connection to use (optional; will obtain one if not provided)
* @throws DocumentException If any is encountered * @throws DocumentException If any is encountered
*/ */
public static function update(string $tableName, mixed $docId, array|object $document, ?PDO $pdo = null): void public static function update(string $tableName, mixed $docId, array|object $document): void
{ {
Custom::nonQuery(Query::update($tableName), Custom::nonQuery(Query::update($tableName),
array_merge(Parameters::id($docId), Parameters::json(':data', $document)), $pdo); array_merge(Parameters::id($docId), Parameters::json(':data', $document)));
} }
} }

View File

@ -18,11 +18,10 @@ class DocumentList
/** /**
* Constructor * Constructor
* *
* @param PDO|null $pdo The database connection against which the query was opened
* @param PDOStatement|null $result The result of the query * @param PDOStatement|null $result The result of the query
* @param Mapper<TDoc> $mapper The mapper to deserialize JSON * @param Mapper<TDoc> $mapper The mapper to deserialize JSON
*/ */
private function __construct(private ?PDO $pdo, private ?PDOStatement $result, private Mapper $mapper) { } private function __construct(private ?PDOStatement &$result, private readonly Mapper $mapper) { }
/** /**
* Construct a new document list * Construct a new document list
@ -35,8 +34,8 @@ class DocumentList
*/ */
public static function create(string $query, array $parameters, Mapper $mapper): static public static function create(string $query, array $parameters, Mapper $mapper): static
{ {
$pdo = Configuration::dbConn(); $stmt = &Custom::runQuery($query, $parameters);
return new static($pdo, Custom::runQuery($query, $parameters, $pdo), $mapper); return new static($stmt, $mapper);
} }
/** /**
@ -50,6 +49,5 @@ class DocumentList
while ($row = $this->result->fetch(PDO::FETCH_ASSOC)) yield $this->mapper->map($row); while ($row = $this->result->fetch(PDO::FETCH_ASSOC)) yield $this->mapper->map($row);
} }
$this->result = null; $this->result = null;
$this->pdo = null;
} }
} }

View File

@ -3,7 +3,6 @@
namespace BitBadger\PDODocument; namespace BitBadger\PDODocument;
use BitBadger\PDODocument\Mapper\ExistsMapper; use BitBadger\PDODocument\Mapper\ExistsMapper;
use PDO;
/** /**
* Functions to determine if documents exist * Functions to determine if documents exist
@ -15,13 +14,12 @@ class Exists
* *
* @param string $tableName The name of the table in which document existence should be determined * @param string $tableName The name of the table in which document existence should be determined
* @param mixed $docId The ID of the document whose existence should be determined * @param mixed $docId The ID of the document whose existence should be determined
* @param PDO|null $pdo The database connection to use (optional; will obtain one if not provided)
* @return bool True if the document exists, false if not * @return bool True if the document exists, false if not
* @throws DocumentException If any is encountered * @throws DocumentException If any is encountered
*/ */
public static function byId(string $tableName, mixed $docId, ?PDO $pdo = null): bool public static function byId(string $tableName, mixed $docId): bool
{ {
return Custom::scalar(Query\Exists::byId($tableName), Parameters::id($docId), new ExistsMapper(), $pdo); return Custom::scalar(Query\Exists::byId($tableName), Parameters::id($docId), new ExistsMapper());
} }
/** /**
@ -29,16 +27,14 @@ class Exists
* *
* @param string $tableName The name of the table in which document existence should be determined * @param string $tableName The name of the table in which document existence should be determined
* @param Field[] $fields The field comparison to match * @param Field[] $fields The field comparison to match
* @param PDO|null $pdo The database connection to use (optional; will obtain one if not provided)
* @param string $conjunction How to handle multiple conditions (optional; defaults to `AND`) * @param string $conjunction How to handle multiple conditions (optional; defaults to `AND`)
* @return bool True if any documents match the field comparison, false if not * @return bool True if any documents match the field comparison, false if not
* @throws DocumentException If any is encountered * @throws DocumentException If any is encountered
*/ */
public static function byFields(string $tableName, array $fields, ?PDO $pdo = null, public static function byFields(string $tableName, array $fields, string $conjunction = 'AND'): bool
string $conjunction = 'AND'): bool
{ {
$namedFields = Parameters::nameFields($fields); $namedFields = Parameters::nameFields($fields);
return Custom::scalar(Query\Exists::byFields($tableName, $namedFields, $conjunction), return Custom::scalar(Query\Exists::byFields($tableName, $namedFields, $conjunction),
Parameters::addFields($namedFields, []), new ExistsMapper(), $pdo); Parameters::addFields($namedFields, []), new ExistsMapper());
} }
} }

View File

@ -2,8 +2,6 @@
namespace BitBadger\PDODocument; namespace BitBadger\PDODocument;
use PDO;
/** /**
* Functions to patch (partially update) documents * Functions to patch (partially update) documents
*/ */
@ -15,13 +13,12 @@ class Patch
* @param string $tableName The table in which the document should be patched * @param string $tableName The table in which the document should be patched
* @param mixed $docId The ID of the document to be patched * @param mixed $docId The ID of the document to be patched
* @param array|object $patch The object with which the document should be patched (will be JSON-encoded) * @param array|object $patch The object with which the document should be patched (will be JSON-encoded)
* @param PDO|null $pdo The database connection to use (optional; will obtain one if not provided)
* @throws DocumentException If any is encountered (database mode must be set) * @throws DocumentException If any is encountered (database mode must be set)
*/ */
public static function byId(string $tableName, mixed $docId, array|object $patch, ?PDO $pdo = null): void public static function byId(string $tableName, mixed $docId, array|object $patch): void
{ {
Custom::nonQuery(Query\Patch::byId($tableName), Custom::nonQuery(Query\Patch::byId($tableName),
array_merge(Parameters::id($docId), Parameters::json(':data', $patch)), $pdo); array_merge(Parameters::id($docId), Parameters::json(':data', $patch)));
} }
/** /**
@ -30,15 +27,14 @@ class Patch
* @param string $tableName The table in which documents should be patched * @param string $tableName The table in which documents should be patched
* @param array|Field[] $fields The field comparison to match * @param array|Field[] $fields The field comparison to match
* @param array|object $patch The object with which the documents should be patched (will be JSON-encoded) * @param array|object $patch The object with which the documents should be patched (will be JSON-encoded)
* @param PDO|null $pdo The database connection to use (optional; will obtain one if not provided)
* @param string $conjunction How to handle multiple conditions (optional; defaults to `AND`) * @param string $conjunction How to handle multiple conditions (optional; defaults to `AND`)
* @throws DocumentException If any is encountered * @throws DocumentException If any is encountered
*/ */
public static function byFields(string $tableName, array $fields, array|object $patch, ?PDO $pdo = null, public static function byFields(string $tableName, array $fields, array|object $patch,
string $conjunction = 'AND'): void string $conjunction = 'AND'): void
{ {
$namedFields = Parameters::nameFields($fields); $namedFields = Parameters::nameFields($fields);
Custom::nonQuery(Query\Patch::byFields($tableName, $namedFields, $conjunction), Custom::nonQuery(Query\Patch::byFields($tableName, $namedFields, $conjunction),
Parameters::addFields($namedFields, Parameters::json(':data', $patch)), $pdo); Parameters::addFields($namedFields, Parameters::json(':data', $patch)));
} }
} }

View File

@ -2,8 +2,6 @@
namespace BitBadger\PDODocument; namespace BitBadger\PDODocument;
use PDO;
/** /**
* Functions to remove fields from documents * Functions to remove fields from documents
*/ */
@ -15,14 +13,13 @@ class RemoveFields
* @param string $tableName The table in which the document should have fields removed * @param string $tableName The table in which the document should have fields removed
* @param mixed $docId The ID of the document from which fields should be removed * @param mixed $docId The ID of the document from which fields should be removed
* @param array|string[] $fieldNames The names of the fields to be removed * @param array|string[] $fieldNames The names of the fields to be removed
* @param PDO|null $pdo The database connection to use (optional; will obtain one if not provided)
* @throws DocumentException If any is encountered * @throws DocumentException If any is encountered
*/ */
public static function byId(string $tableName, mixed $docId, array $fieldNames, ?PDO $pdo = null): void public static function byId(string $tableName, mixed $docId, array $fieldNames): void
{ {
$nameParams = Parameters::fieldNames(':name', $fieldNames); $nameParams = Parameters::fieldNames(':name', $fieldNames);
Custom::nonQuery(Query\RemoveFields::byId($tableName, $nameParams), Custom::nonQuery(Query\RemoveFields::byId($tableName, $nameParams),
array_merge(Parameters::id($docId), $nameParams), $pdo); array_merge(Parameters::id($docId), $nameParams));
} }
/** /**
@ -31,16 +28,15 @@ class RemoveFields
* @param string $tableName The table in which documents should have fields removed * @param string $tableName The table in which documents should have fields removed
* @param array|Field[] $fields The field comparison to match * @param array|Field[] $fields The field comparison to match
* @param array|string[] $fieldNames The names of the fields to be removed * @param array|string[] $fieldNames The names of the fields to be removed
* @param PDO|null $pdo The database connection to use (optional; will obtain one if not provided)
* @param string $conjunction How to handle multiple conditions (optional; defaults to `AND`) * @param string $conjunction How to handle multiple conditions (optional; defaults to `AND`)
* @throws DocumentException If any is encountered * @throws DocumentException If any is encountered
*/ */
public static function byFields(string $tableName, array $fields, array $fieldNames, ?PDO $pdo = null, public static function byFields(string $tableName, array $fields, array $fieldNames,
string $conjunction = 'AND'): void string $conjunction = 'AND'): void
{ {
$nameParams = Parameters::fieldNames(':name', $fieldNames); $nameParams = Parameters::fieldNames(':name', $fieldNames);
$namedFields = Parameters::nameFields($fields); $namedFields = Parameters::nameFields($fields);
Custom::nonQuery(Query\RemoveFields::byFields($tableName, $namedFields, $nameParams, $conjunction), Custom::nonQuery(Query\RemoveFields::byFields($tableName, $namedFields, $nameParams, $conjunction),
Parameters::addFields($namedFields, $nameParams), $pdo); Parameters::addFields($namedFields, $nameParams));
} }
} }