vendor/codeages/biz-framework/src/Dao/GeneralDaoImpl.php line 202

Open in your IDE?
  1. <?php
  2. namespace Codeages\Biz\Framework\Dao;
  3. use Codeages\Biz\Framework\Context\Biz;
  4. abstract class GeneralDaoImpl implements GeneralDaoInterface
  5. {
  6.     protected $biz;
  7.     protected $table null;
  8.     public function __construct(Biz $biz)
  9.     {
  10.         $this->biz $biz;
  11.     }
  12.     public function create($fields)
  13.     {
  14.         $affected $this->db()->insert($this->table(), $fields);
  15.         if ($affected <= 0) {
  16.             throw $this->createDaoException('Insert error.');
  17.         }
  18.         $lastInsertId = isset($fields['id']) ? $fields['id'] : $this->db()->lastInsertId();
  19.         return $this->get($lastInsertId);
  20.     }
  21.     public function update($identifier, array $fields)
  22.     {
  23.         if (empty($identifier)) {
  24.             return 0;
  25.         }
  26.         if (is_numeric($identifier) || is_string($identifier)) {
  27.             return $this->updateById($identifier$fields);
  28.         }
  29.         if (is_array($identifier)) {
  30.             return $this->updateByConditions($identifier$fields);
  31.         }
  32.         throw new DaoException('update arguments type error');
  33.     }
  34.     public function delete($id)
  35.     {
  36.         return $this->db()->delete($this->table(), array('id' => $id));
  37.     }
  38.     public function wave(array $ids, array $diffs)
  39.     {
  40.         $sets array_map(
  41.             function ($name) {
  42.                 return "{$name} = {$name} + ?";
  43.             },
  44.             array_keys($diffs)
  45.         );
  46.         $marks str_repeat('?,'count($ids) - 1).'?';
  47.         $sql "UPDATE {$this->table()} SET ".implode(', '$sets)." WHERE id IN ($marks)";
  48.         return $this->db()->executeUpdate($sqlarray_merge(array_values($diffs), $ids));
  49.     }
  50.     public function get($id, array $options = array())
  51.     {
  52.         $lock = isset($options['lock']) && true === $options['lock'];
  53.         $sql "SELECT * FROM {$this->table()} WHERE id = ?".($lock ' FOR UPDATE' '');
  54.         return $this->db()->fetchAssoc($sql, array($id)) ?: null;
  55.     }
  56.     public function search($conditions$orderBys$start$limit$columns = array())
  57.     {
  58.         $builder $this->createQueryBuilder($conditions)
  59.             ->setFirstResult($start)
  60.             ->setMaxResults($limit);
  61.         $this->addSelect($builder$columns);
  62.         $declares $this->declares();
  63.         foreach ($orderBys ?: array() as $order => $sort) {
  64.             $this->checkOrderBy($order$sort$declares['orderbys']);
  65.             $builder->addOrderBy($order$sort);
  66.         }
  67.         return $builder->execute()->fetchAll();
  68.     }
  69.     private function addSelect(DynamicQueryBuilder $builder$columns)
  70.     {
  71.         if (!$columns) {
  72.             return $builder->select('*');
  73.         }
  74.         foreach ($columns as $column) {
  75.             if (preg_match('/^\w+$/'$column)) {
  76.                 $builder->addSelect($column);
  77.             } else {
  78.                 throw $this->createDaoException('Illegal column name: '$column);
  79.             }
  80.         }
  81.         return $builder;
  82.     }
  83.     public function count($conditions)
  84.     {
  85.         $builder $this->createQueryBuilder($conditions)
  86.             ->select('COUNT(*)');
  87.         return (int) $builder->execute()->fetchColumn(0);
  88.     }
  89.     protected function updateById($id$fields)
  90.     {
  91.         $this->db()->update($this->table$fields, array('id' => $id));
  92.         return $this->get($id);
  93.     }
  94.     /**
  95.      * @param array $conditions conditions of need update rows
  96.      * @param array $fields     updated values
  97.      *
  98.      * @return int the number of affected rows
  99.      */
  100.     protected function updateByConditions(array $conditions, array $fields)
  101.     {
  102.         $builder $this->createQueryBuilder($conditions)
  103.             ->update($this->table$this->table);
  104.         foreach ($fields as $key => $value) {
  105.             $builder
  106.                 ->set($key':'.$key)
  107.                 ->setParameter($key$value);
  108.         }
  109.         return $builder->execute();
  110.     }
  111.     /**
  112.      * @param string $sql
  113.      * @param array  $orderBys
  114.      * @param int    $start
  115.      * @param int    $limit
  116.      *
  117.      * @throws DaoException
  118.      *
  119.      * @return string
  120.      */
  121.     protected function sql($sql, array $orderBys = array(), $start null$limit null)
  122.     {
  123.         if (!empty($orderBys)) {
  124.             $sql .= ' ORDER BY ';
  125.             $orderByStr $separate '';
  126.             $declares $this->declares();
  127.             foreach ($orderBys as $order => $sort) {
  128.                 $this->checkOrderBy($order$sort$declares['orderbys']);
  129.                 $orderByStr .= sprintf('%s %s %s'$separate$order$sort);
  130.                 $separate ',';
  131.             }
  132.             $sql .= $orderByStr;
  133.         }
  134.         if (null !== $start && !is_numeric($start)) {
  135.             throw $this->createDaoException('SQL Limit must can be cast to integer');
  136.         }
  137.         if (null !== $limit && !is_numeric($limit)) {
  138.             throw $this->createDaoException('SQL Limit must can be cast to integer');
  139.         }
  140.         $onlySetStart null !== $start && null === $limit;
  141.         $onlySetLimit null !== $limit && null === $start;
  142.         if ($onlySetStart || $onlySetLimit) {
  143.             throw $this->createDaoException('start and limit need to be assigned');
  144.         }
  145.         if (is_numeric($start) && is_numeric($limit)) {
  146.             $sql .= sprintf(' LIMIT %d, %d'$start$limit);
  147.         }
  148.         return $sql;
  149.     }
  150.     public function table()
  151.     {
  152.         return $this->table;
  153.     }
  154.     /**
  155.      * @return Connection
  156.      */
  157.     public function db()
  158.     {
  159.         return $this->biz['db'];
  160.     }
  161.     protected function getByFields($fields)
  162.     {
  163.         $placeholders array_map(
  164.             function ($name) {
  165.                 return "{$name} = ?";
  166.             },
  167.             array_keys($fields)
  168.         );
  169.         $sql "SELECT * FROM {$this->table()} WHERE ".implode(' AND '$placeholders).' LIMIT 1 ';
  170.         return $this->db()->fetchAssoc($sqlarray_values($fields)) ?: null;
  171.     }
  172.     protected function findInField($field$values)
  173.     {
  174.         if (empty($values)) {
  175.             return array();
  176.         }
  177.         $marks str_repeat('?,'count($values) - 1).'?';
  178.         $sql "SELECT * FROM {$this->table} WHERE {$field} IN ({$marks});";
  179.         return $this->db()->fetchAll($sql$values);
  180.     }
  181.     protected function findByFields($fields)
  182.     {
  183.         $placeholders array_map(
  184.             function ($name) {
  185.                 return "{$name} = ?";
  186.             },
  187.             array_keys($fields)
  188.         );
  189.         $sql "SELECT * FROM {$this->table()} WHERE ".implode(' AND '$placeholders);
  190.         return $this->db()->fetchAll($sqlarray_values($fields));
  191.     }
  192.     protected function createQueryBuilder($conditions)
  193.     {
  194.         $conditions array_filter(
  195.             $conditions,
  196.             function ($value) {
  197.                 if ('' === $value || null === $value) {
  198.                     return false;
  199.                 }
  200.                 if (is_array($value) && empty($value)) {
  201.                     return false;
  202.                 }
  203.                 return true;
  204.             }
  205.         );
  206.         $builder $this->getQueryBuilder($conditions);
  207.         $builder->from($this->table(), $this->table());
  208.         $declares $this->declares();
  209.         $declares['conditions'] = isset($declares['conditions']) ? $declares['conditions'] : array();
  210.         foreach ($declares['conditions'] as $condition) {
  211.             $builder->andWhere($condition);
  212.         }
  213.         return $builder;
  214.     }
  215.     protected function getQueryBuilder($conditions)
  216.     {
  217.         return new DynamicQueryBuilder($this->db(), $conditions);
  218.     }
  219.     protected function filterStartLimit(&$start, &$limit)
  220.     {
  221.         $start = (int) $start;
  222.         $limit = (int) $limit;
  223.     }
  224.     private function createDaoException($message ''$code 0)
  225.     {
  226.         return new DaoException($message$code);
  227.     }
  228.     private function checkOrderBy($order$sort$allowOrderBys)
  229.     {
  230.         if (!in_array($order$allowOrderBystrue)) {
  231.             throw $this->createDaoException(
  232.                 sprintf("SQL order by field is only allowed '%s', but you give `{$order}`."implode(','$allowOrderBys))
  233.             );
  234.         }
  235.         if (!in_array(strtoupper($sort), array('ASC''DESC'), true)) {
  236.             throw $this->createDaoException("SQL order by direction is only allowed `ASC`, `DESC`, but you give `{$sort}`.");
  237.         }
  238.     }
  239. }