Skip to content
Snippets Groups Projects
Commit 32d9770b authored by Mariusz Trela's avatar Mariusz Trela
Browse files

Refactoring of `get_state` method

parent 079f40af
No related branches found
No related tags found
2 merge requests!456Release candidate v1 24,!339Further simplifications regarding `get_pids*` methods
...@@ -3,7 +3,7 @@ CREATE OR REPLACE VIEW public.hive_accounts_info_view ...@@ -3,7 +3,7 @@ CREATE OR REPLACE VIEW public.hive_accounts_info_view
AS AS
SELECT ha.id, SELECT ha.id,
ha.name, ha.name,
COALESCE(posts.post_count, 0::bigint) AS post_count, ha.post_count,
ha.created_at, ha.created_at,
( SELECT GREATEST(ha.created_at, ( SELECT GREATEST(ha.created_at,
COALESCE(latest_post.latest_post, '1970-01-01 00:00:00'::timestamp without time zone), COALESCE(latest_post.latest_post, '1970-01-01 00:00:00'::timestamp without time zone),
...@@ -21,13 +21,7 @@ CREATE OR REPLACE VIEW public.hive_accounts_info_view ...@@ -21,13 +21,7 @@ CREATE OR REPLACE VIEW public.hive_accounts_info_view
( (
SELECT max(hb.num) - 1200 * 24 * 7 AS block_limit FROM hive_blocks hb SELECT max(hb.num) - 1200 * 24 * 7 AS block_limit FROM hive_blocks hb
) bl, ) bl,
hive_accounts ha hive_accounts_info_view_lite ha
LEFT JOIN LATERAL
(
SELECT COUNT(1) AS post_count
FROM hive_posts hp
WHERE hp.counter_deleted = 0 and hp.author_id = ha.id
) posts ON true
LEFT JOIN lateral LEFT JOIN lateral
( (
SELECT hp1.created_at AS latest_post SELECT hp1.created_at AS latest_post
...@@ -53,3 +47,25 @@ CREATE OR REPLACE VIEW public.hive_accounts_info_view ...@@ -53,3 +47,25 @@ CREATE OR REPLACE VIEW public.hive_accounts_info_view
) whole_votes ON true ) whole_votes ON true
; ;
DROP VIEW IF EXISTS hive_accounts_info_view_lite;
CREATE OR REPLACE VIEW public.hive_accounts_info_view_lite
AS
SELECT ha.id,
ha.name,
COALESCE(posts.post_count, 0::bigint) AS post_count,
ha.created_at,
ha.reputation,
ha.rank,
ha.following,
ha.followers,
ha.lastread_at,
ha.posting_json_metadata,
ha.json_metadata
FROM hive_accounts ha
LEFT JOIN LATERAL
(
SELECT COUNT(1) AS post_count
FROM hive_posts hp
WHERE hp.counter_deleted = 0 and hp.author_id = ha.id
) posts ON true
;
...@@ -66,19 +66,19 @@ def json_date(date=None): ...@@ -66,19 +66,19 @@ def json_date(date=None):
if not date or date == datetime.datetime.max: return '1969-12-31T23:59:59' if not date or date == datetime.datetime.max: return '1969-12-31T23:59:59'
return 'T'.join(str(date).split(' ')) return 'T'.join(str(date).split(' '))
def get_hive_accounts_info_view_query_string(names): def get_hive_accounts_info_view_query_string(names, lite = False):
values = [] values = []
for name in names: for name in names:
values.append("('{}')".format( name )) values.append("('{}')".format( name ))
values_str = ','.join(values) values_str = ','.join(values)
sql = """ sql = """
SELECT * SELECT *
FROM hive_accounts_info_view v FROM {} v
JOIN JOIN
( (
VALUES {} VALUES {}
)T( _name ) ON v.name = T._name )T( _name ) ON v.name = T._name
""".format( values_str ) """.format( ( 'hive_accounts_info_view_lite' if lite else 'hive_accounts_info_view' ), values_str )
return sql return sql
def last_month(): def last_month():
......
...@@ -12,7 +12,9 @@ from hive.server.common.mutes import Mutes ...@@ -12,7 +12,9 @@ from hive.server.common.mutes import Mutes
from hive.server.condenser_api.objects import ( from hive.server.condenser_api.objects import (
load_accounts, load_accounts,
load_posts, load_posts,
load_posts_keyed) load_posts_keyed,
_mute_votes,
_condenser_post_object)
from hive.server.common.helpers import ( from hive.server.common.helpers import (
ApiError, ApiError,
return_error_info, return_error_info,
...@@ -30,6 +32,8 @@ from hive.server.condenser_api.methods import get_posts_by_given_sort ...@@ -30,6 +32,8 @@ from hive.server.condenser_api.methods import get_posts_by_given_sort
from hive.server.hive_api.public import get_by_feed_with_reblog_impl from hive.server.hive_api.public import get_by_feed_with_reblog_impl
from hive.server.database_api.methods import find_votes_impl, VotesPresentation
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
# steemd account 'tabs' - specific post list queries # steemd account 'tabs' - specific post list queries
...@@ -131,7 +135,7 @@ async def get_state(context, path: str): ...@@ -131,7 +135,7 @@ async def get_state(context, path: str):
author = valid_account(part[1][1:]) author = valid_account(part[1][1:])
permlink = valid_permlink(part[2]) permlink = valid_permlink(part[2])
state['content'] = await _load_discussion(db, author, permlink) state['content'] = await _load_discussion(db, author, permlink)
state['accounts'] = await _load_content_accounts(db, state['content']) state['accounts'] = await _load_content_accounts(db, state['content'], True)
# ranked posts - `/sort/category` # ranked posts - `/sort/category`
elif part[0] in POST_LIST_SORTS: elif part[0] in POST_LIST_SORTS:
...@@ -205,12 +209,15 @@ def _keyed_posts(posts): ...@@ -205,12 +209,15 @@ def _keyed_posts(posts):
def _ref(post): def _ref(post):
return post['author'] + '/' + post['permlink'] return post['author'] + '/' + post['permlink']
async def _load_content_accounts(db, content): def _ref_parent(post):
return post['parent_author'] + '/' + post['parent_permlink']
async def _load_content_accounts(db, content, lite = False):
if not content: if not content:
return {} return {}
posts = content.values() posts = content.values()
names = set(map(lambda p: p['author'], posts)) names = set(map(lambda p: p['author'], posts))
accounts = await load_accounts(db, names) accounts = await load_accounts(db, names, lite)
return {a['name']: a for a in accounts} return {a['name']: a for a in accounts}
async def _load_account(db, name): async def _load_account(db, name):
...@@ -235,47 +242,39 @@ async def _child_ids(db, parent_ids): ...@@ -235,47 +242,39 @@ async def _child_ids(db, parent_ids):
async def _load_discussion(db, author, permlink): async def _load_discussion(db, author, permlink):
"""Load a full discussion thread.""" """Load a full discussion thread."""
root_id = await cursor.get_post_id(db, author, permlink)
if not root_id:
return {}
# build `ids` list and `tree` map sql = "SELECT * FROM get_discussion('{}','{}')".format( author, permlink)
ids = [] sql_result = await db.query_all(sql)
tree = {}
todo = [root_id]
while todo:
ids.extend(todo)
rows = await _child_ids(db, todo)
todo = []
for pid, cids in rows:
tree[pid] = cids
todo.extend(cids)
# load all post objects, build ref-map
posts = await load_posts_keyed(db, ids)
# remove posts/comments from muted accounts
muted_accounts = Mutes.all() muted_accounts = Mutes.all()
rem_pids = [] posts = []
for pid, post in posts.items(): posts_by_id = {}
if post['author'] in muted_accounts: replies = {}
rem_pids.append(pid)
for pid in rem_pids: for row in sql_result:
if pid in posts: post = _condenser_post_object(row)
del posts[pid]
if pid in tree: if post['author'] not in muted_accounts:
rem_pids.extend(tree[pid]) post['active_votes'] = await find_votes_impl(db, row['author'], row['permlink'], VotesPresentation.CondenserApi)
post['active_votes'] = _mute_votes(post['active_votes'], muted_accounts)
refs = {pid: _ref(post) for pid, post in posts.items()} posts.append(post)
# add child refs to parent posts parent_key = _ref_parent(post)
for pid, post in posts.items(): _key = _ref(post)
if pid in tree: if parent_key not in replies:
post['replies'] = [refs[cid] for cid in tree[pid] replies[parent_key] = []
if cid in refs] replies[parent_key].append(_key)
# return all nodes keyed by ref for post in posts:
return {refs[pid]: post for pid, post in posts.items()} _key = _ref(post)
if _key in replies:
replies[_key].sort()
post['replies'] = replies[_key]
for post in posts:
posts_by_id[_ref(post)] = post
return posts_by_id
@cached(ttl=1800, timeout=1200) @cached(ttl=1800, timeout=1200)
async def _get_feed_price(db): async def _get_feed_price(db):
......
...@@ -13,9 +13,9 @@ log = logging.getLogger(__name__) ...@@ -13,9 +13,9 @@ log = logging.getLogger(__name__)
# Building of legacy account objects # Building of legacy account objects
async def load_accounts(db, names): async def load_accounts(db, names, lite = False):
"""`get_accounts`-style lookup for `get_state` compat layer.""" """`get_accounts`-style lookup for `get_state` compat layer."""
sql = get_hive_accounts_info_view_query_string( names ) sql = get_hive_accounts_info_view_query_string( names, lite )
rows = await db.query_all(sql, names=tuple(names)) rows = await db.query_all(sql, names=tuple(names))
return [_condenser_account_object(row) for row in rows] return [_condenser_account_object(row) for row in rows]
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment