Build SQL query for a filter

@param string $field
@param string $type
@param string $filter
@param mixed $value
@return boolean True on success
1619
protected function buildFilter($field, $type, $filter, $value)
    {
        if (strlen($field) == 0)
            throw new \Exception("Empty 'field'");
        if (strlen($type) == 0)
            throw new \Exception("Empty 'type'");

        if ($type == Table::TYPE_DATETIME) {
            if ($filter == Table::FILTER_BETWEEN
                    && is_array($value) && count($value) == 2) {
                $value = [
                    $value[0] ? new \DateTime('@' . $value[0]) : null,
                    $value[1] ? new \DateTime('@' . $value[1]) : null,
                ];
                if ($value[0] && $this->getDbTimezone())
                    $value[0]->setTimezone(new \DateTimeZone($this->getDbTimezone()));
                if ($value[1] && $this->getDbTimezone())
                    $value[1]->setTimezone(new \DateTimeZone($this->getDbTimezone()));
            } else if ($filter != Table::FILTER_BETWEEN
                    && !is_array($value)) {
                $value = new \DateTime('@' . $value);
                if ($this->getDbTimezone())
                    $value->setTimezone(new \DateTimeZone($this->getDbTimezone()));
            } else {
                return false;
            }
        } else {
            if ($filter == Table::FILTER_BETWEEN) {
                if (!is_array($value) || count($value) != 2)
                    return false;
            } else if (is_array($value)) {
                return false;
            }
        }

        if (!isset($this->sqlAnds[$field]))
            $this->sqlAnds[$field] = [];

        $paramBaseName = 'dt_' . str_replace('.', '_', $field);
        switch ($filter) {
            case Table::FILTER_LIKE:
                $param = ':' . $paramBaseName . '_like';
                $this->sqlAnds[$field][] = "$field LIKE $param";
                $this->sqlParams[$param] = '%' . $value . '%';
                break;
            case Table::FILTER_EQUAL:
                $param = ':' . $paramBaseName . '_equal';
                $this->sqlAnds[$field][] = "$field = $param";
                $this->sqlParams[$param] = $value;
                break;
            case Table::FILTER_BETWEEN:
                $ands = [];
                if ($value[0] !== null) {
                    $param = ':' . $paramBaseName . '_begin';
                    $ands[] = "$field >= $param";
                    $this->sqlParams[$param] = $value[0];
                }
                if ($value[1] !== null) {
                    $param = ':' . $paramBaseName . '_end';
                    $ands[] = "$field <= $param";
                    $this->sqlParams[$param] = $value[1];
                }
                $this->sqlAnds[$field][] = join(' AND ', $ands);
                break;
            case Table::FILTER_NULL:
                $this->sqlAnds[$field][] = "$field IS NULL";
                break;
            default:
                throw new \Exception("Unknown filter: $filter");
        }

        return true;
    }
421547
public function bindValue($parameter, $value, $type = \PDO::PARAM_STR)
    {
        list($value, $type) = TypeUtility::convertToDatabase($value, $type, $this->connection->getPlatform());

        return $this->getDriverStatement()->bindValue($parameter, $value, $type);
    }
229265
public function whereLike($column, $value, $filter = false)
    {
        return $this->where($column, 'LIKE', $value, $filter);
    }
8807
protected function query($value)
    {
        $filters[$this->getKey()] = $value;
        $result = false;
//         if(!$this->getMapper()->enableFilters($filters))
//             throw new \Exception('Invalid filters used in record validator');
        
        $result = $this->getMapper()->findByFilters($filters);
        return $result;
    }
1131263
public function getLookupResults($type, $filter = '', $limit = 10)
    {
        return $this->getRepository()->getValueList($type, $filter, $limit);
    }
729123
public static function registerFilter(string $type, $filter)
    {
        if (gettype($type) !== 'string') {
            return;
        }
        if (!isset(self::$filters[$type])) {
            self::$filters[$type] = [];
        }
        self::$filters[$type][] = $filter;
    }
631172
protected function applyFilter(
        Builder $query,
        Contracts\QueryField $field,
        string $filter,
        $value,
        $boolean = 'and'
    ): Builder
    {
        $type = $field->getType();
        if ($type && $value !== null) {
            $value = is_array($value) ? array_map([$type, 'prepareValue'], $value) : $type->prepareValue($value);
        }
        $qualifiedField = $field->getQualifiedField();
        switch ($filter) {
            case 'equal':
                $query->where($qualifiedField, '=', $value, $boolean);
                break;
            case 'not_equal':
                $query->where($qualifiedField, '<>', $value, $boolean);
                break;
            case 'in':
                $query->whereIn($qualifiedField, (array)$value, $boolean);
                break;
            case 'not_in':
                $query->whereNotIn($qualifiedField, (array)$value, $boolean);
                break;
            case 'less':
                $query->where($qualifiedField, '<', $value, $boolean);
                break;
            case 'less_or_equal':
                $query->where($qualifiedField, '<=', $value, $boolean);
                break;
            case 'greater':
                $query->where($qualifiedField, '>', $value, $boolean);
                break;
            case 'greater_or_equal':
                $query->where($qualifiedField, '>=', $value, $boolean);
                break;
            case 'between':
                $query->whereBetween($qualifiedField, (array)$value, $boolean);
                break;
            case 'not_between':
                $query->whereNotBetween($qualifiedField, (array)$value, $boolean);
                break;
            case 'begins_with':
                $query->where($qualifiedField, 'like', "{$value}%", $boolean);
                break;
            case 'not_begins_with':
                $query->where($qualifiedField, 'not like', "{$value}%", $boolean);
                break;
            case 'contains':
                $query->where($qualifiedField, 'like', "%{$value}%", $boolean);
                break;
            case 'not_contains':
                $query->where($qualifiedField, 'not like', "%{$value}%", $boolean);
                break;
            case 'ends_with':
                $query->where($qualifiedField, 'like', "%{$value}", $boolean);
                break;
            case 'not_ends_with':
                $query->where($qualifiedField, 'not like', "%{$value}", $boolean);
                break;
            case 'is_empty':
                $query->where($qualifiedField, '=', '', $boolean);
                break;
            case 'is_not_empty':
                $query->where($qualifiedField, '<>', '', $boolean);
                break;
            case 'is_null':
                $query->whereNull($qualifiedField, $boolean);
                break;
            case 'is_not_null':
                $query->whereNotNull($qualifiedField, $boolean);
                break;
        }

        //dd($query->toSql(), $query->getBindings());
        return $query;
    }
270475
@VisibleForTesting
    public static boolean checkInBloomFilter(BloomFilter bloomFilter, Object predicateValue, Type sqlType)
    {
        if (sqlType == TINYINT || sqlType == SMALLINT || sqlType == INTEGER || sqlType == BIGINT) {
            return bloomFilter.testLong(((Number) predicateValue).longValue());
        }

        if (sqlType == DOUBLE) {
            return bloomFilter.testDouble((Double) predicateValue);
        }

        if (sqlType instanceof VarcharType || sqlType instanceof VarbinaryType) {
            return bloomFilter.test(((Slice) predicateValue).getBytes());
        }

        // todo support DECIMAL, FLOAT, DATE, TIMESTAMP, and CHAR
        return true;
    }
157694
public function filterLt(string $field, $value): self
    {
        $this->filters[] = new IndexQueryFilter($field, IndexQueryFilterOperator::LESS_THAN(), $value);
        return $this;
    }
1196180
public static function where($filter, $value = null)
    {
        if (is_scalar($filter)) {
            /** @var \ManaPHP\ModelInterface $model */
            $model = Di::getDefault()->getShared(static::class);
            return static::query(null, $model)->whereEq($model->getPrimaryKey(), $filter);
        } else {
            return static::query()->where($filter, $value);
        }
    }
130275
protected function _buildQuery(Query $query, $field, $value, array $data = [])
    {
        $type = $this->config('type');
        $value = '%' . $value . '%';
        $fields = $this->config('fields');
        $typesMap = $this->config('fieldTypes');
        $types = [];
        foreach ($fields as $field) {
            if (is_array($typesMap) && array_key_exists($field, $typesMap)) {
                $types[$field] = $typesMap[$field];
            } else {
                $types[$field] = null;
            }
        }
        if (empty($type)) {
            $type = 'and';
        }

        return $query->where(function ($exp) use (&$query, $value, $type, $fields, $types) {
            return $exp->{$type . '_'}(function ($ex) use ($value, $fields, $types) {
                collection($fields)->each(function ($field) use ($value, &$ex, $types) {
                    return $ex->like($field, $value, $types[$field]);
                });

                return $ex;
            });
        });
    }
267231
function select($fields,$filter=NULL,array $options=NULL,$ttl=0) {
		list($sql,$args)=$this->stringify($fields,$filter,$options);
		$result=$this->db->exec($sql,$args,$ttl);
		$out=[];
		foreach ($result as &$row) {
			foreach ($row as $field=>&$val) {
				if (array_key_exists($field,$this->fields)) {
					if (!is_null($val) || !$this->fields[$field]['nullable'])
						$val=$this->db->value(
							$this->fields[$field]['pdo_type'],$val);
				}
				unset($val);
			}
			$out[]=$this->factory($row);
			unset($row);
		}
		return $out;
	}
161778
private function applyFieldFilter(Builder $query, $field, $value)
    {
        $query = $this->resolveOrLinks($query, $field, $value);

        return $query;
    }
795557
public function where($field, $value)
    {
        $this->reloadQueryAdapter();
        $this->activeQuery->where($field, $value);
        return $this;
    }
1347748
public function equals($column, $value, $filter = false)
    {
        return $this->compare($column, '=', $value, $filter);
    }
575801
private function FieldCondition($field, $value)
        {
            $tbl = $this->Table();
            $mapper = $this->FieldMapper($field);
            $dbVal = $mapper->ToDBString($value);
            
            $sql = $this->SqlBuilder();
            
            if ($dbVal === null)
                return $sql->IsNull($tbl->Field($field));
            else
                return $sql->Equals($tbl->Field($field), $sql->Value($dbVal));
        }
768225
protected function buildQueryByFilter($query, $filter)
    {
        $tableName = $this->getBlankModel()->getTable();

        $query = $this->queryOptions($query);

        if (count($this->querySearchTargets) > 0 && array_key_exists('query', $filter)) {
            $searchWord = Arr::get($filter, 'query');
            if (!empty($searchWord)) {
                $query = $query->where(function($q) use ($searchWord) {
                    foreach ($this->querySearchTargets as $index => $target) {
                        if ($index === 0) {
                            $q = $q->where($target, 'LIKE', '%'.$searchWord.'%');
                        } else {
                            $q = $q->orWhere($target, 'LIKE', '%'.$searchWord.'%');
                        }
                    }
                });
            }
            unset($filter['query']);
        }

        foreach ($filter as $column => $value) {
            if (is_array($value)) {
                $query = $query->whereIn($tableName.'.'.$column, $value);
            } else {
                $query = $query->where($tableName.'.'.$column, $value);
            }
        }

        return $query;
    }