From 9129904623ec8fe406b6cc1ad5e6ed4472a92f2c Mon Sep 17 00:00:00 2001
From: Dariusz Kedzierski <dkedzierski@syncad.com>
Date: Thu, 7 May 2020 09:53:27 +0200
Subject: [PATCH] Fixes and improvements, tests in progress

---
 hive/server/database_api/methods.py | 77 +++++++++++++++++++++--------
 scripts/update_hivemind_db.sql      |  4 ++
 2 files changed, 61 insertions(+), 20 deletions(-)

diff --git a/hive/server/database_api/methods.py b/hive/server/database_api/methods.py
index 9aef5a97a..03ed63409 100644
--- a/hive/server/database_api/methods.py
+++ b/hive/server/database_api/methods.py
@@ -2,26 +2,31 @@
 from hive.server.common.helpers import return_error_info, valid_limit
 from hive.server.common.objects import condenser_post_object
 
+async def get_post_id_by_author_and_permlink(db, author: str, permlink: str, limit: int):
+    """Return post ids for given author and permlink"""
+    sql = """SELECT post_id FROM hive_posts_cache WHERE author >= :author AND permlink >= :permlink ORDER BY author ASC, permlink ASC, post_id ASC LIMIT :limit"""
+    result = await db.query_row(sql, author=author, permlink=permlink, limit=limit)
+    return result.post_id
+
 @return_error_info
 async def list_comments(context, start: list, limit: int, order: str):
     """Returns all comments, starting with the specified options."""
     print("Hivemind native list_comments")
-    supported_order_list = ['by_cashout_time', 'by_permlink', 'by_root', 'by_parent']
-    assert order in supported_order_list, "Unsupported order, valid orders {}".format(supported_order_list)
+    supported_order_list = ['by_cashout_time', 'by_permlink', 'by_root', 'by_parent', 'by_update', 'by_author_last_update']
+    assert order in supported_order_list, "Unsupported order, valid orders: {}".format(", ".join(supported_order_list))
     limit = valid_limit(limit, 1000)
     db = context['db']
 
     comments = []
     if order == 'by_cashout_time':
         assert len(start) == 3, "Expecting three arguments"
-        payout_time = start[0]
+
         author = start[1]
         permlink = start[2]
         post_id = 0
         if author or permlink:
-            sql = """SELECT post_id FROM hive_posts_cache WHERE author >= :author AND permlink >= :permlink LIMIT 1"""
-            result = await db.query_row(sql, author=author, permlink=permlink)
-            post_id = result.post_id
+            post_id = await get_post_id_by_author_and_permlink(db, author, permlink, 1)
+
         sql = """SELECT post_id, community_id, author, permlink, title, body, category, depth,
                     promoted, payout, payout_at, is_paidout, children, votes,
                     created_at, updated_at, rshares, json,
@@ -30,13 +35,12 @@ async def list_comments(context, start: list, limit: int, order: str):
                     root_author, root_permlink, max_accepted_payout, percent_steem_dollars, 
                     allow_replies, allow_votes, allow_curation_rewards, url, root_title 
                FROM hive_posts_cache WHERE payout_at >= :start AND post_id >= :post_id ORDER BY payout_at ASC, post_id ASC LIMIT :limit"""
-        result = await db.query_all(sql, start=payout_time, limit=limit, post_id=post_id)
+        result = await db.query_all(sql, start=start[0], limit=limit, post_id=post_id)
         for row in result:
             comments.append(condenser_post_object(dict(row)))
     elif order == 'by_permlink':
         assert len(start) == 2, "Expecting two arguments"
-        author = start[0]
-        permlink = start[1]
+
         sql = """SELECT post_id, community_id, author, permlink, title, body, category, depth,
                     promoted, payout, payout_at, is_paidout, children, votes,
                     created_at, updated_at, rshares, json,
@@ -45,16 +49,11 @@ async def list_comments(context, start: list, limit: int, order: str):
                     root_author, root_permlink, max_accepted_payout, percent_steem_dollars, 
                     allow_replies, allow_votes, allow_curation_rewards, url, root_title 
                FROM hive_posts_cache WHERE author >= :author AND permlink >= :permlink ORDER BY author ASC, permlink ASC, post_id ASC LIMIT :limit"""
-        result = await db.query_all(sql, author=author, permlink=permlink, limit=limit)
+        result = await db.query_all(sql, author=start[0], permlink=start[1], limit=limit)
         for row in result:
             comments.append(condenser_post_object(dict(row)))
     elif order == 'by_root':
         assert len(start) == 4, "Expecting 4 arguments"
-        root_author = start[0]
-        root_permlink = start[1]
-
-        child_author = start[2]
-        child_permlink = start[3]
 
         sql = """SELECT post_id, community_id, author, permlink, title, body, category, depth,
                     promoted, payout, payout_at, is_paidout, children, votes,
@@ -64,18 +63,33 @@ async def list_comments(context, start: list, limit: int, order: str):
                     root_author, root_permlink, max_accepted_payout, percent_steem_dollars, 
                     allow_replies, allow_votes, allow_curation_rewards, url, root_title 
                FROM get_rows_by_root(:root_author, :root_permlink, :child_author, :child_permlink) ORDER BY post_id ASC LIMIT :limit"""
-        result = await db.query_all(sql, root_author=root_author, root_permlink=root_permlink, child_author=child_author, child_permlink=child_permlink, limit=limit)
+        result = await db.query_all(sql, root_author=start[0], root_permlink=start[1], child_author=start[2], child_permlink=start[3], limit=limit)
         for row in result:
             comments.append(condenser_post_object(dict(row)))
     elif order == 'by_parent':
         assert len(start) == 4, "Expecting 4 arguments"
 
-        parent_author = start[0]
-        parent_permlink = start[1]
+        sql = """SELECT post_id, community_id, author, permlink, title, body, category, depth,
+                    promoted, payout, payout_at, is_paidout, children, votes,
+                    created_at, updated_at, rshares, json,
+                    is_hidden, is_grayed, total_votes, flag_weight,
+                    legacy_id, parent_author, parent_permlink, curator_payout_value, 
+                    root_author, root_permlink, max_accepted_payout, percent_steem_dollars, 
+                    allow_replies, allow_votes, allow_curation_rewards, url, root_title 
+               FROM get_rows_by_parent(:parent_author, :parent_permlink, :child_author, :child_permlink) LIMIT :limit"""
+        result = await db.query_all(sql, parent_author=start[0], parent_permlink=start[1], child_author=start[2], child_permlink=start[3], limit=limit)
+        for row in result:
+            comments.append(condenser_post_object(dict(row)))
+    elif order == 'by_update':
+        assert len(start) == 4, "Expecting 4 arguments"
 
         child_author = start[2]
         child_permlink = start[3]
 
+        post_id = 0
+        if author or permlink:
+            post_id = await get_post_id_by_author_and_permlink(db, child_author, child_permlink, 1)
+
         sql = """SELECT post_id, community_id, author, permlink, title, body, category, depth,
                     promoted, payout, payout_at, is_paidout, children, votes,
                     created_at, updated_at, rshares, json,
@@ -83,8 +97,31 @@ async def list_comments(context, start: list, limit: int, order: str):
                     legacy_id, parent_author, parent_permlink, curator_payout_value, 
                     root_author, root_permlink, max_accepted_payout, percent_steem_dollars, 
                     allow_replies, allow_votes, allow_curation_rewards, url, root_title 
-               FROM get_rows_by_parent(:parent_author, :parent_permlink, :child_author, :child_permlink) LIMIT :limit"""
-        result = await db.query_all(sql, parent_author=parent_author, parent_permlink=parent_permlink, child_author=child_author, child_permlink=child_permlink, limit=limit)
+               FROM hive_posts_cache WHERE parent_author >= :parent_author AND updated_at >= :updated_at AND post_id >= :post_id ORDER BY parent_author ASC, updated_at ASC, post_id ASC LIMIT :limit"""
+        result = await db.query_all(sql, parent_author=start[0], updated_at=start[1], post_id=post_id, limit=limit)
         for row in result:
             comments.append(condenser_post_object(dict(row)))
+
+    elif order == 'by_author_last_update':
+        assert len(start) == 4, "Expecting 4 arguments"
+
+        author = start[2]
+        permlink = start[3]
+
+        post_id = 0
+        if author or permlink:
+            post_id = await get_post_id_by_author_and_permlink(db, author, permlink, 1)
+
+        sql = """SELECT post_id, community_id, author, permlink, title, body, category, depth,
+                    promoted, payout, payout_at, is_paidout, children, votes,
+                    created_at, updated_at, rshares, json,
+                    is_hidden, is_grayed, total_votes, flag_weight,
+                    legacy_id, parent_author, parent_permlink, curator_payout_value, 
+                    root_author, root_permlink, max_accepted_payout, percent_steem_dollars, 
+                    allow_replies, allow_votes, allow_curation_rewards, url, root_title 
+               FROM hive_posts_cache WHERE author >= :author AND updated_at >= :updated_at AND post_id >= :post_id ORDER BY parent_author ASC, updated_at ASC, post_id ASC LIMIT :limit"""
+        result = await db.query_all(sql, author=start[0], updated_at=start[1], post_id=post_id, limit=limit)
+        for row in result:
+            comments.append(condenser_post_object(dict(row)))
+
     return comments
diff --git a/scripts/update_hivemind_db.sql b/scripts/update_hivemind_db.sql
index d15a676df..05e0201ee 100644
--- a/scripts/update_hivemind_db.sql
+++ b/scripts/update_hivemind_db.sql
@@ -96,6 +96,10 @@ DO $$
       CREATE INDEX IF NOT EXISTS author_permlink_post_id_idx ON hive_posts_cache (author ASC, permlink ASC, post_id ASC);
       RAISE NOTICE 'Creating post_id_author_permlink_idx';
       CREATE INDEX IF NOT EXISTS post_id_author_permlink_idx ON hive_posts_cache (post_id ASC, author ASC, permlink ASC);
+      RAISE NOTICE 'Creating parent_updated_id_idx';
+      CREATE INDEX IF NOT EXISTS parent_updated_id_idx ON hive_posts_cache (parent_author ASC, updated_at ASC, post_id ASC);
+      RAISE NOTICE 'Creating author_updated_id_idx';
+      CREATE INDEX IF NOT EXISTS author_updated_id_idx ON hive_posts_cache (author ASC, updated_at ASC, post_id ASC);
 
       -- Creating functions
       -- for list_comments by_root
-- 
GitLab