def _get_json_criterion(items: List): if len(items) == 2: left = items.pop(0) right = items.pop(0) return BasicCriterion(JSONOperators.GET_TEXT_VALUE, ValueWrapper(left), ValueWrapper(right)) left = items.pop(0) return BasicCriterion(JSONOperators.GET_JSON_VALUE, ValueWrapper(left), _get_json_criterion(items))
def _create_json_criterion(items: List, field_term: Term, operator_: Callable, value: str): if len(items) == 1: term = items.pop(0) return operator_( BasicCriterion(JSONOperators.GET_TEXT_VALUE, field_term, ValueWrapper(term)), value) return operator_( BasicCriterion(JSONOperators.GET_JSON_VALUE, field_term, _get_json_criterion(items)), value)
def not_in(field: Term, value: Any) -> Criterion: if value: return field.notin(value) | field.isnull() return BasicCriterion(Equality.eq, ValueWrapper(1), ValueWrapper(1))
def is_in(field: Term, value: Any) -> Criterion: if value: return field.isin(value) return BasicCriterion(Equality.eq, ValueWrapper(1), ValueWrapper(0))
def solve_condition(c): if isinstance(c, QueryConditions): items = list([solve_condition(x) for x in c.items]) if items: return reduce(ComplexCriterion.__and__, items) # 部分orm在实现join条件的时候拼接的语句不正确 elif isinstance(c, (QueryConditions, ConditionLogicExpr)): items = [solve_condition(x) for x in c.items] if items: if c.type == 'and': return reduce(ComplexCriterion.__and__, items) else: return reduce(ComplexCriterion.__or__, items) elif isinstance(c, ConditionExpr): field = getattr(self.mapping2model[c.column.table], c.column.name) if isinstance(c.value, RecordMappingField): real_value = getattr(self.mapping2model[c.value.table], c.value.name) else: contains_relation = c.op in ( QUERY_OP_RELATION.CONTAINS, QUERY_OP_RELATION.CONTAINS_ANY) # value = [c.value] if c.op == QUERY_OP_RELATION.CONTAINS_ANY else c.value if c.op in (QUERY_OP_RELATION.PREFIX, QUERY_OP_RELATION.IPREFIX): # TODO: 更好的安全机制,防止利用like语句 c.value = c.value.replace('%', '') c.value = c.value + '%' real_value = phg.next( c.value, contains_relation=contains_relation) if c.op == QUERY_OP_RELATION.PREFIX: cond = field.like(real_value) elif c.op == QUERY_OP_RELATION.IPREFIX: cond = field.ilike(real_value) elif c.op == QUERY_OP_RELATION.IS: cond = BasicCriterion(ArrayMatchingExt.is_, field, field.wrap_constant(real_value)) elif c.op == QUERY_OP_RELATION.IS_NOT: cond = BasicCriterion(ArrayMatchingExt.is_not, field, field.wrap_constant(real_value)) elif c.op == QUERY_OP_RELATION.CONTAINS_ANY: # && cond = BasicCriterion(ArrayMatchingExt.contains_any, field, field.wrap_constant(real_value)) else: cond = getattr(field, _sql_method_map[c.op])(real_value) return cond elif isinstance(c, NegatedExpr): return ~solve_condition(c.expr)
def is_in(field: Term, value: Any) -> Criterion: if value: return field.isin(value) # SQL has no False, so we return 1=0 return BasicCriterion(Equality.eq, ValueWrapper(1), ValueWrapper(0))
def postgres_json_contained_by(field: Term, value: str) -> Criterion: return BasicCriterion(JSONOperators.CONTAINED_BY, field, ValueWrapper(value))
def fn_array_cat(a, b, *cs): q = BasicCriterion("||", a, b) for c in cs: q = BasicCriterion("||", q, c) return q