phplibrary/src/Database.php

196 lines
6.1 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
///<reference path="Database/PDOStatement.php" />
namespace {
if(!function_exists('sqliteLower')){
function sqliteLower($str) {
return mb_strtolower($str, 'UTF-8');
}
}
}
namespace ctiso {
use PDO,
ctiso\Database\Statement,
ctiso\Database\PDOStatement,
ctiso\Database\IdGenerator;
/**
* Класс оболочка для PDO для замены Creole
*/
class Database/*<Database_PDOStatement>*/ extends PDO
{
public $dsn;
public function __construct($dsn, $username = null, $password = null)
{
parent::__construct($dsn, $username, $password);
$this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
$this->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('ctiso\\Database\\PDOStatement', array()));
}
function prepare($sql, $args = []) {
$result/*: PDOStatement*/ = parent::prepare($sql, $args);
return $result;
}
public function getDSN()
{
return $this->dsn;
}
public function isPostgres(){
return ($this->dsn["phptype"] == "pgsql");
}
/**
* Создает соединение с базой данных
*/
static function getConnection(array $dsn)
{
if ($dsn['phptype'] == 'pgsql' || $dsn['phptype'] == 'mysql') {
$port = (isset($dsn['port'])) ? "port={$dsn['port']};" : "";
$connection/*: Database*/ = new static("{$dsn['phptype']}:host={$dsn['hostspec']}; $port dbname={$dsn['database']}", $dsn['username'], $dsn['password']);
if ($dsn['phptype'] == 'pgsql') {
$connection->query('SET client_encoding="UTF-8"');
}
if (isset($dsn['schema'])) {
$connection->query('SET search_path TO ' . $dsn['schema']);
}
}
if ($dsn['phptype'] == 'sqlite') {
$connection/*: Database*/ = new static("{$dsn['phptype']}:{$dsn['database']}");
$connection->setAttribute(PDO::ATTR_TIMEOUT, 5);
$mode = defined('SQLITE_JOURNAL_MODE') ? SQLITE_JOURNAL_MODE : 'WAL';
$connection->query("PRAGMA journal_mode=$mode");
$connection->sqliteCreateFunction('LOWER', 'sqliteLower', 1);
}
$connection->dsn = $dsn;
return $connection;
}
public function executeQuery($query, $values=null)
{
$stmt/*: PDOStatement*/ = $this->prepare($query);
$stmt->execute($values);
$stmt->cache = $stmt->fetchAll(PDO::FETCH_ASSOC);
return $stmt;
}
public function prepareStatement($query)
{
return new Statement($query, $this);
}
// Для совместимости со старым представлением баз данных CIS
/**
* Извлекает из базы все элементы по запросу
*/
public function fetchAllArray($query, $values = null)
{
$sth/*: PDOStatement*/ = $this->prepare($query);
$prep = $this->prepareValues($values);
$sth->execute($prep);
return $sth->fetchAll(PDO::FETCH_ASSOC);
}
/**
* Извлекает из базы первый элемент по запросу
*/
public function fetchOneArray($query, $values = null)
{
$sth/*: PDOStatement*/ = $this->prepare($query);
$prep = $this->prepareValues($values);
$sth->execute($prep);
return $sth->fetch(PDO::FETCH_ASSOC);
}
private static function assignQuote($x, $y)
{
return $x . "=" . $this->quote($y);
}
private function prepareValues($values)
{
if (!$values) {
return null;
}
$pg = $this->isPostgres();
$prep = array();
foreach ($values as $key => $value) {
$result = null;
if(is_bool($value)) {
if ($pg) {
$result = $value ? 'true' : 'false';
} else {
$result = $value ? 1 : 0;
}
} else {
$result = $value;
}
$prep[":" . $key] = $result;
}
return $prep;
}
/**
* Создает INSERT запрос
*/
function insertQuery($table, array $values, $return_id = false, $index = null)
{
$prep = $this->prepareValues($values);
$sql = "INSERT INTO $table (" . implode(",", array_keys($values))
. ") VALUES (" . implode(",", array_keys($prep)). ")";
if ($return_id) {
if ($this->isPostgres()){
$sql = $sql." RETURNING $index";
}
}
$stmt = $this->prepare($sql);
$stmt->setFetchMode(PDO::FETCH_ASSOC);
$stmt->execute($prep);
$result = $stmt->fetch();
if ($return_id) {
if ($this->isPostgres()) {
return $result[$index];
} else {
$result = $this->fetchOneArray("SELECT $index AS lastid FROM $table WHERE OID = last_insert_rowid()");
return $result['lastid'];
}
}
}
/**
* Создает UPDATE запрос
*/
function updateQuery($table, array $values, $cond)
{
$prep = $this->prepareValues($values);
$sql = "UPDATE $table SET " . implode(",",
array_map(function($k,$v){return $k."=".$v;}, array_keys($values), array_keys($prep))) . " WHERE $cond";
$stmt = $this->prepare($sql);
$stmt->setFetchMode(PDO::FETCH_ASSOC);
$stmt->execute($prep);
}
function getIdGenerator() {
return new IdGenerator($this);
}
/**
* Замечание: Только для Postgres SQL
* @param string $seq Имя последовательности для ключа таблицы
* @return int Идентефикатор следующей записи
*/
function getNextId($seq) {
$result = $this->fetchOneArray("SELECT nextval('$seq')");
return $result['nextval'];
}
function close() {
return null;
}
}}