def validate_value_list(self, ctx: Ctx, values: List[Any]) -> str: replaces = {} transformedValues = [] args = [] for val in values: if isinstance(val, datetime.datetime) or isinstance( val, datetime.date): val, _ = process_value(str(val.astimezone(UTC))) replaces[val] = f'{val}::timestamptz' elif isinstance(val, asyncpg.pgproto.pgproto.UUID): val = quote_literal(str(val)) replaces[val] = f'{val}::uuid' else: val, p = process_value(val) if p is not None: args.append(p) val = str(val) transformedValues.append(val) nestedCtx = Ctx(ctx.param_offset + len(ctx.args), args) result = _value_list.parse(','.join(transformedValues), nestedCtx) for rep in replaces: result = result.replace(rep, replaces[rep]) ctx.args.extend(args) return result
def where(self, _where: str, *items: Any): if len(items) == 0 or '?' in _where: try: ctx = Ctx(self.paramOffset, items) sql = self.validator.validate_where(_where, ctx) except ValidationError as err: raise UserWarning(f'invalid WHERE: {err}') from None value = {'sql': sql, 'params': ctx.args} elif len(items) <= 2: if len(items) == 1: if isinstance(items[0], list): operator = 'IN' else: operator = '=' val = items[0] if val is None: operator = 'IS' else: operator = items[0] val = items[1] _where += f' {operator}' if val is None: _where += ' NULL' params = [] else: jsonbTest = '->' in _where if operator == 'IN' or operator == 'NOT IN': params = [] vs = [] for v in val: processed, _ = process_value(v) if processed == '?' or jsonbTest: params.append(v) vs.append('?') else: vs.append(str(processed)) _where += ' (' + ', '.join(vs) + ')' else: params = [] processed, _ = process_value(val) if processed == '?' or jsonbTest: params.append(val) _where += ' ?' else: _where += f' {processed}' try: ctx = Ctx(self.paramOffset, params) sql = self.validator.validate_where(_where, ctx) except ValidationError as err: raise UserWarning(f'invalid WHERE: {err}') from None value = {'sql': sql, 'params': ctx.args} else: raise UserWarning(f"Invalid WHERE: {_where} {items}") self.paramOffset += len(value['params']) self.append(WhereToken(value))
def validate_insert_values(self, values: List[Any], ctx: Ctx) -> str: results = [] for val in values: val, p = process_value(val) if p is not None: ctx.args.append(p) results.append(str(val)) return '(' + _value_list.parse(','.join(results), ctx) + ')'
def validate_rrule_values(self, ctx: Ctx, values: List[Any], rrulesetVal: rrule.rruleset, occurrences: slice) -> str: row = [None] # slot for rrule timestamp args = [] for val in values: val, p = process_value(val) if p is not None: args.append(p) row.append(str(val)) results = [] # set a limit in case the rrule is unbound for tm in rrulesetVal[occurrences]: row[0], _ = process_value(str(tm.astimezone(UTC))) nestedCtx = Ctx(ctx.param_offset + len(ctx.args), args) rowTmpl = '(' + _value_list.parse(','.join(row), nestedCtx) + ')' results.append(rowTmpl.replace(row[0], f'{row[0]}::timestamptz')) ctx.args.extend(args) return ', '.join(results)
def update(self, *items: Any): if len(items) == 1 and isinstance(items[0], Dict): _sqls = [] params = [] for name, val in items[0].items(): val, p = process_value(val) if p is not None: params.append(p) _sqls.append(f'{name} = {val}') sql = ', '.join(_sqls) elif len(items) > 0: sql = items[0] params = items[1:] else: raise UserWarning(f'not valid updates: {items}') self.collector.update(sql, *params) return self