%PDF- %PDF-
Direktori : /www/varak.net/losik.varak.net/vendor/dibi/dibi/src/Dibi/Drivers/ |
Current File : //www/varak.net/losik.varak.net/vendor/dibi/dibi/src/Dibi/Drivers/FirebirdDriver.php |
<?php /** * This file is part of the Dibi, smart database abstraction layer (https://dibiphp.com) * Copyright (c) 2005 David Grudl (https://davidgrudl.com) */ declare(strict_types=1); namespace Dibi\Drivers; use Dibi; use Dibi\Helpers; /** * The driver for Firebird/InterBase database. * * Driver options: * - database => the path to database file (server:/path/database.fdb) * - username (or user) * - password (or pass) * - charset => character encoding to set * - buffers (int) => buffers is the number of database buffers to allocate for the server-side cache. If 0 or omitted, server chooses its own default. * - resource (resource) => existing connection resource */ class FirebirdDriver implements Dibi\Driver { use Dibi\Strict; public const ERROR_EXCEPTION_THROWN = -836; /** @var resource */ private $connection; /** @var resource|null */ private $transaction; /** @var bool */ private $inTransaction = false; /** @throws Dibi\NotSupportedException */ public function __construct(array $config) { if (!extension_loaded('interbase')) { throw new Dibi\NotSupportedException("PHP extension 'interbase' is not loaded."); } Helpers::alias($config, 'database', 'db'); if (isset($config['resource'])) { $this->connection = $config['resource']; } else { // default values $config += [ 'username' => ini_get('ibase.default_password'), 'password' => ini_get('ibase.default_user'), 'database' => ini_get('ibase.default_db'), 'charset' => ini_get('ibase.default_charset'), 'buffers' => 0, ]; $this->connection = empty($config['persistent']) ? @ibase_connect($config['database'], $config['username'], $config['password'], $config['charset'], $config['buffers']) // intentionally @ : @ibase_pconnect($config['database'], $config['username'], $config['password'], $config['charset'], $config['buffers']); // intentionally @ if (!is_resource($this->connection)) { throw new Dibi\DriverException(ibase_errmsg(), ibase_errcode()); } } } /** * Disconnects from a database. */ public function disconnect(): void { @ibase_close($this->connection); // @ - connection can be already disconnected } /** * Executes the SQL query. * @throws Dibi\DriverException|Dibi\Exception */ public function query(string $sql): ?Dibi\ResultDriver { $resource = $this->inTransaction ? $this->transaction : $this->connection; $res = ibase_query($resource, $sql); if ($res === false) { if (ibase_errcode() === self::ERROR_EXCEPTION_THROWN) { preg_match('/exception (\d+) (\w+) (.*)/i', ibase_errmsg(), $match); throw new Dibi\ProcedureException($match[3], $match[1], $match[2], $sql); } else { throw new Dibi\DriverException(ibase_errmsg(), ibase_errcode(), $sql); } } elseif (is_resource($res)) { return $this->createResultDriver($res); } return null; } /** * Gets the number of affected rows by the last INSERT, UPDATE or DELETE query. */ public function getAffectedRows(): ?int { return Helpers::false2Null(ibase_affected_rows($this->connection)); } /** * Retrieves the ID generated for an AUTO_INCREMENT column by the previous INSERT query. */ public function getInsertId(?string $sequence): ?int { return Helpers::false2Null(ibase_gen_id($sequence, 0, $this->connection)); } /** * Begins a transaction (if supported). * @throws Dibi\DriverException */ public function begin(?string $savepoint = null): void { if ($savepoint !== null) { throw new Dibi\NotSupportedException('Savepoints are not supported in Firebird/Interbase.'); } $this->transaction = ibase_trans($this->getResource()); $this->inTransaction = true; } /** * Commits statements in a transaction. * @throws Dibi\DriverException */ public function commit(?string $savepoint = null): void { if ($savepoint !== null) { throw new Dibi\NotSupportedException('Savepoints are not supported in Firebird/Interbase.'); } if (!ibase_commit($this->transaction)) { throw new Dibi\DriverException('Unable to handle operation - failure when commiting transaction.'); } $this->inTransaction = false; } /** * Rollback changes in a transaction. * @throws Dibi\DriverException */ public function rollback(?string $savepoint = null): void { if ($savepoint !== null) { throw new Dibi\NotSupportedException('Savepoints are not supported in Firebird/Interbase.'); } if (!ibase_rollback($this->transaction)) { throw new Dibi\DriverException('Unable to handle operation - failure when rolbacking transaction.'); } $this->inTransaction = false; } /** * Is in transaction? */ public function inTransaction(): bool { return $this->inTransaction; } /** * Returns the connection resource. * @return resource|null */ public function getResource() { return is_resource($this->connection) ? $this->connection : null; } /** * Returns the connection reflector. */ public function getReflector(): Dibi\Reflector { return new FirebirdReflector($this); } /** * Result set driver factory. * @param resource $resource */ public function createResultDriver($resource): FirebirdResult { return new FirebirdResult($resource); } /********************* SQL ********************/ /** * Encodes data for use in a SQL statement. */ public function escapeText(string $value): string { return "'" . str_replace("'", "''", $value) . "'"; } public function escapeBinary(string $value): string { return "'" . str_replace("'", "''", $value) . "'"; } public function escapeIdentifier(string $value): string { return '"' . str_replace('"', '""', $value) . '"'; } public function escapeBool(bool $value): string { return $value ? '1' : '0'; } public function escapeDate(\DateTimeInterface $value): string { return $value->format("'Y-m-d'"); } public function escapeDateTime(\DateTimeInterface $value): string { return "'" . substr($value->format('Y-m-d H:i:s.u'), 0, -2) . "'"; } public function escapeDateInterval(\DateInterval $value): string { throw new Dibi\NotImplementedException; } /** * Encodes string for use in a LIKE statement. */ public function escapeLike(string $value, int $pos): string { $value = addcslashes($this->escapeText($value), '%_\\'); return ($pos & 1 ? "'%" : "'") . $value . ($pos & 2 ? "%'" : "'") . " ESCAPE '\\'"; } /** * Injects LIMIT/OFFSET to the SQL query. */ public function applyLimit(string &$sql, ?int $limit, ?int $offset): void { if ($limit > 0 || $offset > 0) { // http://www.firebirdsql.org/refdocs/langrefupd20-select.html $sql = 'SELECT ' . ($limit > 0 ? 'FIRST ' . $limit : '') . ($offset > 0 ? ' SKIP ' . $offset : '') . ' * FROM (' . $sql . ')'; } } }