phplibrary/core/database_pdo.php
Фёдор Подлеснов 5dac5a6e19 utf-8
2016-10-07 16:01:47 +03:00

362 lines
8.2 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
/**
* @package system.db
* Класс оболочка для PDO для замены Creole
*/
class Database extends PDO
{
public function __construct($dsn, $username = false, $password = false)
{
parent::__construct($dsn, $username, $password);
$this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('PDODatabaseStatement', array()));
}
public function getDSN()
{
return $this->dsn;
}
/**
* Создает соединение с базой данных
*/
static function getConnection(array $dsn)
{
if ($dsn['phptype'] == 'pgsql' || $dsn['phptype'] == 'mysql') {
$port = (isset($dsn['port'])) ? "port={$dsn['port']};" : "";
$connection = new Database("{$dsn['phptype']}:host={$dsn['hostspec']}; $port dbname={$dsn['database']}", $dsn['username'], $dsn['password']);
$connection->query('SET client_encoding = "UTF-8"');
}
if ($dsn['phptype'] == 'sqlite') {
$connection = new Database("{$dsn['phptype']}:{$dsn['database']}");
}
$connection->dsn = $dsn;
return $connection;
}
public function executeQuery($query)
{
$stmt = $this->prepare($query);
$stmt->setFetchMode(PDO::FETCH_ASSOC);
$stmt->execute();
$stmt->cache = $stmt->fetchAll();
return $stmt;//$sth->fetchAll();
}
public function prepareStatement($query)
{
return new DatabaseStatement($query, $this);
}
// Для совместимости со старым представлением баз данных CIS
/**
* Извлекает из базы все элементы по запросу
*/
public function fetchAllArray($query)
{
$sth = $this->prepare($query);
$sth->setFetchMode(PDO::FETCH_ASSOC);
$sth->execute();
return $sth->fetchAll();
}
/**
* Извлекает из базы первый элемент по запросу
*/
public function fetchOneArray($query)
{
$sth = $this->prepare($query);
$sth->setFetchMode(PDO::FETCH_ASSOC);
$sth->execute();
return $sth->fetch();
}
private static function assignQuote($x, $y)
{
return $x . "=" . $this->quote($y);
}
/**
* Создает INSERT запрос
*/
function insertQuery($table, array $values)
{
return $this->query("INSERT INTO $table (" . implode(",", array_keys($values))
. ") VALUES (" . implode(",", array_map(array($this, 'quote'), array_values($values))) . ")");
}
/**
* Создает UPDATE запрос
*/
function updateQuery($table, array $values, $cond)
{
return $this->query("UPDATE $table SET " . implode(",",
array_map(array('self', 'assignQuote'), array_keys($values), array_values($values))) . " WHERE $cond");
}
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;
}
}
class IdGenerator {
private $db;
function __construct($db) {
$this->db = $db;
}
function isBeforeInsert() {
return false;
}
function isAfterInsert() {
return true;
}
function getId($seq) {
$result = $this->db->fetchOneArray("SELECT nextval('$seq')");
return $result['nextval'];
// $result = $this->db->fetchOneArray("SELECT last_insert_rowid() AS nextval");
// return $result['nextval'];
}
}
class PDODatabaseStatementIterator implements Iterator
{
private $result;
private $pos = 0;
private $fetchmode;
private $row_count;
private $rs;
/**
* Construct the iterator.
* @param PgSQLResultSet $rs
*/
public function __construct($rs)
{
$this->result = $rs;
$this->row_count = $rs->getRecordCount();
}
function rewind()
{
$this->pos = 0;
}
function valid()
{
return ($this->pos < $this->row_count);
}
function key()
{
return $this->pos;
}
function current()
{
if (!isset($this->result->cache[$this->pos])) {
$this->result->cache[$this->pos] = $this->result->fetch(PDO::FETCH_ASSOC);
}
return $this->result->cache[$this->pos];
}
function next()
{
$this->pos++;
}
function seek ( $index )
{
$this->pos = $index;
}
function count ( ) {
return $this->row_count;
}
}
class PDODatabaseStatement extends PDOStatement implements IteratorAggregate
{
protected $cursorPos = 0;
public $cache = array();
function getIterator()
{
return new PDODatabaseStatementIterator($this);
}
protected function __construct() {
}
function rewind()
{
$this->cursorPos = 0;
}
public function seek($rownum)
{
if ($rownum < 0) {
return false;
}
// PostgreSQL rows start w/ 0, but this works, because we are
// looking to move the position _before_ the next desired position
$this->cursorPos = $rownum;
return true;
}
function valid()
{
return ( true );
}
public function first()
{
if($this->cursorPos !== 0) { $this->seek(0); }
return $this->next();
}
function next()
{
if ($this->getRecordCount() > $this->cursorPos) {
if (!isset($this->cache[$this->cursorPos])) {
$this->cache[$this->cursorPos] = $this->fetch(PDO::FETCH_ASSOC);
}
$this->fields = $this->cache[$this->cursorPos];
$this->cursorPos++;
return true;
} else {
$this->fields = null;
return false;
}
}
function key() {
return $this->cursorPos;
}
function current()
{
return $this->result->fetch(PDO::FETCH_ASSOC);
}
function getRow()
{
return $this->fields;
}
function getInt($name)
{
return intval($this->fields[$name]);
}
function getBlob($name)
{
return $this->fields[$name];
}
function getString($name)
{
return $this->fields[$name];
}
function getBoolean($name)
{
return (bool)$this->fields[$name];
}
function get($name)
{
return $this->fields[$name];
}
function getRecordCount()
{
return count($this->cache);
}
}
/**
* Класс оболочка для PDOStatement для замены Creole
*/
class DatabaseStatement
{
protected $limit = null;
protected $offset = null;
protected $statement = null;
protected $binds = array();
protected $conn;
protected $query;
function __construct($query, $conn) {
$this->query = $query;
$this->conn = $conn;
}
function setInt($n, $value)
{
$this->binds [] = array($n, $value, PDO::PARAM_INT);
}
function setString($n, $value)
{
$this->binds [] = array($n, $value, PDO::PARAM_STR);
}
function setBlob($n, $value)
{
$this->binds [] = array($n, $value, PDO::PARAM_LOB);
}
function setLimit($limit)
{
$this->limit = $limit;
}
function setOffset($offset)
{
$this->offset = $offset;
}
function executeQuery()
{
if ($this->limit) {
$this->query .= " LIMIT {$this->limit} OFFSET {$this->offset}";
}
$stmt = $this->conn->prepare($this->query);
foreach ($this->binds as $bind) {
list($n, $value, $type) = $bind;
$stmt->bindValue($n, $value, $type);
}
$stmt->setFetchMode(PDO::FETCH_ASSOC);
$stmt->execute();
$stmt->cache = $stmt->fetchAll();
return $stmt;
}
}