def execute_query(sql, values, row_offset: int, row_limit: int, censor: Censor) -> List: context = ctx.get() context.set_query_timeout() try: c = context.db.cursor() def row_filter(cursor, row): nonlocal row_offset row = row_factory(cursor, row) if len(row) > 1 and censor.censor(row): return if row_offset: row_offset -= 1 return return row c.setrowtrace(row_filter) i, rows = 0, [] for row in c.execute(sql, values): i += 1 rows.append(row) if i >= row_limit: break return rows except apsw.Error as err: plain_sql = interpolate(sql, values) if context.is_tracking_metrics: context.metrics['execute_query'][-1]['sql'] = plain_sql if isinstance(err, apsw.InterruptError): context.log.warning("interrupted slow sqlite query:\n%s", plain_sql) raise SQLiteInterruptedError(context.metrics) context.log.exception('failed running query', exc_info=err) raise SQLiteOperationalError(context.metrics)
def test_query_interpolation(self): self.maxDiff = None # tests that interpolation replaces longer keys first self.assertEqual( interpolate(*query( "select * from foo", a__not='b', b__in='select * from blah where c=:$c', d__any={ 'one__like': 'o', 'two': 2 }, a0=3, a00=1, a00a=2, a00aa=4, # <-- breaks without correct interpolation key order ahash=sha256(b'hello world'), limit=10, order_by='b', **{'$c': 3})), "select * from foo WHERE a != 'b' AND " "b IN (select * from blah where c=3) AND " "(one LIKE 'o' OR two = 2) AND " "a0 = 3 AND a00 = 1 AND a00a = 2 AND a00aa = 4 " "AND ahash = X'b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9' " "ORDER BY b LIMIT 10")
def execute_query(sql, values, row_offset: int, row_limit: int, censor: Censor) -> List: context = ctx.get() context.set_query_timeout() try: rows = context.db.execute(sql, values).fetchall() return rows[row_offset:row_limit] except sqlite3.OperationalError as err: plain_sql = interpolate(sql, values) if context.is_tracking_metrics: context.metrics['execute_query'][-1]['sql'] = plain_sql context.log.exception('failed running query', exc_info=err) raise SQLiteOperationalError(context.metrics)
def execute_query(sql, values) -> List: context = ctx.get() context.set_query_timeout() try: return context.db.cursor().execute(sql, values).fetchall() except apsw.Error as err: plain_sql = interpolate(sql, values) if context.is_tracking_metrics: context.metrics['execute_query'][-1]['sql'] = plain_sql if isinstance(err, apsw.InterruptError): context.log.warning("interrupted slow sqlite query:\n%s", plain_sql) raise SQLiteInterruptedError(context.metrics) context.log.exception('failed running query', exc_info=err) raise SQLiteOperationalError(context.metrics)