diff --git a/libervia/backend/memory/sqla.py b/libervia/backend/memory/sqla.py index daf9da78..094e7bdd 100644 --- a/libervia/backend/memory/sqla.py +++ b/libervia/backend/memory/sqla.py @@ -630,6 +630,18 @@ class Storage: if filters is None: filters = {} + # An "after_uid" filter asks for the first messages after a given one, so ASC + # order is used and the result is returned as-is. Otherwise DESC+LIMIT keeps the + # last messages and the result is reversed. + asc = "after_uid" in filters + order = ( + History.timestamp.asc() if asc else History.timestamp.desc(), + ( + History.received_timestamp.asc() + if asc + else History.received_timestamp.desc() + ), + ) stmt = ( select(History) .filter_by(profile_id=self.profiles[profile]) @@ -641,14 +653,7 @@ class Storage: contains_eager(History.subjects), contains_eager(History.thread), ) - .order_by( - # timestamp may be identical for 2 close messages (specially when delay is - # used) that's why we order ties by received_timestamp. We'll reverse the - # order when returning the result. We use DESC here so LIMIT keep the last - # messages - History.timestamp.desc(), - History.received_timestamp.desc(), - ) + .order_by(*order) ) if not from_jid and not to_jid: @@ -689,8 +694,8 @@ class Storage: if "timestamp_start" in filters: stmt = stmt.where(History.timestamp >= float(filters["timestamp_start"])) if "before_uid" in filters: - # orignially this query was using SQLITE's rowid. This has been changed - # to use coalesce(received_timestamp, timestamp) to be SQL engine independant + # orignially this query was using SQLITE's rowid. This has been changed to + # use coalesce(received_timestamp, timestamp) to be SQL engine independant stmt = stmt.where( coalesce(History.received_timestamp, History.timestamp) < ( @@ -699,6 +704,15 @@ class Storage: ).filter_by(uid=filters["before_uid"]) ).scalar_subquery() ) + if "after_uid" in filters: + stmt = stmt.where( + coalesce(History.received_timestamp, History.timestamp) + > ( + select( + coalesce(History.received_timestamp, History.timestamp) + ).filter_by(uid=filters["after_uid"]) + ).scalar_subquery() + ) if "body" in filters: # TODO: use REGEXP (function to be defined) instead of GLOB: # https://www.sqlite.org/lang_expr.html @@ -754,7 +768,8 @@ class Storage: result = await session.execute(stmt) result = result.scalars().unique().all() - result.reverse() + if not asc: + result.reverse() return [h.as_tuple() for h in result] @aio