Advertisement
stuppid_bot

Untitled

Jul 16th, 2014
325
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 6.96 KB | None | 0 0
  1. <?php
  2.  
  3. abstract class ORM_DataBase {
  4.     public $pdo;
  5.     protected $_queryCache = [];
  6.     protected $_columnCache = [];
  7.     protected $_rowCache = [];
  8.  
  9.     /*
  10.  
  11.     Должна возвращать структуру типа этой:
  12.  
  13.     [
  14.         'columns' =>
  15.         [
  16.             0 => 'id',
  17.             1 => 'cat_id',
  18.             2 => 'author_id',
  19.             3 => 'title',
  20.             4 => 'content',
  21.         ],
  22.         'pk' => 'id',
  23.         'foreign_keys' =>
  24.         [
  25.             0 =>
  26.             [
  27.                 'name' => 'category',
  28.                 'key' => 'cat_id',
  29.                 'ref_table' => 'categories',
  30.                 'ref_key' => 'id',
  31.             ],
  32.         ],
  33.     ]
  34.  
  35.     */
  36.     abstract public function columns($table);
  37.  
  38.     // переопределить в случае необходимости
  39.     public function quoteName($name) {
  40.         return $this->quote($name);
  41.     }
  42.  
  43.     public function __construct(PDO $pdo) {
  44.         $this->pdo = $pdo;
  45.     }
  46.  
  47.     // возвращает ряд в виде объекта ActiveRecord
  48.     public function row($table) {
  49.         $t = $this;
  50.         $columns = isset($t->_columnCache[$table]) ?
  51.                    $t->_columnCache[$table] :
  52.                    $t->_columnCache[$table] = $t->columns($table);
  53.         extract($columns);
  54.         $r = new ORM_Row($t, $table, $pk, $columns, $foreign_keys);
  55.         return $r;
  56.     }
  57.  
  58.     // ищет одну запись по $id, если $k не указан, то при поиске использует
  59.     // primary key
  60.     public function find($table, $id, $k=null) {
  61.         $t = $this;
  62.         $cache = &$t->_rowCache;
  63.  
  64.         if ( isset($t->_rowCache[$table][$k][$id]) ) {
  65.             return $t->_rowCache[$table][$k][$id];
  66.         }
  67.            
  68.         $row = $t->row($table);
  69.         $row->load($id, $k);
  70.         return $t->_rowCache[$table][$k][$id] = $row;
  71.     }
  72.  
  73.     // ! кешируются только вложенные ряды.
  74.     public function findMany($table, $where=1, $limit=25, $offset=0, $order=1) {
  75.         $t = $this;
  76.         $objects = [];
  77.         $tbl = $t->quotename($table);
  78.         $arr = $t->get("SELECT * FROM $tbl WHERE $where ORDER BY $order LIMIT $offset,$limit");
  79.  
  80.         foreach ($arr as $v) {
  81.             $row = $t->row($table);
  82.             $row->setup($v);
  83.             $objects[] = $t->_rowCache[$table][$row->pk()][$row->id()] = $row;
  84.         }
  85.  
  86.         return $objects;
  87.     }
  88.  
  89.     public function execute($query, array $bindings=[]) {
  90.         $t = $this;
  91.  
  92.         if (ORM::DEBUG) {
  93.             echo '<br><b>SQL запрос:</b>';
  94.             echo dump($query);
  95.         }
  96.  
  97.         $h = md5($query);
  98.  
  99.         if (isset($t->_queryCache[$h])) {
  100.             if (ORM::DEBUG) {
  101.                 echo '<br>Берем из кеша.';
  102.             }
  103.  
  104.             $s = $t->_queryCache[$h];
  105.         }
  106.         else {
  107.             $s = $t->pdo->prepare($query);
  108.             $t->_queryCache[$h] = $s;
  109.         }
  110.  
  111.         $s->execute($bindings);
  112.         preg_match('/^\s*(\w+)/', $query, $m);
  113.         $action = strtolower($m[1]);
  114.  
  115.         if ($action == 'update' or $action == 'delete') {
  116.             return $s->rowCount();
  117.         }
  118.  
  119.         if ($action == 'insert') {
  120.             return $t->lastInsertId();
  121.         }
  122.  
  123.         return $s;
  124.     }
  125.  
  126.     public function get($query, array $bindings=[],
  127.                         $fetch_type=ORM::FETCH_ALL) {
  128.         $r = $this->execute($query, $bindings);
  129.  
  130.         if ($fetch_type & ORM::FETCH_COLUMN) {
  131.             return $r->fetchColumn();
  132.         }
  133.  
  134.         if ($fetch_type & ORM::FETCH_ONE) {
  135.             return $r->fetch(PDO::FETCH_ASSOC);
  136.         }
  137.  
  138.         return $r->fetchAll(PDO::FETCH_ASSOC);
  139.     }
  140.  
  141.     public function one($query, array $bindings=[]) {
  142.         return $this->get($query, $bindings, ORM::FETCH_ONE);
  143.     }
  144.  
  145.     public function col($query, array $bindings=[]) {
  146.         return $this->get($query, $bindings, ORM::FETCH_COLUMN);
  147.     }
  148.  
  149.     public function count($table, $where=1, array $bindings=[]) {
  150.         $t = $this;
  151.         $tbl = $t->quotename($table);
  152.         $q = "SELECT COUNT(*) FROM $tbl WHERE $where";
  153.         return (int) $t->col($q, $bindings);
  154.     }
  155.  
  156.     // например нужно проверить зарегистрирован ли пользователь с таким
  157.     // именем, конечно можно попытаться вставить запись INSERT'ом, но
  158.     // так увеличится счетчик id.
  159.     public function noexists($table, $k, $v) {
  160.         return !$this->count($table, $this->quotename($k) . '=?', [$v,]);
  161.     }
  162.  
  163.     public function add($table, array $data) {
  164.         $t = $this;
  165.         $columns = [];
  166.         $values = [];
  167.         $keys = array_keys($data);
  168.  
  169.         foreach ($keys as $v) {
  170.             $columns[] = $t->quotename($v);
  171.             $values[] = ":$v";
  172.         }
  173.  
  174.         $columns = implode(',', $columns);
  175.         $values = implode(',', $values);
  176.         $tbl = $t->quotename($table);
  177.         $q = "INSERT INTO $tbl ($columns) VALUES ($values)";
  178.         return $t->execute($q, $data);
  179.     }
  180.  
  181.     public function update($table, array $data, $where=1,
  182.                            array $bindings=[]) {
  183.         $t = $this;
  184.         $set = [];
  185.         $is_l = is_list($bindings);
  186.         $bindings = array_merge($is_l ? array_values($data) : $data,
  187.                                 $bindings);
  188.         $keys = array_keys($data);
  189.  
  190.         foreach ($keys as $v) {
  191.             // подстраитваемся под стиль плейсхолдеров
  192.             $set[] = $t->quotename($v) . '=' . ($is_l ? '?' : ":$v");
  193.         }
  194.  
  195.         $set = implode(',', $set);
  196.         $tbl = $t->quotename($table);
  197.         return $t->execute("UPDATE $tbl SET $set WHERE $where", $bindings);
  198.     }
  199.  
  200.     public function delete($table, $where=1, array $bindings=[]) {
  201.         $t = $this;
  202.         $tbl = $t->quotename($table);
  203.         return $t->execute("DELETE FROM $tbl WHERE $where", $bindings);
  204.     }
  205.  
  206.     // при смене базы следует вручную сбросить кеш
  207.     public function clearCache() {
  208.         $this->_queryCache = [];
  209.         $this->_columnCache = [];
  210.         $this->_rowCache = [];
  211.     }
  212.  
  213.     /*
  214.      * Обертки над PDO-шными методами.
  215.      */
  216.  
  217.     public function query($query) {
  218.         return $this->pdo->query($query);
  219.     }
  220.  
  221.     public function exec($query) {
  222.         return $this->pdo->exec($query);
  223.     }
  224.  
  225.     public function quote($s) {
  226.         return $this->pdo->quote($s);
  227.     }
  228.  
  229.     public function commit() {
  230.         return $this->pdo->commit();
  231.     }
  232.  
  233.     public function rollback() {
  234.         return $this->pdo->rollback();
  235.     }
  236.  
  237.     public function lastInsertId() {
  238.         return $this->pdo->lastInsertId();
  239.     }
  240. }
  241.  
  242. /* ---------------------------- 78 characters ----------------------------- */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement