mirror of
https://code.mensbeam.com/MensBeam/Arsse.git
synced 2024-12-23 09:02:41 +00:00
c21ae3eca9
This finally brings PostgreSQL to parity with SQLite and MySQL. Two tests casting binary data to text were removed since behaviour here should in fact be undefined Accountinf for any encoding when retrieving data will be addressed by a later commit
72 lines
2.3 KiB
PHP
72 lines
2.3 KiB
PHP
<?php
|
|
/** @license MIT
|
|
* Copyright 2017 J. King, Dustin Wilson et al.
|
|
* See LICENSE and AUTHORS files for details */
|
|
|
|
declare(strict_types=1);
|
|
namespace JKingWeb\Arsse\Db\PostgreSQL;
|
|
|
|
class Statement extends \JKingWeb\Arsse\Db\AbstractStatement {
|
|
use Dispatch;
|
|
|
|
protected const BINDINGS = [
|
|
self::T_INTEGER => "bigint",
|
|
self::T_FLOAT => "decimal",
|
|
self::T_DATETIME => "timestamp(0) without time zone",
|
|
self::T_BINARY => "bytea",
|
|
self::T_STRING => "text",
|
|
self::T_BOOLEAN => "smallint", // FIXME: using boolean leads to incompatibilities with versions of SQLite bundled prior to PHP 7.3
|
|
];
|
|
|
|
protected $db;
|
|
protected $in = [];
|
|
protected $query;
|
|
protected $qMunged;
|
|
protected $bindings;
|
|
|
|
public function __construct($db, string $query, array $bindings = []) {
|
|
$this->db = $db;
|
|
$this->query = $query;
|
|
$this->retypeArray($bindings);
|
|
}
|
|
|
|
public function runArray(array $values = []): \JKingWeb\Arsse\Db\Result {
|
|
$this->in = [];
|
|
$this->bindValues($values);
|
|
$r = $this->dispatchQuery($this->qMunged, $this->in);
|
|
$this->in = [];
|
|
if (is_resource($r)) {
|
|
return new Result($this->db, $r);
|
|
} else {
|
|
[$excClass, $excMsg, $excData] = $r;
|
|
throw new $excClass($excMsg, $excData);
|
|
}
|
|
}
|
|
|
|
protected function bindValue($value, int $type, int $position): bool {
|
|
if ($value !== null && ($this->types[$position - 1] % self::T_NOT_NULL) === self::T_BINARY) {
|
|
$value = "\\x".bin2hex($value);
|
|
}
|
|
$this->in[] = $value;
|
|
return true;
|
|
}
|
|
|
|
public static function mungeQuery(string $q, array $types, ...$extraData): string {
|
|
$mungeParamMarkers = (bool) ($extraData[0] ?? true);
|
|
$q = explode("?", $q);
|
|
$out = "";
|
|
for ($b = 1; $b < sizeof($q); $b++) {
|
|
$a = $b - 1;
|
|
$mark = $mungeParamMarkers ? "\$$b" : "?";
|
|
$type = isset($types[$a]) ? "::".self::BINDINGS[$types[$a] % self::T_NOT_NULL] : "";
|
|
$out .= $q[$a].$mark.$type;
|
|
}
|
|
$out .= array_pop($q);
|
|
return $out;
|
|
}
|
|
|
|
protected function prepare(string $query): bool {
|
|
$this->qMunged = $query;
|
|
return true;
|
|
}
|
|
}
|