diff --git a/hive/db/schema.py b/hive/db/schema.py index 73bbffdd23b0e618880ffc83e2468e99781388b6..2d4b7f445f13f644074813d89c6da90cf7604a8c 100644 --- a/hive/db/schema.py +++ b/hive/db/schema.py @@ -1552,6 +1552,59 @@ def setup(db): """ db.query_no_return(sql) + sql = """ + DROP FUNCTION IF EXISTS find_account_id(character varying, boolean) + ; + CREATE OR REPLACE FUNCTION find_account_id( + in _account hive_accounts.name%TYPE, + in _check boolean) + RETURNS INT + LANGUAGE 'plpgsql' + AS + $function$ + DECLARE + account_id INT; + BEGIN + SELECT INTO account_id COALESCE( ( SELECT id FROM hive_accounts WHERE name=_account ), 0 ); + IF _check AND account_id = 0 THEN + RAISE EXCEPTION 'Account % does not exist', _account; + END IF; + RETURN account_id; + END + $function$ + ; + """ + db.query_no_return(sql) + + sql = """ + DROP FUNCTION IF EXISTS get_account_post_replies; + CREATE FUNCTION get_account_post_replies( in _account VARCHAR, in start_author VARCHAR, in start_permlink VARCHAR, in _limit SMALLINT ) + RETURNS SETOF INTEGER + AS + $function$ + DECLARE + __post_id INTEGER = -1; + __account_id INTEGER; + BEGIN + IF start_author <> '' THEN + __post_id = find_comment_id( start_author, start_permlink, True ); + END IF; + __account_id = find_account_id(_account, False); + IF __account_id = 0 THEN + RETURN; + END IF; + RETURN QUERY SELECT + hpr.id as id + FROM hive_posts hpr + JOIN hive_posts hp ON hp.id = hpr.parent_id + WHERE hp.author_id = __account_id AND hp.counter_deleted = 0 AND hpr.counter_deleted = 0 AND ( __post_id = -1 OR hpr.id < __post_id ) + ORDER BY hpr.id DESC LIMIT _limit; + END + $function$ + LANGUAGE plpgsql STABLE + """ + db.query_no_return(sql) + def reset_autovac(db): """Initializes/resets per-table autovacuum/autoanalyze params. diff --git a/hive/server/bridge_api/cursor.py b/hive/server/bridge_api/cursor.py index dc046a863b8fe9119c576e699a909392cf3c692d..ef1e6468d6ee94bba70be7498362c5d2a32da436 100644 --- a/hive/server/bridge_api/cursor.py +++ b/hive/server/bridge_api/cursor.py @@ -351,50 +351,14 @@ async def pids_by_comments(db, account: str, start_permlink: str = '', limit: in return await db.query_col(sql, account=account, start_id=start_id, limit=limit) -async def pids_by_replies(db, start_author: str, start_permlink: str = '', +async def pids_by_replies(db, author: str, start_replies_author: str, start_replies_permlink: str = '', limit: int = 20): """Get a list of post_ids representing replies to an author. - - To get the first page of results, specify `start_author` as the - account being replied to. For successive pages, provide the - last loaded reply's author/permlink. """ - seek = '' - start_id = None - if start_permlink: - sql = """ - SELECT (SELECT name FROM hive_accounts WHERE id = parent.author_id), - child.id - FROM hive_posts child - JOIN hive_posts parent - ON child.parent_id = parent.id - WHERE child.author_id = (SELECT id FROM hive_accounts WHERE name = :author) - AND child.permlink = (SELECT id FROM hive_permlink_data WHERE permlink = :permlink) - """ - - row = await db.query_row(sql, author=start_author, permlink=start_permlink) - if not row: - return [] - - parent_account = row[0] - start_id = row[1] - seek = "AND id <= :start_id" - else: - parent_account = start_author - - sql = """ - SELECT id FROM hive_posts - WHERE parent_id IN (SELECT id FROM hive_posts - WHERE author_id = (SELECT id FROM hive_accounts WHERE name = :parent) - AND counter_deleted = 0 - ORDER BY id DESC - LIMIT 10000) %s - AND counter_deleted = 0 - ORDER BY id DESC - LIMIT :limit - """ % seek - return await db.query_col(sql, parent=parent_account, start_id=start_id, limit=limit) + sql = "SELECT get_account_post_replies( (:author)::VARCHAR, (:start_author)::VARCHAR, (:start_permlink)::VARCHAR, (:limit)::SMALLINT ) as id" + return await db.query_col( + sql, author=author, start_author=start_replies_author, start_permlink=start_replies_permlink, limit=limit) async def pids_by_payout(db, account: str, start_author: str = '', start_permlink: str = '', limit: int = 20): diff --git a/hive/server/bridge_api/methods.py b/hive/server/bridge_api/methods.py index 52ff634999a07f2a066a47b54b098da2f38ec748..4d8ded7e872826e842d3fd9b5bb6f917bebbe156 100644 --- a/hive/server/bridge_api/methods.py +++ b/hive/server/bridge_api/methods.py @@ -318,8 +318,7 @@ async def get_account_posts(context, sort, account, start_author='', start_perml res = await cursor.pids_by_feed_with_reblog(db, account, *start, limit) return await load_posts_reblogs(context['db'], res) elif sort == 'replies': - start = start if start_permlink else (account, None) - ids = await cursor.pids_by_replies(db, *start, limit) + ids = await cursor.pids_by_replies(db, account, start_author, start_permlink, limit) return await load_posts(context['db'], ids) if start_author and start_permlink: diff --git a/scripts/upgrade.sql b/scripts/upgrade.sql index b8b77882bdc8ce36e56801ff42ac2f12d2233eb7..6b156a75142803048b663e22a21559f79efdf4a2 100644 --- a/scripts/upgrade.sql +++ b/scripts/upgrade.sql @@ -319,3 +319,50 @@ END $function$ language plpgsql STABLE ; + +DROP FUNCTION IF EXISTS find_account_id(character varying, boolean) +; +CREATE OR REPLACE FUNCTION find_account_id( + in _account hive_accounts.name%TYPE, + in _check boolean) +RETURNS INT +LANGUAGE 'plpgsql' +AS +$function$ +DECLARE + account_id INT; +BEGIN + SELECT INTO account_id COALESCE( ( SELECT id FROM hive_accounts WHERE name=_account ), 0 ); + IF _check AND account_id = 0 THEN + RAISE EXCEPTION 'Account % does not exist', _account; + END IF; + RETURN account_id; +END +$function$ +; + +DROP FUNCTION IF EXISTS get_account_post_replies; +CREATE FUNCTION get_account_post_replies( in _account VARCHAR, in start_author VARCHAR, in start_permlink VARCHAR, in _limit SMALLINT ) +RETURNS SETOF INTEGER +AS +$function$ +DECLARE + __post_id INTEGER = -1; + __account_id INTEGER; +BEGIN + IF start_author <> '' THEN + __post_id = find_comment_id( start_author, start_permlink, True ); + END IF; + __account_id = find_account_id(_account, False); + IF __account_id = 0 THEN + RETURN; + END IF; + RETURN QUERY SELECT + hpr.id as id + FROM hive_posts hpr + JOIN hive_posts hp ON hp.id = hpr.parent_id + WHERE hp.author_id = __account_id AND hp.counter_deleted = 0 AND hpr.counter_deleted = 0 AND ( __post_id = -1 OR hpr.id < __post_id ) + ORDER BY hpr.id DESC LIMIT _limit; +END +$function$ +LANGUAGE plpgsql STABLE