Регистр файлов

This commit is contained in:
origami11 2017-02-16 10:14:36 +03:00
parent 4fd0187ea6
commit c8958cbee0
83 changed files with 25 additions and 53 deletions

408
src/Database.php Normal file
View file

@ -0,0 +1,408 @@
<?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;
}
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 = 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,$values=null)
{
$sth = $this->prepare($query);
$prep = $this->prepareValues($values);
$sth->execute($prep);
return $sth->fetchAll(PDO::FETCH_ASSOC);
}
/**
* Извлекает из базы первый элемент по запросу
*/
public function fetchOneArray($query,$values=null)
{
$sth = $this->prepare($query);
$prep = $this->prepareValues($values);
$sth->execute($prep);
return $sth->fetch(PDO::FETCH_ASSOC);
}
private 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)
{
return $this->query("UPDATE $table SET " . implode(",",
array_map(array($this, '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();
public $fields;
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;
}
}