| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400 |
- <?php
- class DbCriteria extends \CDbCriteria
- {
- // 通过 setDebugUntil 方法开启
- public const DEBUG_ON = 1;
- public const DEBUG_OFF = 0;
- public string $forceIndex = ''; // 强制索引
- private bool $lock = false; // 是否加锁
- private int $page = 0;
- private string $countSelect = 'count(*) as total';
- private bool $_fenye = false; // 是否分页 只有调用 setPage 才会分页
- private int $pageSize = 0;
- private int $debugMode = self::DEBUG_OFF; // 1 可以开启debug记录日志
- protected string $debugTag = '';
- /**
- * Adds a comparison expression to the {@link condition} property.
- *
- * This method is a helper that appends to the {@link condition} property
- * with a new comparison expression. The comparison is done by comparing a column
- * with the given value using some comparison operator.
- *
- * The comparison operator is intelligently determined based on the first few
- * characters in the given value. In particular, it recognizes the following operators
- * if they appear as the leading characters in the given value:
- * <ul>
- * <li><code><</code>: the column must be less than the given value.</li>
- * <li><code>></code>: the column must be greater than the given value.</li>
- * <li><code><=</code>: the column must be less than or equal to the given value.</li>
- * <li><code>>=</code>: the column must be greater than or equal to the given value.</li>
- * <li><code><></code>: the column must not be the same as the given value.
- * Note that when $partialMatch is true, this would mean the value must not be a substring
- * of the column.</li>
- * <li><code>=</code>: the column must be equal to the given value.</li>
- * <li>none of the above: the column must be equal to the given value. Note that when $partialMatch
- * is true, this would mean the value must be the same as the given value or be a substring of it.</li>
- * </ul>
- *
- * Note that any surrounding white spaces will be removed from the value before comparison.
- * When the value is empty, no comparison expression will be added to the search condition.
- *
- * @param string $column the name of the column to be searched
- * @param mixed $value the column value to be compared with. If the value is a string, the aforementioned
- * intelligent comparison will be conducted. If the value is an array, the comparison is done
- * by exact match of any of the value in the array. If the string or the array is empty,
- * the existing search condition will not be modified.
- * @param boolean $partialMatch whether the value should consider partial text match (using LIKE and NOT LIKE operators).
- * Defaults to false, meaning exact comparison.
- * @param string $operator the operator used to concatenate the new condition with the existing one.
- * Defaults to 'AND'.
- * @param boolean $escape whether the value should be escaped if $partialMatch is true and
- * the value contains characters % or _. When this parameter is true (default),
- * the special characters % (matches 0 or more characters)
- * and _ (matches a single character) will be escaped, and the value will be surrounded with a %
- * character on both ends. When this parameter is false, the value will be directly used for
- * matching without any change.
- * @return static the criteria object itself
- * @since 1.1.1
- */
- public function compare($column, $value, $partialMatch = false, $operator = 'AND', $escape = true): static
- {
- if (is_array($value)) {
- if ($value === array()) {
- return $this;
- }
- return $this->addInCondition($column, $value, $operator);
- } else {
- $value = "$value";
- }
- if (preg_match('/^(?:\s*(<>|<=|>=|<|>|=|%|\!=))?(.*)$/', $value, $matches)) {
- $value = $matches[2];
- $op = $matches[1];
- } else {
- $op = '';
- }
- if ($op == '%') {
- //模糊匹配
- $partialMatch = true;
- $op = '';
- }
- if ($value === '') {
- return $this;
- }
- if ($partialMatch) {
- if ($op === '') {
- return $this->addSearchCondition($column, $value, $escape, $operator);
- }
- if ($op === '<>') {
- return $this->addSearchCondition($column, $value, $escape, $operator, 'NOT LIKE');
- }
- } elseif ($op === '') {
- $op = '=';
- }
- $this->addCondition($column.$op.self::PARAM_PREFIX.self::$paramCount, $operator);
- $this->params[self::PARAM_PREFIX.self::$paramCount++] = $value;
- return $this;
- }
- /**
- * 设置 分页数据
- * @param int $page
- * @param int $pageSize
- * @return DbCriteria
- */
- public function setPage(int $page = 1, int $pageSize = 30): static
- {
- if ($page < 0 || $pageSize < 1) {
- return $this;
- }
- $this->pageSize = $this->limit = $pageSize;
- $this->page = $page > 0 ? $page : 1;
- if ($this->offset > 0) {
- $this->offset += ($this->page - 1) * $this->limit;
- } else {
- $this->offset = ($this->page - 1) * $this->limit;
- }
- $this->_fenye = 1;
- return $this;
- }
- public function setLockStatus($status): static
- {
- $this->lock = (bool)$status;
- return $this;
- }
- public function getLockStatus(): bool
- {
- return $this->lock;
- }
- public function getPage(): int
- {
- return $this->page;
- }
- public function getPageSize(): int
- {
- return $this->pageSize;
- }
- public function setSelect($field = '*'): static
- {
- $this->select = $field;
- return $this;
- }
- public function setJoin($join): static
- {
- $this->join = $join;
- return $this;
- }
- public function addJoin($join): static
- {
- $this->join.= ' ' . $join;
- return $this;
- }
- public function setAlias($alias): static
- {
- $this->alias = $alias;
- return $this;
- }
- public function setGroup($group): static
- {
- $this->group = $group;
- return $this;
- }
- public function setOrder($order): static
- {
- $this->order = $order;
- return $this;
- }
- public function addOrder($order): static
- {
- if ($this->order) {
- $this->order .= ','.$order;
- } else {
- $this->order = $order;
- }
- return $this;
- }
- public function setOffset($offset): static
- {
- $this->offset = $offset;
- return $this;
- }
- public function addOffset($offset): static
- {
- $this->offset += $offset;
- return $this;
- }
- public function setLimit($limit): static
- {
- $this->limit = $limit;
- return $this;
- }
- public function setHaving($having): static
- {
- $this->having = $having;
- return $this;
- }
- public function andHaving($having): static
- {
- if (!$having) {
- return $this;
- }
- if (!$this->having) {
- $this->having = $having;
- } else {
- $this->having .= ' AND '.$having;
- }
- return $this;
- }
- public function orHaving($having): static
- {
- if (!$having) {
- return $this;
- }
- if (!$this->having) {
- $this->having = $having;
- } else {
- $this->having .= ' OR '.$having;
- }
- return $this;
- }
- public function setForceIndex($index): static
- {
- $this->forceIndex = $index;
- return $this;
- }
- /**
- * 开启线上日志记录到指定时间
- * @param string $tag 标记 查找日志方便
- * @param string $deadline 必须指定 -1永久(不建议使用)
- */
- public function setDebugUntil($tag, $deadline): static
- {
- if ($deadline != '-1' && strtotime($deadline) < time()) {
- $this->debugMode = self::DEBUG_OFF;
- return $this;
- }
- $this->debugTag = $tag;
- $this->debugMode = self::DEBUG_ON;
- return $this;
- }
- public function getDebugMode(): bool
- {
- return $this->debugMode;
- }
- /**
- * @return array the array representation of the criteria
- */
- public function toArray(): array
- {
- $result = array();
- foreach (
- [
- 'select',
- // 'condition',
- // 'params',
- 'limit',
- 'offset',
- 'order',
- 'group',
- 'join',
- 'having',
- 'distinct',
- 'scopes',
- 'with',
- 'alias',
- 'index',
- 'together',
- 'page',
- 'pageSize',
- 'debugTag',
- ] as $name
- ) {
- $result[$name] = $this->$name;
- }
- return $result;
- }
- public function getSql($sql, $params): string
- {
- if ($params) {
- foreach ($params as $k => $v) {
- if (!is_numeric($v)) {
- $params[$k] = "'{$v}'";
- }
- }
- // 这里倒序会导致 :ycp5 覆盖 :ycp50
- $params = array_reverse($params);
- $sql = str_replace(array_keys($params), array_values($params), $sql);
- }
- $sql = str_replace("\n", ' ', $sql);
- return $this->getLockStatus() ? $sql." FOR UPDATE" : $sql;
- }
- public function getDebugTag(): string
- {
- return $this->debugTag;
- }
- public function getUseTime()
- {
- }
- public function isFenye(): bool
- {
- return $this->_fenye;
- }
- /**
- * 分页情况下,查询总条数的 select 字段,如果含有 group 时可能需要额外插叙字段
- * @param $str
- * @return string
- */
- public function setCountSelectStr($str): string
- {
- return $this->countSelect .= ','.trim($str, ',');
- }
- public function getCountSelectStr(): string
- {
- return $this->countSelect;
- }
- /**
- * 简单的compare
- * @param array $filter
- * @param bool $checkPage
- * @return $this
- */
- public static function simpleCompare(array $filter): static
- {
- $cri = new static();
- foreach ($filter as $k => $v) {
- $cri->compare($k, $v);
- }
- return $cri;
- }
- /**
- * 简单的compare
- * @param array $filter
- * @param bool $checkPage
- * @return $this
- */
- public static function simpleCompareWithPage(array $filter): static
- {
- $cri = self::simpleCompare($filter);
- $cri->setPage(
- Helper::getArrParam($_REQUEST, 'current', 'int', 1),
- Helper::getArrParam($_REQUEST, 'size', 'int', 20)
- );
- return $cri;
- }
- }
|