def _message_index(message_path: Path) -> dict: revision = _database_revision(message_path) def build(): connection = connect_sqlite(str(message_path)) try: columns = _columns(connection, "message_table") result = {"columns": columns, "total_messages": 0, "conversations": {}, "ordered": [], "previews": {}, "revision": revision} if not {"conversation_id", "send_time"}.issubset(columns): return result result["total_messages"] = _message_counts(message_path)[0] # Sort/group inside SQLite instead of allocating one Python tuple # per message. Only compact row IDs and one timestamp per chat are # retained; message bodies are fetched for the visible page only. cursor = connection.execute( "SELECT conversation_id,GROUP_CONCAT(message_rowid),MAX(message_time) " "FROM (SELECT rowid AS message_rowid,conversation_id,CAST(send_time AS REAL) AS message_time " "FROM message_table WHERE conversation_id IS NOT NULL AND conversation_id<>'' " "AND conversation_id NOT LIKE 'Y:%' " "ORDER BY conversation_id,CAST(send_time AS REAL),rowid) GROUP BY conversation_id" ) for conversation_id, encoded_rows, timestamp in cursor: row_ids = array("q", map(int, str(encoded_rows).split(","))) timestamp = float(timestamp or 0) if not math.isfinite(timestamp): timestamp = 0.0 result["conversations"][str(conversation_id)] = { "rows": row_ids, "lastTimestamp": timestamp, "lastRowId": row_ids[-1], } result["ordered"] = sorted(result["conversations"], key=lambda key: ( result["conversations"][key]["lastTimestamp"], result["conversations"][key]["lastRowId"], key), reverse=True) return result finally: connection.close() return _cached("index", revision[0], revision, build)