début pgsql
This commit is contained in:
parent
ecd01777c1
commit
bab9ba81fe
@ -25,6 +25,7 @@
|
|||||||
"ext-pcntl": "*",
|
"ext-pcntl": "*",
|
||||||
"ext-curl": "*",
|
"ext-curl": "*",
|
||||||
"ext-pdo": "*",
|
"ext-pdo": "*",
|
||||||
|
"ext-pgsql": "*",
|
||||||
"ext-sqlite3": "*"
|
"ext-sqlite3": "*"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
|
@ -3,7 +3,6 @@ namespace nulib;
|
|||||||
|
|
||||||
use ArrayAccess;
|
use ArrayAccess;
|
||||||
use nulib\php\func;
|
use nulib\php\func;
|
||||||
use nulib\php\nur_func;
|
|
||||||
use Traversable;
|
use Traversable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -11,12 +11,13 @@ interface ITransactor {
|
|||||||
*/
|
*/
|
||||||
function willUpdate(...$transactors): self;
|
function willUpdate(...$transactors): self;
|
||||||
|
|
||||||
|
/** Indiquer si une transaction est en cours */
|
||||||
function inTransaction(): bool;
|
function inTransaction(): bool;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* démarrer une transaction
|
* démarrer une transaction
|
||||||
*
|
*
|
||||||
* si $func!==null, l'apppeler. ensuite, si $commit===true, commiter la
|
* si $func!==null, l'apppeler. ensuite, si $commit===true, valider la
|
||||||
* transaction. si une erreur se produit lors de l'appel de la fonction,
|
* transaction. si une erreur se produit lors de l'appel de la fonction,
|
||||||
* annuler la transaction
|
* annuler la transaction
|
||||||
*
|
*
|
||||||
@ -24,7 +25,9 @@ interface ITransactor {
|
|||||||
*/
|
*/
|
||||||
function beginTransaction(?callable $func=null, bool $commit=true): void;
|
function beginTransaction(?callable $func=null, bool $commit=true): void;
|
||||||
|
|
||||||
|
/** valider la transaction */
|
||||||
function commit(): void;
|
function commit(): void;
|
||||||
|
|
||||||
|
/** annuler la transaction */
|
||||||
function rollback(): void;
|
function rollback(): void;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace nulib\db\pdo;
|
namespace nulib\db\_private;
|
||||||
|
|
||||||
|
use nulib\db\IDatabase;
|
||||||
use nulib\php\func;
|
use nulib\php\func;
|
||||||
|
|
||||||
class _config {
|
class _config {
|
||||||
@ -23,12 +24,12 @@ class _config {
|
|||||||
/** @var array */
|
/** @var array */
|
||||||
protected $configs;
|
protected $configs;
|
||||||
|
|
||||||
function configure(Pdo $pdo): void {
|
function configure(IDatabase $db): void {
|
||||||
foreach ($this->configs as $key => $config) {
|
foreach ($this->configs as $key => $config) {
|
||||||
if (is_string($config) && !func::is_method($config)) {
|
if (is_string($config) && !func::is_method($config)) {
|
||||||
$pdo->exec($config);
|
$db->exec($config);
|
||||||
} else {
|
} else {
|
||||||
func::with($config)->bind($this, true)->invoke([$pdo, $key]);
|
func::with($config)->bind($this, true)->invoke([$db, $key]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -3,6 +3,7 @@ namespace nulib\db\pdo;
|
|||||||
|
|
||||||
use Generator;
|
use Generator;
|
||||||
use nulib\cl;
|
use nulib\cl;
|
||||||
|
use nulib\db\_private\_config;
|
||||||
use nulib\db\_private\Tvalues;
|
use nulib\db\_private\Tvalues;
|
||||||
use nulib\db\IDatabase;
|
use nulib\db\IDatabase;
|
||||||
use nulib\db\ITransactor;
|
use nulib\db\ITransactor;
|
||||||
@ -104,7 +105,7 @@ class Pdo implements IDatabase {
|
|||||||
protected ?array $dbconn;
|
protected ?array $dbconn;
|
||||||
|
|
||||||
/** @var array|callable */
|
/** @var array|callable */
|
||||||
protected array $options;
|
protected $options;
|
||||||
|
|
||||||
/** @var array|string|callable */
|
/** @var array|string|callable */
|
||||||
protected $config;
|
protected $config;
|
||||||
|
201
php/src/db/pgsql/Pgsql.php
Normal file
201
php/src/db/pgsql/Pgsql.php
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
<?php
|
||||||
|
namespace nulib\db\pgsql;
|
||||||
|
|
||||||
|
use nulib\cl;
|
||||||
|
use nulib\db\_private\_config;
|
||||||
|
use nulib\db\_private\Tvalues;
|
||||||
|
use nulib\db\IDatabase;
|
||||||
|
use nulib\db\ITransactor;
|
||||||
|
use nulib\php\func;
|
||||||
|
|
||||||
|
class Pgsql implements IDatabase {
|
||||||
|
use Tvalues;
|
||||||
|
|
||||||
|
static function with($pgsql, ?array $params=null): self {
|
||||||
|
if ($pgsql instanceof static) {
|
||||||
|
return $pgsql;
|
||||||
|
} elseif ($pgsql instanceof self) {
|
||||||
|
# recréer avec les mêmes paramètres
|
||||||
|
return new static(null, cl::merge([
|
||||||
|
"dbconn" => $pgsql->dbconn,
|
||||||
|
"options" => $pgsql->options,
|
||||||
|
"config" => $pgsql->config,
|
||||||
|
"migrate" => $pgsql->migration,
|
||||||
|
], $params));
|
||||||
|
} else {
|
||||||
|
return new static($pgsql, $params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected const OPTIONS = [
|
||||||
|
"persistent" => true,
|
||||||
|
"force_new" => false,
|
||||||
|
];
|
||||||
|
|
||||||
|
const CONFIG = null;
|
||||||
|
|
||||||
|
const MIGRATE = null;
|
||||||
|
|
||||||
|
const params_SCHEMA = [
|
||||||
|
"dbconn" => ["array"],
|
||||||
|
"options" => ["?array|callable"],
|
||||||
|
"replace_config" => ["?array|callable"],
|
||||||
|
"config" => ["?array|callable"],
|
||||||
|
"migrate" => ["?array|string|callable"],
|
||||||
|
"auto_open" => ["bool", true],
|
||||||
|
];
|
||||||
|
|
||||||
|
const dbconn_SCHEMA = [
|
||||||
|
"" => "?string",
|
||||||
|
"host" => "string",
|
||||||
|
"hostaddr" => "?string",
|
||||||
|
"port" => "?int",
|
||||||
|
"dbname" => "string",
|
||||||
|
"user" => "string",
|
||||||
|
"password" => "string",
|
||||||
|
"connect_timeout" => "?int",
|
||||||
|
"options" => "?string",
|
||||||
|
"sslmode" => "?string",
|
||||||
|
"service" => "?string",
|
||||||
|
];
|
||||||
|
|
||||||
|
protected const dbconn_MAP = [
|
||||||
|
"name" => "dbname",
|
||||||
|
"pass" => "password",
|
||||||
|
];
|
||||||
|
|
||||||
|
const options_SCHEMA = [
|
||||||
|
"persistent" => ["bool", self::OPTIONS["persistent"]],
|
||||||
|
"force_new" => ["bool", self::OPTIONS["force_new"]],
|
||||||
|
];
|
||||||
|
|
||||||
|
function __construct($dbconn=null, ?array $params=null) {
|
||||||
|
if ($dbconn !== null) {
|
||||||
|
if (!is_array($dbconn)) {
|
||||||
|
$dbconn = ["" => $dbconn];
|
||||||
|
#XXX à terme, il faudra interroger config
|
||||||
|
#$tmp = config::db($dbconn);
|
||||||
|
#if ($tmp !== null) $dbconn = $tmp;
|
||||||
|
#else $dbconn = ["" => $dbconn];
|
||||||
|
}
|
||||||
|
$params["dbconn"] = $dbconn;
|
||||||
|
}
|
||||||
|
# dbconn
|
||||||
|
$this->dbconn = $params["dbconn"] ?? null;
|
||||||
|
# options
|
||||||
|
$this->options = $params["options"] ?? static::OPTIONS;
|
||||||
|
# configuration
|
||||||
|
$config = $params["replace_config"] ?? null;
|
||||||
|
if ($config === null) {
|
||||||
|
$config = $params["config"] ?? static::CONFIG;
|
||||||
|
if (is_callable($config)) $config = [$config];
|
||||||
|
}
|
||||||
|
$this->config = $config;
|
||||||
|
# migrations
|
||||||
|
$this->migration = $params["migrate"] ?? static::MIGRATE;
|
||||||
|
#
|
||||||
|
$defaultAutoOpen = self::params_SCHEMA["auto_open"][1];
|
||||||
|
if ($params["auto_open"] ?? $defaultAutoOpen) {
|
||||||
|
$this->open();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ?array $dbconn;
|
||||||
|
|
||||||
|
/** @var array|callable|null */
|
||||||
|
protected $options;
|
||||||
|
|
||||||
|
/** @var array|string|callable */
|
||||||
|
protected $config;
|
||||||
|
|
||||||
|
/** @var array|string|callable */
|
||||||
|
protected $migration;
|
||||||
|
|
||||||
|
/** @var resource */
|
||||||
|
protected $db = null;
|
||||||
|
|
||||||
|
function open(): self {
|
||||||
|
if ($this->db === null) {
|
||||||
|
$dbconn = $this->dbconn;
|
||||||
|
$connection_string = [$dbconn[""] ?? null];
|
||||||
|
unset($dbconn[""]);
|
||||||
|
foreach ($dbconn as $key => $value) {
|
||||||
|
if ($value === null) continue;
|
||||||
|
$value = strval($value);
|
||||||
|
if ($value === "" || preg_match("/[ '\\\\]/", $value)) {
|
||||||
|
$value = str_replace("\\", "\\\\", $value);
|
||||||
|
$value = str_replace("'", "\\'", $value);
|
||||||
|
$value = "'$value'";
|
||||||
|
}
|
||||||
|
$key = cl::get(self::dbconn_MAP, $key, $key);
|
||||||
|
$connection_string[] = "$key=$value";
|
||||||
|
}
|
||||||
|
$connection_string = implode(" ", array_filter($connection_string));
|
||||||
|
$options = $this->options;
|
||||||
|
if (is_callable($options)) {
|
||||||
|
$options = func::with($options)->bind($this, true)->invoke();
|
||||||
|
}
|
||||||
|
$forceNew = $options["force_new"] ?? false;
|
||||||
|
$flags = $forceNew? PGSQL_CONNECT_FORCE_NEW: 0;
|
||||||
|
|
||||||
|
if ($options["persistent"] ?? true) $db = pg_pconnect($connection_string, $flags);
|
||||||
|
else $db = pg_connect($connection_string, $flags);
|
||||||
|
if ($db === false) throw new PgsqlException("unable to connect");
|
||||||
|
$this->db = $db;
|
||||||
|
|
||||||
|
_config::with($this->config)->configure($this);
|
||||||
|
//_migration::with($this->migration)->migrate($this);
|
||||||
|
}
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
function close(): self {
|
||||||
|
if ($this->db !== null) {
|
||||||
|
pg_close($this->db);
|
||||||
|
$this->db = null;
|
||||||
|
}
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function db() {
|
||||||
|
$this->open();
|
||||||
|
return $this->db;
|
||||||
|
}
|
||||||
|
|
||||||
|
function exec($query, ?array $params = null) {
|
||||||
|
// TODO: Implement exec() method.
|
||||||
|
}
|
||||||
|
|
||||||
|
function willUpdate(...$transactors): \nulib\db\ITransactor {
|
||||||
|
// TODO: Implement willUpdate() method.
|
||||||
|
}
|
||||||
|
|
||||||
|
function inTransaction(): bool {
|
||||||
|
// TODO: Implement inTransaction() method.
|
||||||
|
}
|
||||||
|
|
||||||
|
function beginTransaction(?callable $func = null, bool $commit = true): void {
|
||||||
|
// TODO: Implement beginTransaction() method.
|
||||||
|
}
|
||||||
|
|
||||||
|
function commit(): void {
|
||||||
|
// TODO: Implement commit() method.
|
||||||
|
}
|
||||||
|
|
||||||
|
function rollback(): void {
|
||||||
|
// TODO: Implement rollback() method.
|
||||||
|
}
|
||||||
|
|
||||||
|
function get($query, ?array $params = null, bool $entireRow = false) {
|
||||||
|
// TODO: Implement get() method.
|
||||||
|
}
|
||||||
|
|
||||||
|
function one($query, ?array $params = null): ?array {
|
||||||
|
// TODO: Implement one() method.
|
||||||
|
}
|
||||||
|
|
||||||
|
function all($query, ?array $params = null, $primaryKeys = null): iterable {
|
||||||
|
// TODO: Implement all() method.
|
||||||
|
}
|
||||||
|
}
|
12
php/src/db/pgsql/PgsqlException.php
Normal file
12
php/src/db/pgsql/PgsqlException.php
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
namespace nulib\db\pgsql;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
use RuntimeException;
|
||||||
|
use SQLite3;
|
||||||
|
|
||||||
|
class PgsqlException extends RuntimeException {
|
||||||
|
static final function wrap(Exception $e): self {
|
||||||
|
return new static($e->getMessage(), $e->getCode(), $e);
|
||||||
|
}
|
||||||
|
}
|
@ -3,6 +3,7 @@ namespace nulib\db\sqlite;
|
|||||||
|
|
||||||
use Generator;
|
use Generator;
|
||||||
use nulib\cl;
|
use nulib\cl;
|
||||||
|
use nulib\db\_private\_config;
|
||||||
use nulib\db\_private\Tvalues;
|
use nulib\db\_private\Tvalues;
|
||||||
use nulib\db\IDatabase;
|
use nulib\db\IDatabase;
|
||||||
use nulib\db\ITransactor;
|
use nulib\db\ITransactor;
|
||||||
|
@ -1,35 +0,0 @@
|
|||||||
<?php
|
|
||||||
namespace nulib\db\sqlite;
|
|
||||||
|
|
||||||
use nulib\php\func;
|
|
||||||
|
|
||||||
class _config {
|
|
||||||
static function with($configs): self {
|
|
||||||
if ($configs instanceof static) return $configs;
|
|
||||||
return new static($configs);
|
|
||||||
}
|
|
||||||
|
|
||||||
const CONFIG = null;
|
|
||||||
|
|
||||||
function __construct($configs) {
|
|
||||||
if ($configs === null) $configs = static::CONFIG;
|
|
||||||
if ($configs === null) $configs = [];
|
|
||||||
elseif (is_string($configs)) $configs = [$configs];
|
|
||||||
elseif (is_callable($configs)) $configs = [$configs];
|
|
||||||
elseif (!is_array($configs)) $configs = [strval($configs)];
|
|
||||||
$this->configs = $configs;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @var array */
|
|
||||||
protected $configs;
|
|
||||||
|
|
||||||
function configure(Sqlite $sqlite): void {
|
|
||||||
foreach ($this->configs as $key => $config) {
|
|
||||||
if (is_string($config) && !func::is_method($config)) {
|
|
||||||
$sqlite->exec($config);
|
|
||||||
} else {
|
|
||||||
func::with($config)->bind($this, true)->invoke([$sqlite, $key]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -2,7 +2,6 @@
|
|||||||
namespace nulib\db\sqlite;
|
namespace nulib\db\sqlite;
|
||||||
|
|
||||||
use nulib\php\func;
|
use nulib\php\func;
|
||||||
use nulib\php\nur_func;
|
|
||||||
|
|
||||||
class _migration {
|
class _migration {
|
||||||
static function with($migrations): self {
|
static function with($migrations): self {
|
||||||
|
@ -6,7 +6,6 @@ use nulib\cl;
|
|||||||
use nulib\file\TempStream;
|
use nulib\file\TempStream;
|
||||||
use nulib\os\path;
|
use nulib\os\path;
|
||||||
use nulib\php\func;
|
use nulib\php\func;
|
||||||
use nulib\php\nur_func;
|
|
||||||
use nulib\php\time\DateTime;
|
use nulib\php\time\DateTime;
|
||||||
use nulib\web\http;
|
use nulib\web\http;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user