diff --git a/hive/db/schema.py b/hive/db/schema.py index a536fbcef3e4bba85833c1b796d7ad94590a425d..7061ebd9b2ea14bef29c6b123bc7ff410a7dfefd 100644 --- a/hive/db/schema.py +++ b/hive/db/schema.py @@ -10,7 +10,8 @@ from sqlalchemy.types import BOOLEAN #pylint: disable=line-too-long, too-many-lines, bad-whitespace -DB_VERSION = 17 +# [DK] we changed and removed some tables so i upgraded DB_VERSION to 18 +DB_VERSION = 18 def build_metadata(): """Build schema def with SqlAlchemy""" @@ -72,9 +73,9 @@ def build_metadata(): 'hive_posts', metadata, sa.Column('id', sa.Integer, primary_key=True), sa.Column('parent_id', sa.Integer), - sa.Column('author', VARCHAR(16), nullable=False), - sa.Column('permlink', VARCHAR(255), nullable=False), - sa.Column('category', VARCHAR(255), nullable=False, server_default=''), + sa.Column('author_id', sa.Integer, nullable=False), + sa.Column('permlink_id', sa.Integer, nullable=False), + sa.Column('category_id', sa.Integer, nullable=False), sa.Column('community_id', sa.Integer, nullable=True), sa.Column('created_at', sa.DateTime, nullable=False), sa.Column('depth', SMALLINT, nullable=False), @@ -84,13 +85,74 @@ def build_metadata(): sa.Column('is_valid', BOOLEAN, nullable=False, server_default='1'), sa.Column('promoted', sa.types.DECIMAL(10, 3), nullable=False, server_default='0'), - sa.ForeignKeyConstraint(['author'], ['hive_accounts.name'], name='hive_posts_fk1'), + sa.Column('children', SMALLINT, nullable=False, server_default='0'), + + # basic/extended-stats + sa.Column('author_rep', sa.Float(precision=6), nullable=False, server_default='0'), + sa.Column('flag_weight', sa.Float(precision=6), nullable=False, server_default='0'), + sa.Column('total_votes', sa.Integer, nullable=False, server_default='0'), + sa.Column('up_votes', sa.Integer, nullable=False, server_default='0'), + + # core stats/indexes + sa.Column('payout', sa.types.DECIMAL(10, 3), nullable=False, server_default='0'), + sa.Column('payout_at', sa.DateTime, nullable=False, server_default='1990-01-01'), + sa.Column('updated_at', sa.DateTime, nullable=False, server_default='1990-01-01'), + sa.Column('is_paidout', BOOLEAN, nullable=False, server_default='0'), + + # ui flags/filters + sa.Column('is_nsfw', BOOLEAN, nullable=False, server_default='0'), + sa.Column('is_declined', BOOLEAN, nullable=False, server_default='0'), + sa.Column('is_full_power', BOOLEAN, nullable=False, server_default='0'), + sa.Column('is_hidden', BOOLEAN, nullable=False, server_default='0'), + sa.Column('is_grayed', BOOLEAN, nullable=False, server_default='0'), + + # important indexes + sa.Column('rshares', sa.BigInteger, nullable=False, server_default='0'), + sa.Column('sc_trend', sa.Float(precision=6), nullable=False, server_default='0'), + sa.Column('sc_hot', sa.Float(precision=6), nullable=False, server_default='0'), + + sa.Column('parent_author_id', sa.Integer, nullable=False), + sa.Column('parent_permlink_id', sa.Integer, nullable=False), + sa.Column('curator_payout_value', sa.String(16), nullable=False, server_default=''), + sa.Column('root_author_id', sa.Integer, nullable=False), + sa.Column('root_permlink_id', sa.Integer, nullable=False), + sa.Column('max_accepted_payout', sa.String(16), nullable=False, server_default=''), + sa.Column('percent_steem_dollars', sa.Integer, nullable=False, server_default='-1'), + sa.Column('allow_replies', BOOLEAN, nullable=False, server_default='1'), + sa.Column('allow_votes', BOOLEAN, nullable=False, server_default='1'), + sa.Column('allow_curation_rewards', BOOLEAN, nullable=False, server_default='1'), + sa.Column('beneficiaries', sa.JSON, nullable=False, server_default='[]'), + sa.Column('url', sa.Text, nullable=False, server_default=''), + sa.Column('root_title', sa.String(255), nullable=False, server_default=''), + + sa.ForeignKeyConstraint(['author_id'], ['hive_accounts.id'], name='hive_posts_fk1'), sa.ForeignKeyConstraint(['parent_id'], ['hive_posts.id'], name='hive_posts_fk3'), - sa.UniqueConstraint('author', 'permlink', name='hive_posts_ux1'), - sa.Index('hive_posts_ix3', 'author', 'depth', 'id', postgresql_where=sql_text("is_deleted = '0'")), # API: author blog/comments - sa.Index('hive_posts_ix4', 'parent_id', 'id', postgresql_where=sql_text("is_deleted = '0'")), # API: fetching children - sa.Index('hive_posts_ix5', 'id', postgresql_where=sql_text("is_pinned = '1' AND is_deleted = '0'")), # API: pinned post status - sa.Index('hive_posts_ix6', 'community_id', 'id', postgresql_where=sql_text("community_id IS NOT NULL AND is_pinned = '1' AND is_deleted = '0'")), # API: community pinned + sa.UniqueConstraint('author_id', 'permlink_id', name='hive_posts_ux1'), + ) + + sa.Table( + 'hive_post_data', metadata, + sa.column('id', sa.Integer, nullable=False), + sa.column('title', VARCHAR(255), nullable=False), + sa.column('preview', VARCHAR(1024), nullable=False), + sa.column('img_url', VARCHAR(1024), nullable=False), + sa.Column('body', TEXT), + sa.Column('votes', TEXT), + sa.Column('json', sa.JSON) + ) + + sa.Table( + 'hive_permlink_data', metadata, + sa.column('id', sa.Integer, primary_key=True), + sa.column('permlink', sa.String(255), nullable=False), + sa.UniqueConstraint('permlink', name='hive_permlink_data_permlink') + ) + + sa.Table( + 'hive_category_data', metadata, + sa.column('id', sa.Integer, primary_key=True), + sa.column('category', sa.String(255), nullable=False), + sa.UniqueConstraint('category', name='hive_category_data_category') ) sa.Table( @@ -150,100 +212,6 @@ def build_metadata(): sa.Index('hive_feed_cache_ix1', 'account_id', 'post_id', 'created_at'), # API (and rebuild?) ) - sa.Table( - 'hive_posts_cache', metadata, - sa.Column('post_id', sa.Integer, primary_key=True, autoincrement=False), - sa.Column('author', VARCHAR(16), nullable=False), - sa.Column('permlink', VARCHAR(255), nullable=False), - sa.Column('category', VARCHAR(255), nullable=False, server_default=''), - - # important/index - sa.Column('community_id', sa.Integer, nullable=True), - sa.Column('depth', SMALLINT, nullable=False, server_default='0'), - sa.Column('children', SMALLINT, nullable=False, server_default='0'), - - # basic/extended-stats - sa.Column('author_rep', sa.Float(precision=6), nullable=False, server_default='0'), - sa.Column('flag_weight', sa.Float(precision=6), nullable=False, server_default='0'), - sa.Column('total_votes', sa.Integer, nullable=False, server_default='0'), - sa.Column('up_votes', sa.Integer, nullable=False, server_default='0'), - - # basic ui fields - sa.Column('title', sa.String(255), nullable=False, server_default=''), - sa.Column('preview', sa.String(1024), nullable=False, server_default=''), - sa.Column('img_url', sa.String(1024), nullable=False, server_default=''), - - # core stats/indexes - sa.Column('payout', sa.types.DECIMAL(10, 3), nullable=False, server_default='0'), - sa.Column('promoted', sa.types.DECIMAL(10, 3), nullable=False, server_default='0'), - sa.Column('created_at', sa.DateTime, nullable=False, server_default='1990-01-01'), - sa.Column('payout_at', sa.DateTime, nullable=False, server_default='1990-01-01'), - sa.Column('updated_at', sa.DateTime, nullable=False, server_default='1990-01-01'), - sa.Column('is_paidout', BOOLEAN, nullable=False, server_default='0'), - - # ui flags/filters - sa.Column('is_nsfw', BOOLEAN, nullable=False, server_default='0'), - sa.Column('is_declined', BOOLEAN, nullable=False, server_default='0'), - sa.Column('is_full_power', BOOLEAN, nullable=False, server_default='0'), - sa.Column('is_hidden', BOOLEAN, nullable=False, server_default='0'), - sa.Column('is_grayed', BOOLEAN, nullable=False, server_default='0'), - - # important indexes - sa.Column('rshares', sa.BigInteger, nullable=False, server_default='0'), - sa.Column('sc_trend', sa.Float(precision=6), nullable=False, server_default='0'), - sa.Column('sc_hot', sa.Float(precision=6), nullable=False, server_default='0'), - - # bulk data - sa.Column('body', TEXT), - sa.Column('votes', TEXT), - sa.Column('json', sa.Text), - #sa.Column('raw_json', sa.Text), - - sa.Column('legacy_id', sa.Integer, nullable=False, server_default='-1'), - sa.Column('parent_author', sa.String(16), nullable=False, server_default=''), - sa.Column('parent_permlink', sa.String(255), nullable=False, server_default=''), - sa.Column('curator_payout_value', sa.String(16), nullable=False, server_default=''), - sa.Column('root_author', sa.String(16), nullable=False, server_default=''), - sa.Column('root_permlink', sa.String(255), nullable=False, server_default=''), - sa.Column('max_accepted_payout', sa.String(16), nullable=False, server_default=''), - sa.Column('percent_steem_dollars', sa.Integer, nullable=False, server_default='-1'), - sa.Column('allow_replies', BOOLEAN, nullable=False, server_default='1'), - sa.Column('allow_votes', BOOLEAN, nullable=False, server_default='1'), - sa.Column('allow_curation_rewards', BOOLEAN, nullable=False, server_default='1'), - sa.Column('beneficiaries', sa.JSON, nullable=False, server_default=''), - sa.Column('url', sa.Text, nullable=False, server_default=''), - sa.Column('root_title', sa.String(255), nullable=False, server_default=''), - - sa.Column('author_permlink', sa.String(255 + 16, collation='C'), nullable=False, server_default=''), - - # index: misc - sa.Index('hive_posts_cache_ix3', 'payout_at', 'post_id', postgresql_where=sql_text("is_paidout = '0'")), # core: payout sweep - sa.Index('hive_posts_cache_ix8', 'category', 'payout', 'depth', postgresql_where=sql_text("is_paidout = '0'")), # API: tag stats - - # index: ranked posts - sa.Index('hive_posts_cache_ix2', 'promoted', postgresql_where=sql_text("is_paidout = '0' AND promoted > 0")), # API: promoted - - sa.Index('hive_posts_cache_ix6a', 'sc_trend', 'post_id', postgresql_where=sql_text("is_paidout = '0'")), # API: trending todo: depth=0 - sa.Index('hive_posts_cache_ix7a', 'sc_hot', 'post_id', postgresql_where=sql_text("is_paidout = '0'")), # API: hot todo: depth=0 - sa.Index('hive_posts_cache_ix6b', 'post_id', 'sc_trend', postgresql_where=sql_text("is_paidout = '0'")), # API: trending, filtered todo: depth=0 - sa.Index('hive_posts_cache_ix7b', 'post_id', 'sc_hot', postgresql_where=sql_text("is_paidout = '0'")), # API: hot, filtered todo: depth=0 - - sa.Index('hive_posts_cache_ix9a', 'depth', 'payout', 'post_id', postgresql_where=sql_text("is_paidout = '0'")), # API: payout todo: rem depth - sa.Index('hive_posts_cache_ix9b', 'category', 'depth', 'payout', 'post_id', postgresql_where=sql_text("is_paidout = '0'")), # API: payout, filtered todo: rem depth - - sa.Index('hive_posts_cache_ix10', 'post_id', 'payout', postgresql_where=sql_text("is_grayed = '1' AND payout > 0")), # API: muted, by filter/date/payout - - # index: stats - sa.Index('hive_posts_cache_ix20', 'community_id', 'author', 'payout', 'post_id', postgresql_where=sql_text("is_paidout = '0'")), # API: pending distribution; author payout - - # index: community ranked posts - sa.Index('hive_posts_cache_ix30', 'community_id', 'sc_trend', 'post_id', postgresql_where=sql_text("community_id IS NOT NULL AND is_grayed = '0' AND depth = 0")), # API: community trend - sa.Index('hive_posts_cache_ix31', 'community_id', 'sc_hot', 'post_id', postgresql_where=sql_text("community_id IS NOT NULL AND is_grayed = '0' AND depth = 0")), # API: community hot - sa.Index('hive_posts_cache_ix32', 'community_id', 'created_at', 'post_id', postgresql_where=sql_text("community_id IS NOT NULL AND is_grayed = '0' AND depth = 0")), # API: community created - sa.Index('hive_posts_cache_ix33', 'community_id', 'payout', 'post_id', postgresql_where=sql_text("community_id IS NOT NULL AND is_grayed = '0' AND is_paidout = '0'")), # API: community payout - sa.Index('hive_posts_cache_ix34', 'community_id', 'payout', 'post_id', postgresql_where=sql_text("community_id IS NOT NULL AND is_grayed = '1' AND is_paidout = '0'")), # API: community muted - ) - sa.Table( 'hive_state', metadata, sa.Column('block_num', sa.Integer, primary_key=True, autoincrement=False), @@ -369,7 +337,6 @@ def reset_autovac(db): autovac_config = { # vacuum analyze 'hive_accounts': (50000, 100000), - 'hive_posts_cache': (25000, 25000), 'hive_posts': (2500, 10000), 'hive_post_tags': (5000, 10000), 'hive_follows': (5000, 5000), diff --git a/hive/indexer/blocks.py b/hive/indexer/blocks.py index 58af5b48ffa431036cbd6b57f887e73ec428f971..fa47f4af8f7ce4081c3f289c7a602aefaf536e3b 100644 --- a/hive/indexer/blocks.py +++ b/hive/indexer/blocks.py @@ -219,9 +219,9 @@ class Blocks: # remove posts: core, tags, cache entries if post_ids: - DB.query("DELETE FROM hive_posts_cache WHERE post_id IN :ids", ids=post_ids) DB.query("DELETE FROM hive_post_tags WHERE post_id IN :ids", ids=post_ids) DB.query("DELETE FROM hive_posts WHERE id IN :ids", ids=post_ids) + DB.query("DELETE FROM hive_posts_data WHERE id IN :ids", ids=post_ids) DB.query("DELETE FROM hive_payments WHERE block_num = :num", num=num) DB.query("DELETE FROM hive_blocks WHERE num = :num", num=num) diff --git a/hive/indexer/cached_post.py b/hive/indexer/cached_post.py index 21ce636b35359da8966cef8e5c0ab1c8da21e2aa..e0db3053b07f11ff50a42afdcbad045e1ff8c761 100644 --- a/hive/indexer/cached_post.py +++ b/hive/indexer/cached_post.py @@ -504,7 +504,6 @@ class CachedPost: ('json', json.dumps(basic['json_metadata'])), #('raw_json', json.dumps(legacy_data)), # TODO: check if writting fields below on every update is necessary! - ('legacy_id', legacy_data['id']), ('parent_author', legacy_data['parent_author']), ('parent_permlink', legacy_data['parent_permlink']), ('curator_payout_value', legacy_data['curator_payout_value']), diff --git a/hive/indexer/community.py b/hive/indexer/community.py index d57c5acad001a68c8074c319ca50c08cd613d797..51df8447568c87fdeafd1f79eab98b1c8d71846a 100644 --- a/hive/indexer/community.py +++ b/hive/indexer/community.py @@ -235,10 +235,11 @@ class Community: SELECT community_id, COUNT(*) posts, ROUND(SUM(payout)) payouts, - COUNT(DISTINCT author) authors - FROM hive_posts_cache + COUNT(DISTINCT author_id) authors + FROM hive_posts WHERE community_id IS NOT NULL AND is_paidout = '0' + AND is_deleted = '0' GROUP BY community_id ) p ON community_id = id diff --git a/hive/indexer/posts.py b/hive/indexer/posts.py index 9a72cd2433dfd7803db45a84480a4f9ece265b7a..3917217a1e3e291d6c8ee60b8f92cb592eae99f6 100644 --- a/hive/indexer/posts.py +++ b/hive/indexer/posts.py @@ -40,8 +40,13 @@ class Posts: cls._ids[url] = _id else: cls._miss += 1 - sql = """SELECT id FROM hive_posts WHERE - author = :a AND permlink = :p""" + sql = """ + SELECT id + FROM hive_posts hp + LEFT JOIN hive_accounts ha_a ON ha_a.id = hp.author_id + LEFT JOIN hive_permlink_data hpd_p ON hpd_p.id = hp.permlink_id + WHERE ha_a.name = :a AND hpd_p.permlink = :p + """ _id = DB.query_one(sql, a=author, p=permlink) if _id: cls._set_id(url, _id) @@ -112,10 +117,11 @@ class Posts: @classmethod def insert(cls, op, date): """Inserts new post records.""" - sql = """INSERT INTO hive_posts (is_valid, is_muted, parent_id, author, - permlink, category, community_id, depth, created_at) - VALUES (:is_valid, :is_muted, :parent_id, :author, - :permlink, :category, :community_id, :depth, :date)""" + # TODO check if category and permlink exists + sql = """INSERT INTO hive_posts (is_valid, is_muted, parent_id, author_id, + permlink_id, category_id, community_id, depth, created_at) + VALUES (:is_valid, :is_muted, :parent_id, (SELECT id FROM hive_accounts WHERE name = :author), + (SELECT id FROM hive_permlink_data WHERE permlink = :permlink), (SELECT :category), :community_id, :depth, :date)""" sql += ";SELECT currval(pg_get_serial_sequence('hive_posts','id'))" post = cls._build_post(op, date) result = DB.query(sql, **post) diff --git a/hive/server/bridge_api/cursor.py b/hive/server/bridge_api/cursor.py index 8d9477468a877d142a817fd93c6708710e7c80a9..928bfbc89ee215a2185f7b19a8e47cd405d675a7 100644 --- a/hive/server/bridge_api/cursor.py +++ b/hive/server/bridge_api/cursor.py @@ -104,7 +104,7 @@ async def pids_by_community(db, ids, sort, seek_id, limit): # setup field, pending, toponly, gray, promoted = definitions[sort] - table = 'hive_posts_cache' + table = 'hive_posts' where = ["community_id IN :ids"] if ids else ["community_id IS NOT NULL AND community_id != 1337319"] # select @@ -117,8 +117,8 @@ async def pids_by_community(db, ids, sort, seek_id, limit): # seek if seek_id: - sval = "(SELECT %s FROM %s WHERE post_id = :seek_id)" % (field, table) - sql = """((%s < %s) OR (%s = %s AND post_id > :seek_id))""" + sval = "(SELECT %s FROM %s WHERE id = :seek_id)" % (field, table) + sql = """((%s < %s) OR (%s = %s AND id > :seek_id))""" where.append(sql % (field, sval, field, sval)) # simpler `%s <= %s` eval has edge case: many posts with payout 0 @@ -129,8 +129,8 @@ async def pids_by_community(db, ids, sort, seek_id, limit): #where.append(sql % (field, sval, field, sval)) # build - sql = ("""SELECT post_id FROM %s WHERE %s - ORDER BY %s DESC, post_id LIMIT :limit + sql = ("""SELECT id FROM %s WHERE %s + ORDER BY %s DESC, id LIMIT :limit """ % (table, ' AND '.join(where), field)) # execute @@ -157,7 +157,7 @@ async def pids_by_category(db, tag, sort, last_id, limit): 'muted': ('payout', True, False, False, False), }[sort] - table = 'hive_posts_cache' + table = 'hive_post' field = params[0] where = [] @@ -172,17 +172,17 @@ async def pids_by_category(db, tag, sort, last_id, limit): # filter by category or tag if tag: if sort in ['payout', 'payout_comments']: - where.append('category = :tag') + where.append('category_id = (SELECT id FROM hive_category_data WHERE category = :tag)') else: sql = "SELECT post_id FROM hive_post_tags WHERE tag = :tag" - where.append("post_id IN (%s)" % sql) + where.append("id IN (%s)" % sql) if last_id: - sval = "(SELECT %s FROM %s WHERE post_id = :last_id)" % (field, table) - sql = """((%s < %s) OR (%s = %s AND post_id > :last_id))""" + sval = "(SELECT %s FROM %s WHERE id = :last_id)" % (field, table) + sql = """((%s < %s) OR (%s = %s AND id > :last_id))""" where.append(sql % (field, sval, field, sval)) - sql = ("""SELECT post_id FROM %s WHERE %s + sql = ("""SELECT id FROM %s WHERE %s ORDER BY %s DESC, post_id LIMIT :limit """ % (table, ' AND '.join(where), field)) @@ -390,14 +390,14 @@ async def pids_by_payout(db, account: str, start_author: str = '', start_id = None if start_permlink: start_id = await _get_post_id(db, start_author, start_permlink) - last = "(SELECT payout FROM hive_posts_cache WHERE post_id = :start_id)" - seek = ("""AND (payout < %s OR (payout = %s AND post_id > :start_id))""" + last = "(SELECT payout FROM hive_posts WHERE id = :start_id)" + seek = ("""AND (payout < %s OR (payout = %s AND id > :start_id))""" % (last, last)) sql = """ - SELECT post_id - FROM hive_posts_cache - WHERE author = :account + SELECT id + FROM hive_posts + WHERE author_id = (SELECT id FROM hive_accounts WHERE name = :account) AND is_paidout = '0' %s ORDER BY payout DESC, post_id LIMIT :limit diff --git a/hive/server/bridge_api/objects.py b/hive/server/bridge_api/objects.py index 64b845f93658ef9877ecee593c8a198f9f82d38e..956589340271dcf74c0cfad7f7b919963d197121 100644 --- a/hive/server/bridge_api/objects.py +++ b/hive/server/bridge_api/objects.py @@ -43,14 +43,53 @@ async def load_posts_keyed(db, ids, truncate_body=0): assert ids, 'no ids passed to load_posts_keyed' # fetch posts and associated author reps - 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 post_id IN :ids""" + sql = """ + SELECT hp.id, + community_id, + ha_a.name as author, + hpd_p.permlink as permlink, + hpd.title as title, + hpd.body as body, + hcd.category as category, + depth, + promoted, + payout, + payout_at, + is_paidout, + children, + hpd.votes as votes, + hp.created_at, + updated_at, + rshares, + hpd.json as json, + is_hidden, + is_grayed, + total_votes, + flag_weight, + ha_pa.name as parent_author, + hpd_pp.permlink as parent_permlink, + curator_payout_value, + ha_ra.name as root_author, + hpd_rp.permlink as root_permlink, + max_accepted_payout, + percent_steem_dollars, + allow_replies, + allow_votes, + allow_curation_rewards, + beneficiaries, + url, + root_title + FROM hive_posts hp + LEFT JOIN hive_accounts ha_a ON ha_a.id = hp.author_id + LEFT JOIN hive_permlink_data hpd_p ON hpd_p.id = hp.permlink_id + LEFT JOIN hive_post_data hpd ON hpd.id = hp.id + LEFT JOIN hive_category_data hcd ON hcd.id = hp.category_id + LEFT JOIN hive_accounts ha_pa ON ha_pa.id = hp.parent_author_id + LEFT JOIN hive_permlink_data hpd_pp ON hpd_pp.id = hp.parent_permlink_id + LEFT JOIN hive_accounts ha_ra ON ha_ra.id = hp.root_author_id + LEFT JOIN hive_permlink_data hpd_rp ON hpd_rp.id = hp.root_permlink_id + WHERE id IN :ids + """ result = await db.query_all(sql, ids=tuple(ids)) author_map = await _query_author_map(db, result) @@ -178,7 +217,7 @@ def _condenser_profile_object(row): }}} def _condenser_post_object(row, truncate_body=0): - """Given a hive_posts_cache row, create a legacy-style post object.""" + """Given a hive_posts row, create a legacy-style post object.""" paid = row['is_paidout'] # condenser#3424 mitigation @@ -186,7 +225,7 @@ def _condenser_post_object(row, truncate_body=0): row['category'] = 'undefined' post = {} - post['post_id'] = row['post_id'] + post['post_id'] = row['id'] post['author'] = row['author'] post['permlink'] = row['permlink'] post['category'] = row['category'] @@ -222,8 +261,6 @@ def _condenser_post_object(row, truncate_body=0): #post['author_reputation'] = rep_to_raw(row['author_rep']) - post['legacy_id'] = row['legacy_id'] - post['root_author'] = row['root_author'] post['root_permlink'] = row['root_permlink'] diff --git a/hive/server/common/objects.py b/hive/server/common/objects.py index 1e731d960d6f2520247bf56c4325e6b6a37d01e2..f2497a6c3162e574bb7d5e9be4fbc6e5fd937419 100644 --- a/hive/server/common/objects.py +++ b/hive/server/common/objects.py @@ -28,7 +28,7 @@ async def query_author_map(db, posts): return {r['name']: r for r in await db.query_all(sql, names=names)} def condenser_post_object(row, truncate_body=0): - """Given a hive_posts_cache row, create a legacy-style post object.""" + """Given a hive_posts row, create a legacy-style post object.""" paid = row['is_paidout'] # condenser#3424 mitigation @@ -36,7 +36,7 @@ def condenser_post_object(row, truncate_body=0): row['category'] = 'undefined' post = {} - post['post_id'] = row['post_id'] + post['post_id'] = row['id'] post['author'] = row['author'] post['permlink'] = row['permlink'] post['category'] = row['category'] @@ -63,8 +63,6 @@ def condenser_post_object(row, truncate_body=0): post['active_votes'] = _hydrate_active_votes(row['votes']) #post['author_reputation'] = rep_to_raw(row['author_rep']) - post['legacy_id'] = row['legacy_id'] - post['root_author'] = row['root_author'] post['root_permlink'] = row['root_permlink'] diff --git a/hive/server/condenser_api/cursor.py b/hive/server/condenser_api/cursor.py index 04d65b4527e735e49357af82b89ac0e2b8baa4f8..633113383b2c307e686708b250220e688cab591e 100644 --- a/hive/server/condenser_api/cursor.py +++ b/hive/server/condenser_api/cursor.py @@ -141,7 +141,7 @@ async def pids_by_query(db, sort, start_author, start_permlink, limit, tag): 'payout_comments': ('payout', True, False, True, False), }[sort] - table = 'hive_posts_cache' + table = 'hive_posts' field = params[0] where = [] @@ -157,29 +157,67 @@ async def pids_by_query(db, sort, start_author, start_permlink, limit, tag): # cid = get_community_id(tag) # where.append('community_id = :cid') if sort in ['payout', 'payout_comments']: - where.append('category = :tag') + where.append('category_id = (SELECT id FROM hive_category_data WHERE category = :tag)') else: if tag[:5] == 'hive-': - where.append('category = :tag') + where.append('category_id = (SELECT id FROM hive_category_data WHERE category = :tag)') if sort in ('trending', 'hot'): where.append('depth = 0') sql = "SELECT post_id FROM hive_post_tags WHERE tag = :tag" - where.append("post_id IN (%s)" % sql) + where.append("id IN (%s)" % sql) start_id = None if start_permlink and start_author: - sql = "%s <= (SELECT %s FROM %s WHERE post_id = (SELECT post_id FROM hive_posts_cache WHERE author = :start_author AND permlink= :start_permlink))" + sql = "%s <= (SELECT %s FROM %s WHERE id = (SELECT id FROM hive_posts WHERE author_id = (SELECT id FROM hive_accounts WHERE name = :start_author) AND permlink_id = (SELECT id FROM hive_permlink_data WHERE permlink = :start_permlink)))" where.append(sql % (field, field, table)) - columns = ['hive_posts_cache.post_id', 'hive_posts_cache.author', 'hive_posts_cache.permlink', - 'hive_posts_cache.title', 'hive_posts_cache.body', 'hive_posts_cache.category', - 'hive_posts_cache.depth', 'hive_posts_cache.promoted', - 'hive_posts_cache.payout', 'hive_posts_cache.payout_at', 'hive_posts_cache.is_paidout', - 'hive_posts_cache.children', 'hive_posts_cache.votes', 'hive_posts_cache.created_at', - 'hive_posts_cache.updated_at', 'hive_posts_cache.rshares', 'hive_posts_cache.raw_json', - 'hive_posts_cache.json'] - sql = ("SELECT %s FROM %s WHERE %s ORDER BY %s DESC LIMIT :limit" - % (', '.join(columns), table, ' AND '.join(where), field)) + sql = """ + SELECT hp.id, + community_id, + ha_a.name as author, + hpd_p.permlink as permlink, + hpd.title as title, + hpd.body as body, + hcd.category as category, + depth, + promoted, + payout, + payout_at, + is_paidout, + children, + hpd.votes as votes, + hp.created_at, + updated_at, + rshares, + hpd.json as json, + is_hidden, + is_grayed, + total_votes, + flag_weight, + ha_pa.name as parent_author, + hpd_pp.permlink as parent_permlink, + curator_payout_value, + ha_ra.name as root_author, + hpd_rp.permlink as root_permlink, + max_accepted_payout, + percent_steem_dollars, + allow_replies, + allow_votes, + allow_curation_rewards, + beneficiaries, + url, + root_title + FROM hive_posts hp + LEFT JOIN hive_accounts ha_a ON ha_a.id = hp.author_id + LEFT JOIN hive_permlink_data hpd_p ON hpd_p.id = hp.permlink_id + LEFT JOIN hive_post_data hpd ON hpd.id = hp.id + LEFT JOIN hive_category_data hcd ON hcd.id = hp.category_id + LEFT JOIN hive_accounts ha_pa ON ha_pa.id = hp.parent_author_id + LEFT JOIN hive_permlink_data hpd_pp ON hpd_pp.id = hp.parent_permlink_id + LEFT JOIN hive_accounts ha_ra ON ha_ra.id = hp.root_author_id + LEFT JOIN hive_permlink_data hpd_rp ON hpd_rp.id = hp.root_permlink_id + WHERE %s ORDER BY %s DESC LIMIT :limit + """ % (' AND '.join(where), field) #return await db.query_col(sql, tag=tag, start_id=start_id, limit=limit) return [sql, tag, start_id, limit] diff --git a/hive/server/condenser_api/methods.py b/hive/server/condenser_api/methods.py index be188cbd7f4f3f1b543219665825666e34efad37..e6831f6638d9acd95b134da97e192b562b9a1693 100644 --- a/hive/server/condenser_api/methods.py +++ b/hive/server/condenser_api/methods.py @@ -19,7 +19,53 @@ from hive.server.common.mutes import Mutes # pylint: disable=too-many-arguments,line-too-long,too-many-lines -# Dummy +SQL_TEMPLATE = """ + SELECT hp.id, + community_id, + ha_a.name as author, + hpd_p.permlink as permlink, + hpd.title as title, + hpd.body as body, + hcd.category as category, + depth, + promoted, + payout, + payout_at, + is_paidout, + children, + hpd.votes as votes, + hp.created_at, + updated_at, + rshares, + hpd.json as json, + is_hidden, + is_grayed, + total_votes, + flag_weight, + ha_pa.name as parent_author, + hpd_pp.permlink as parent_permlink, + curator_payout_value, + ha_ra.name as root_author, + hpd_rp.permlink as root_permlink, + max_accepted_payout, + percent_steem_dollars, + allow_replies, + allow_votes, + allow_curation_rewards, + beneficiaries, + url, + root_title, + ha_a.reputation AS author_rep + FROM hive_posts hp + LEFT JOIN hive_accounts ha_a ON ha_a.id = hp.author_id + LEFT JOIN hive_permlink_data hpd_p ON hpd_p.id = hp.permlink_id + LEFT JOIN hive_post_data hpd ON hpd.id = hp.id + LEFT JOIN hive_category_data hcd ON hcd.id = hp.category_id + LEFT JOIN hive_accounts ha_pa ON ha_pa.id = hp.parent_author_id + LEFT JOIN hive_permlink_data hpd_pp ON hpd_pp.id = hp.parent_permlink_id + LEFT JOIN hive_accounts ha_ra ON ha_ra.id = hp.root_author_id + LEFT JOIN hive_permlink_data hpd_rp ON hpd_rp.id = hp.root_permlink_id +""" @return_error_info async def get_account_votes(context, account): @@ -104,18 +150,9 @@ async def get_content(context, author: str, permlink: str): valid_account(author) valid_permlink(permlink) - sql = """ - ---get_content - SELECT hive_posts_cache.post_id, hive_posts_cache.author, hive_posts_cache.permlink, - hive_posts_cache.title, hive_posts_cache.body, hive_posts_cache.category, hive_posts_cache.depth, - hive_posts_cache.promoted, hive_posts_cache.payout, hive_posts_cache.payout_at, - hive_posts_cache.is_paidout, hive_posts_cache.children, hive_posts_cache.votes, - hive_posts_cache.created_at, hive_posts_cache.updated_at, hive_posts_cache.rshares, - hive_posts_cache.raw_json, hive_posts_cache.json, hive_accounts.reputation AS author_rep - FROM hive_posts_cache JOIN hive_accounts ON (hive_posts_cache.author = hive_accounts.name) - JOIN hive_posts ON (hive_posts_cache.post_id = hive_posts.id) - WHERE hive_posts_cache.author = :author AND hive_posts_cache.permlink = :permlink AND NOT hive_posts.is_deleted - """ + #force copy + sql = str(SQL_TEMPLATE) + sql += """ WHERE ha_a.name = :author AND hpd_p.permlink = :permlink AND NOT hp.is_deleted """ result = await db.query_all(sql, author=author, permlink=permlink) result = dict(result[0]) @@ -125,14 +162,6 @@ async def get_content(context, author: str, permlink: str): assert post, 'post was not found in cache' return post - #post_id = await cursor.get_post_id(db, author, permlink) - #if not post_id: - # return {'id': 0, 'author': '', 'permlink': ''} - #posts = await load_posts(db, [post_id]) - #assert posts, 'post was not found in cache' - #return posts[0] - - @return_error_info async def get_content_replies(context, author: str, permlink: str): """Get a list of post objects based on parent.""" @@ -140,25 +169,24 @@ async def get_content_replies(context, author: str, permlink: str): valid_account(author) valid_permlink(permlink) - sql = """ - --get_content_replies - SELECT post_id, author, permlink, title, body, category, depth, - promoted, payout, payout_at, is_paidout, children, votes, - created_at, updated_at, rshares, json, - 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 post_id IN ( - SELECT hp2.id FROM hive_posts hp2 - WHERE hp2.is_deleted = '0' AND - hp2.parent_id = (SELECT id FROM hive_posts - WHERE author = :author - AND permlink = :permlink AND is_deleted = '0') - LIMIT :limit - ) - ORDER BY post_id""" - - result=await db.query_all(sql, author=author, permlink = permlink, limit=5000) + #force copy + sql = str(SQL_TEMPLATE) + sql += """ + WHERE + hp.is_deleted = '0' AND + hp.parent_id = ( + SELECT id + FROM hive_posts + WHERE + author_id = (SELECT id FROM hive_accounts WHERE name =:author) + AND permlink_id = (SELECT id FROM hive_permlink_data WHERE permlink = :permlink) + AND is_deleted = '0' + ) + LIMIT :limit + ORDER BY id + """ + + result = await db.query_all(sql, author=author, permlink=permlink, limit=5000) posts = await resultset_to_posts(db=db, resultset=result, truncate_body=0) return posts @@ -204,7 +232,7 @@ async def get_discussions_by(discussion_type, context, start_author: str = '', valid_permlink(start_permlink, allow_empty=True), valid_limit(limit, 100), valid_tag(tag, allow_empty=True)) - + assert len(query_information) == 4, 'generated query is malformed, aborting' sql = query_information[0] sql = "---get_discussions_by_" + discussion_type + "\r\n" + sql @@ -278,26 +306,19 @@ async def get_discussions_by_blog(context, tag: str = None, start_author: str = valid_permlink(start_permlink, allow_empty=True) valid_limit(limit, 100) - sql = """ - ---get_discussions_by_blog - SELECT hive_posts_cache.post_id, hive_posts_cache.author, hive_posts_cache.permlink, - hive_posts_cache.title, hive_posts_cache.body, hive_posts_cache.category, hive_posts_cache.depth, - hive_posts_cache.promoted, hive_posts_cache.payout, hive_posts_cache.payout_at, - hive_posts_cache.is_paidout, hive_posts_cache.children, hive_posts_cache.votes, - hive_posts_cache.created_at, hive_posts_cache.updated_at, hive_posts_cache.rshares, - hive_posts_cache.raw_json, hive_posts_cache.json, hive_accounts.reputation AS author_rep - FROM hive_posts_cache JOIN hive_accounts ON (hive_posts_cache.author = hive_accounts.name) - JOIN hive_posts ON (hive_posts_cache.post_id = hive_posts.id) - WHERE NOT hive_posts.is_deleted AND hive_posts_cache.post_id IN + #force copy + sql = str(SQL_TEMPLATE) + sql += """ + WHERE NOT hp.is_deleted AND hp.id IN (SELECT post_id FROM hive_feed_cache JOIN hive_accounts ON (hive_feed_cache.account_id = hive_accounts.id) WHERE hive_accounts.name = :author) """ if start_author and start_permlink != '': sql += """ - AND hive_posts_cache.created_at <= (SELECT created_at from hive_posts_cache where author = :start_author AND permlink = :start_permlink) + AND hp.created_at <= (SELECT created_at from hive_posts WHERE author_id = (SELECT id FROM hive_accounts WHERE name = :start_author) AND permlink_id = (SELECT id FROM hive_permlink_data WHERE permlink = :start_permlink)) """ sql += """ - ORDER BY hive_posts_cache.created_at DESC + ORDER BY hp.created_at DESC LIMIT :limit """ @@ -310,7 +331,7 @@ async def get_discussions_by_blog(context, tag: str = None, start_author: str = post = _condenser_post_object(row, truncate_body=truncate_body) post['active_votes'] = _mute_votes(post['active_votes'], Mutes.all()) #posts_by_id[row['post_id']] = post - posts_by_id.append(post); + posts_by_id.append(post) return posts_by_id @@ -330,18 +351,6 @@ async def get_discussions_by_feed(context, tag: str = None, start_author: str = valid_limit(limit, 100)) return await load_posts_reblogs(context['db'], res, truncate_body=truncate_body) - #valid_account(start_author, allow_empty=True) - #valid_account(tag) - #valid_permlink(start_permlink, allow_empty=True) - #valid_limit(limit, 100) - - #sql = """ - # - #""" - - #if start_permlink and start_author: - - @return_error_info @nested_query_compat @@ -355,28 +364,20 @@ async def get_discussions_by_comments(context, start_author: str = None, start_p valid_permlink(start_permlink, allow_empty=True) valid_limit(limit, 100) - sql = """ - ---get_discussions_by_comments - SELECT hive_posts_cache.post_id, hive_posts_cache.author, hive_posts_cache.permlink, - hive_posts_cache.title, hive_posts_cache.body, hive_posts_cache.category, hive_posts_cache.depth, - hive_posts_cache.promoted, hive_posts_cache.payout, hive_posts_cache.payout_at, - hive_posts_cache.is_paidout, hive_posts_cache.children, hive_posts_cache.votes, - hive_posts_cache.created_at, hive_posts_cache.updated_at, hive_posts_cache.rshares, - hive_posts_cache.raw_json, hive_posts_cache.json, hive_accounts.reputation AS author_rep - FROM hive_posts_cache JOIN hive_accounts ON (hive_posts_cache.author = hive_accounts.name) - JOIN hive_posts ON (hive_posts_cache.post_id = hive_posts.id) - WHERE hive_posts_cache.author = :start_author AND hive_posts_cache.depth > 0 - AND NOT hive_posts.is_deleted + #force copy + sql = str(SQL_TEMPLATE) + sql += """ + WHERE ha_a.author = :start_author AND hp.depth > 0 + AND NOT hp.is_deleted """ if start_permlink: sql += """ - AND hive_posts_cache.post_id <= (SELECT hive_posts_cache.post_id FROM - hive_posts_cache WHERE permlink = :start_permlink AND author=:start_author) + AND hp.id <= (SELECT hive_posts.id FROM hive_posts WHERE author_id = (SELECT id FROM hive_accounts WHERE name = :start_author) AND permlink_id = (SELECT id FROM hive_permlink_data WHERE permlink = :start_permlink)) """ sql += """ - ORDER BY hive_posts_cache.post_id DESC, depth LIMIT :limit + ORDER BY hp.id DESC, depth LIMIT :limit """ posts = [] @@ -398,21 +399,6 @@ async def get_replies_by_last_update(context, start_author: str = None, start_pe limit: int = 20, truncate_body: int = 0): """Get all replies made to any of author's posts.""" assert start_author, '`start_author` cannot be blank' - #valid_account(start_author) - #valid_permlink(start_permlink, allow_empty=True) - #valid_limit(limit, 100) - - #sql = """ - # SELECT hive_posts_cache.post_id, hive_posts_cache.author, hive_posts_cache.permlink, - # hive_posts_cache.title, hive_posts_cache.body, hive_posts_cache.category, hive_posts_cache.depth, - # hive_posts_cache.promoted, hive_posts_cache.payout, hive_posts_cache.payout_at, - # hive_posts_cache.is_paidout, hive_posts_cache.children, hive_posts_cache.votes, - # hive_posts_cache.created_at, hive_posts_cache.updated_at, hive_posts_cache.rshares, - # hive_posts_cache.raw_json, hive_posts_cache.json, hive_accounts.reputation AS author_rep - # FROM hive_posts_cache JOIN hive_accounts ON (hive_posts_cache.author = hive_accounts.name) - # JOIN hive_posts ON (hive_posts_cache.post_id = hive_posts.id) - # - #""" ids = await cursor.pids_by_replies_to_account( context['db'], diff --git a/hive/server/condenser_api/objects.py b/hive/server/condenser_api/objects.py index 71148d3c59bad168150b7e464d1e06fe95a7dc81..30c216ab949f19e17ce8be2e33cdf24c7457b06b 100644 --- a/hive/server/condenser_api/objects.py +++ b/hive/server/condenser_api/objects.py @@ -40,13 +40,53 @@ async def load_posts_keyed(db, ids, truncate_body=0): assert ids, 'no ids passed to load_posts_keyed' # fetch posts and associated author reps - sql = """SELECT post_id, author, permlink, title, body, category, depth, - promoted, payout, payout_at, is_paidout, children, votes, - created_at, updated_at, rshares, json, - 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 post_id IN :ids""" + sql = """ + SELECT hp.id, + community_id, + ha_a.name as author, + hpd_p.permlink as permlink, + hpd.title as title, + hpd.body as body, + hcd.category as category, + depth, + promoted, + payout, + payout_at, + is_paidout, + children, + hpd.votes as votes, + hp.created_at, + updated_at, + rshares, + hpd.json as json, + is_hidden, + is_grayed, + total_votes, + flag_weight, + ha_pa.name as parent_author, + hpd_pp.permlink as parent_permlink, + curator_payout_value, + ha_ra.name as root_author, + hpd_rp.permlink as root_permlink, + max_accepted_payout, + percent_steem_dollars, + allow_replies, + allow_votes, + allow_curation_rewards, + beneficiaries, + url, + root_title, + FROM hive_posts hp + LEFT JOIN hive_accounts ha_a ON ha_a.id = hp.author_id + LEFT JOIN hive_permlink_data hpd_p ON hpd_p.id = hp.permlink_id + LEFT JOIN hive_post_data hpd ON hpd.id = hp.id + LEFT JOIN hive_category_data hcd ON hcd.id = hp.category_id + LEFT JOIN hive_accounts ha_pa ON ha_pa.id = hp.parent_author_id + LEFT JOIN hive_permlink_data hpd_pp ON hpd_pp.id = hp.parent_permlink_id + LEFT JOIN hive_accounts ha_ra ON ha_ra.id = hp.root_author_id + LEFT JOIN hive_permlink_data hpd_rp ON hpd_rp.id = hp.root_permlink_id + WHERE post_id IN :ids""" + result = await db.query_all(sql, ids=tuple(ids)) author_reps = await _query_author_rep_map(db, result) @@ -57,7 +97,7 @@ async def load_posts_keyed(db, ids, truncate_body=0): row['author_rep'] = author_reps[row['author']] post = _condenser_post_object(row, truncate_body=truncate_body) post['active_votes'] = _mute_votes(post['active_votes'], muted_accounts) - posts_by_id[row['post_id']] = post + posts_by_id[row['id']] = post return posts_by_id @@ -132,7 +172,7 @@ def _condenser_account_object(row): }})} def _condenser_post_object(row, truncate_body=0): - """Given a hive_posts_cache row, create a legacy-style post object.""" + """Given a hive_posts row, create a legacy-style post object.""" paid = row['is_paidout'] # condenser#3424 mitigation @@ -140,7 +180,7 @@ def _condenser_post_object(row, truncate_body=0): row['category'] = 'undefined' post = {} - post['post_id'] = row['post_id'] + post['post_id'] = row['id'] post['author'] = row['author'] post['permlink'] = row['permlink'] post['category'] = row['category'] @@ -167,8 +207,6 @@ def _condenser_post_object(row, truncate_body=0): post['active_votes'] = _hydrate_active_votes(row['votes']) post['author_reputation'] = rep_to_raw(row['author_rep']) - post['legacy_id'] = row['legacy_id'] - post['root_author'] = row['root_author'] post['root_permlink'] = row['root_permlink'] diff --git a/hive/server/condenser_api/tags.py b/hive/server/condenser_api/tags.py index 9a4f5b5b3384a5dd004940dfbddcc163cbc0d5fe..7cb83f44b0514aeb10e85e6659db43a13795be80 100644 --- a/hive/server/condenser_api/tags.py +++ b/hive/server/condenser_api/tags.py @@ -11,7 +11,7 @@ async def get_top_trending_tags_summary(context): #return [tag['name'] for tag in await get_trending_tags('', 50)] sql = """ SELECT category - FROM hive_posts_cache + FROM hive_posts WHERE is_paidout = '0' GROUP BY category ORDER BY SUM(payout) DESC @@ -31,7 +31,7 @@ async def get_trending_tags(context, start_tag: str = '', limit: int = 250): seek = """ HAVING SUM(payout) <= ( SELECT SUM(payout) - FROM hive_posts_cache + FROM hive_posts WHERE is_paidout = '0' AND category = :start_tag) """ @@ -43,7 +43,7 @@ async def get_trending_tags(context, start_tag: str = '', limit: int = 250): COUNT(*) AS total_posts, SUM(CASE WHEN depth = 0 THEN 1 ELSE 0 END) AS top_posts, SUM(payout) AS total_payouts - FROM hive_posts_cache + FROM hive_posts WHERE is_paidout = '0' GROUP BY category %s ORDER BY SUM(payout) DESC diff --git a/hive/server/database_api/methods.py b/hive/server/database_api/methods.py index 4142ec1b196c741f39d6e49a50fcd2b09bb2370d..f47e8b2d39267850ca1a0a1ff544e09723348169 100644 --- a/hive/server/database_api/methods.py +++ b/hive/server/database_api/methods.py @@ -2,11 +2,69 @@ from hive.server.common.helpers import return_error_info, valid_limit from hive.server.common.objects import condenser_post_object +SQL_TEMPLATE = """ + SELECT hp.id, + community_id, + ha_a.name as author, + hpd_p.permlink as permlink, + hpd.title as title, + hpd.body as body, + hcd.category as category, + depth, + promoted, + payout, + payout_at, + is_paidout, + children, + hpd.votes as votes, + hp.created_at, + updated_at, + rshares, + hpd.json as json, + is_hidden, + is_grayed, + total_votes, + flag_weight, + ha_pa.name as parent_author, + hpd_pp.permlink as parent_permlink, + curator_payout_value, + ha_ra.name as root_author, + hpd_rp.permlink as root_permlink, + max_accepted_payout, + percent_steem_dollars, + allow_replies, + allow_votes, + allow_curation_rewards, + beneficiaries, + url, + root_title + FROM hive_posts hp + LEFT JOIN hive_accounts ha_a ON ha_a.id = hp.author_id + LEFT JOIN hive_permlink_data hpd_p ON hpd_p.id = hp.permlink_id + LEFT JOIN hive_post_data hpd ON hpd.id = hp.id + LEFT JOIN hive_category_data hcd ON hcd.id = hp.category_id + LEFT JOIN hive_accounts ha_pa ON ha_pa.id = hp.parent_author_id + LEFT JOIN hive_permlink_data hpd_pp ON hpd_pp.id = hp.parent_permlink_id + LEFT JOIN hive_accounts ha_ra ON ha_ra.id = hp.root_author_id + LEFT JOIN hive_permlink_data hpd_rp ON hpd_rp.id = hp.root_permlink_id + WHERE +""" + 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""" + sql = """ + SELECT hp.id + FROM hive_posts hp + LEFT JOIN hive_accounts ha_a ON ha_a.id = hp.author_id + LEFT JOIN hive_permlink_data hpd_p ON hpd_p.id = hp.permlink_id + WHERE ha_a.name >= :author AND hpd_p.permlink >= :permlink + ORDER BY ha_a.name ASC + LIMIT :limit + """ result = await db.query_row(sql, author=author, permlink=permlink, limit=limit) - return result.post_id + if result is not None: + return int(result.get('post_id', 0)) + return 0 @return_error_info async def list_comments(context, start: list, limit: int, order: str): @@ -27,56 +85,38 @@ async def list_comments(context, start: list, limit: int, order: str): 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, beneficiaries, 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""" + sql = str(SQL_TEMPLATE) + sql += "hp.payout_at >= :start AND hp.id >= :post_id ORDER BY hp.payout_at ASC, hp.id ASC LIMIT :limit" + 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" - 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, beneficiaries, url, root_title - FROM hive_posts_cache WHERE author >= :author AND permlink >= :permlink ORDER BY author ASC, permlink ASC LIMIT :limit""" + sql = str(SQL_TEMPLATE) + sql += 'ha_a.name >= :author COLLATE "C" AND hpd_p.permlink >= :permlink COLLATE "C" ORDER BY ha_a.name COLLATE "C" ASC 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" + raise NotImplementedError('by_root') + + sql = str(SQL_TEMPLATE) + sql += "get_rows_by_root(:root_author, :root_permlink, :child_author, :child_permlink) ORDER BY post_id ASC LIMIT :limit" - 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, beneficiaries, 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=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" + raise NotImplementedError('by_parent') + + sql = str(SQL_TEMPLATE) + sql += "get_rows_by_parent(:parent_author, :parent_permlink, :child_author, :child_permlink) LIMIT :limit" - 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, beneficiaries, 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))) @@ -90,14 +130,9 @@ async def list_comments(context, start: list, limit: int, order: str): 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, - 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, beneficiaries, url, root_title - 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""" + sql = str(SQL_TEMPLATE) + sql += "ha_pa.name >= :parent_author AND hp.updated_at >= :updated_at AND hp.id >= :post_id ORDER BY ha_pa.name ASC, updated_at ASC, hp.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))) @@ -112,16 +147,35 @@ async def list_comments(context, start: list, limit: int, order: str): 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, beneficiaries, 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""" + sql = str(SQL_TEMPLATE) + sql += "ha_a.name >= :author AND hp.updated_at >= :updated_at AND hp.id >= :post_id ORDER BY ha_a.name ASC, hp.updated_at ASC, hp.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 + +@return_error_info +async def find_comments(context, start: list, limit: int, order: str): + """ Search for comments: limit and order is ignored in hive code """ + comments = [] + + assert len(start) <= 1000, "Parameters count is greather than max allowed (1000)" + db = context['db'] + + # make a copy + sql = str(SQL_TEMPLATE) + + idx = 0 + for arg in start: + if idx > 0: + sql += " OR " + sql += "(ha_a.name = '{}' AND hpd_p.permlink = '{}')".format(arg[0], arg[1]) + idx += 1 + + result = await db.query_all(sql) + for row in result: + comments.append(condenser_post_object(dict(row))) + + return comments diff --git a/hive/server/hive_api/community.py b/hive/server/hive_api/community.py index 47963d1ce30661bd7e23a315713acfbed5aa497b..fa572de000d4773868331037f22b9e3179afd9c1 100644 --- a/hive/server/hive_api/community.py +++ b/hive/server/hive_api/community.py @@ -353,8 +353,16 @@ async def top_community_muted(context, community): async def _top_community_posts(db, community, limit=50): # TODO: muted equivalent - sql = """SELECT author, votes, payout FROM hive_posts_cache - WHERE category = :community AND is_paidout = '0' - AND post_id IN (SELECT id FROM hive_posts WHERE is_muted = '0') - ORDER BY payout DESC LIMIT :limit""" + sql = """ + SELECT ha_a.name as author, + hpd.votes as votes, + payout + FROM hive_posts hp + LEFT JOIN hive_accounts ha_a ON ha_a.id = hp.author_id + LEFT JOIN hive_post_data hpd ON hpd.id = hp.id + LEFT JOIN hive_category_data hcd ON hcd.id = hp.category_id + WHERE hcdcategory = :community AND is_paidout = '0' + AND post_id IN (SELECT id FROM hive_posts WHERE is_muted = '0') + ORDER BY payout DESC LIMIT :limit""" + return await db.query_all(sql, community=community, limit=limit) diff --git a/hive/server/hive_api/objects.py b/hive/server/hive_api/objects.py index c8c74a37ed8f28951d1f9243b31d60e90b893a2f..05dfe19de769ba67128c76f4ccd415b73021994e 100644 --- a/hive/server/hive_api/objects.py +++ b/hive/server/hive_api/objects.py @@ -68,10 +68,22 @@ async def comments_by_id(db, ids, observer=None): """Given an array of post ids, returns comment objects keyed by id.""" assert ids, 'no ids passed to comments_by_id' - sql = """SELECT post_id, author, permlink, body, depth, - payout, payout_at, is_paidout, created_at, updated_at, - rshares, is_hidden, is_grayed, votes - FROM hive_posts_cache WHERE post_id IN :ids""" #votes + sql = """SELECT hp.id, + (SELECT name FROM hive_accounts ha WHERE ha.id = hp.author_id) as author, + (SELECT permlink FROM hive_permlink_data hpd WHERE hpd.id = hp.permlink_id) as permlink, + (SELECT body FROM hive_post_data hpa WHERE hpa.id = hp.id) as body, + hp.depth, + hp.payout, + hp.payout_at, + hp.is_paidout, + hp.created_at, + hp.updated_at, + hp.rshares, + hp.is_hidden, + hp.is_grayed, + hp.votes + FROM hive_posts hp + WHERE hp.id IN :ids""" #votes result = await db.query_all(sql, ids=tuple(ids)) authors = set() @@ -79,7 +91,7 @@ async def comments_by_id(db, ids, observer=None): for row in result: top_votes, observer_vote = _top_votes(row, 5, observer) post = { - 'id': row['post_id'], + 'id': row['id'], 'author': row['author'], 'url': row['author'] + '/' + row['permlink'], 'depth': row['depth'], @@ -108,10 +120,23 @@ async def posts_by_id(db, ids, observer=None, lite=True): """Given a list of post ids, returns lite post objects in the same order.""" # pylint: disable=too-many-locals - sql = """SELECT post_id, author, permlink, title, img_url, payout, promoted, - created_at, payout_at, is_nsfw, rshares, votes, - is_muted, is_invalid, %s - FROM hive_posts_cache WHERE post_id IN :ids""" + sql = """SELECT hp.id, + author, + permlink, + title, + img_url, + hp.payout, + hp.promoted, + hp.created_at, + hp.payout_at, + hp.is_nsfw, + hp.rshares, + hp.votes, + hp.is_muted, + hp.is_invalid, + %s + FROM hive_posts hp + WHERE post_id IN :ids""" fields = ['preview'] if lite else ['body', 'updated_at', 'json'] sql = sql % (', '.join(fields)) diff --git a/hive/server/hive_api/thread.py b/hive/server/hive_api/thread.py index 27d98423528e2874e31e9c827ee013d99a155ee1..b3f03f7c96deb08faf22ea6e029b9adbfe28d391 100644 --- a/hive/server/hive_api/thread.py +++ b/hive/server/hive_api/thread.py @@ -29,7 +29,7 @@ async def fetch_more_children(context, root_id, last_sibling_id, sort='top', valid_limit(limit, 50), observer) -_SORTS = dict(hot='sc_hot', top='payout', new='post_id') +_SORTS = dict(hot='sc_hot', top='payout', new='id') async def _fetch_children(db, root_id, start_id, sort, limit, observer=None): """Fetch truncated children from tree.""" mutes = set() @@ -41,10 +41,10 @@ async def _fetch_children(db, root_id, start_id, sort, limit, observer=None): # find most relevant ids in subset seek = '' if start_id: - seek = """AND %s < (SELECT %s FROM hive_posts_cache - WHERE post_id = :start_id)""" % (field, field) - sql = """SELECT post_id FROM hive_posts_cache - WHERE post_id IN :ids %s ORDER BY %s DESC + seek = """AND %s < (SELECT %s FROM hive_posts + WHERE id = :start_id)""" % (field, field) + sql = """SELECT id FROM hive_posts + WHERE id IN :ids %s ORDER BY %s DESC LIMIT :limit""" % (seek, field) relevant_ids = await db.query_col(sql, ids=tuple(parent.keys()), start_id=start_id, limit=limit) diff --git a/hive/server/serve.py b/hive/server/serve.py index 873387dba2df1a3b9759d0d1242e10f783697474..9593dce1c9eacad0db9db9e0074ec6deab6f3229 100644 --- a/hive/server/serve.py +++ b/hive/server/serve.py @@ -140,7 +140,8 @@ def build_methods(): # database_api methods methods.add(**{ - 'database_api.list_comments' : database_api.list_comments + 'database_api.list_comments' : database_api.list_comments, + 'database_api.find_comments' : database_api.find_comments }) return methods diff --git a/hive/utils/post.py b/hive/utils/post.py index 9f299710f34a957d826f6ed2f8101cecc9023c68..8e4de28b7e2ea4db9a4fd938445cdd1b5d492761 100644 --- a/hive/utils/post.py +++ b/hive/utils/post.py @@ -60,7 +60,6 @@ def post_to_internal(post, post_id, level='insert', promoted=None): ('is_paidout', basic['is_paidout']), ('json', json.dumps(basic['json_metadata'])), #('raw_json', json.dumps(legacy_data)), - ('legacy_id', legacy_data['id']), ('parent_author', legacy_data['parent_author']), ('parent_permlink', legacy_data['parent_permlink']), ('curator_payout_value', legacy_data['curator_payout_value']), diff --git a/tests/manual_tests/list_comments_by_permlink.py b/tests/manual_tests/list_comments_by_permlink.py index a5ef3e3339c49b317af35cb243bf3c149d07c3d8..8822f581b0634803c3b234a65c896c34570d4c65 100644 --- a/tests/manual_tests/list_comments_by_permlink.py +++ b/tests/manual_tests/list_comments_by_permlink.py @@ -1,5 +1,5 @@ #!/usr/bin/python3 -from .test_base import run_test +from test_base import run_test if __name__ == '__main__': reference_hive_node_url = 'https://api.hive.blog' diff --git a/tests/server/test_server_database_api.py b/tests/server/test_server_database_api.py index 9e8c1691db94931b604106c2f8343463df189cea..3bcb65bd289ddff068464de1b95ef22383528f73 100644 --- a/tests/server/test_server_database_api.py +++ b/tests/server/test_server_database_api.py @@ -12,7 +12,7 @@ def test_list_comments_by_cashout_time(client): assert reference_data assert test_data assert len(reference_data) == len(test_data) - to_compare = keys = ['author','permlink'] + to_compare = ['author','permlink'] for idx in range(len(reference_data)): for key in to_compare: assert reference_data[idx][key] == test_data[idx][key] @@ -24,7 +24,7 @@ def test_list_comments_by_permlink(client): assert reference_data assert test_data assert len(reference_data) == len(test_data) - to_compare = keys = ['author','permlink'] + to_compare = ['author','permlink'] for idx in range(len(reference_data)): for key in to_compare: assert reference_data[idx][key] == test_data[idx][key] @@ -35,7 +35,7 @@ def test_list_comments_by_root(client): assert reference_data assert test_data assert len(reference_data) == len(test_data) - to_compare = keys = ['author','permlink','root_author','root_permlink'] + to_compare = ['author','permlink','root_author','root_permlink'] for idx in range(len(reference_data)): for key in to_compare: assert reference_data[idx][key] == test_data[idx][key] @@ -46,7 +46,7 @@ def test_list_comments_by_parent(client): assert reference_data assert test_data assert len(reference_data) == len(test_data) - to_compare = keys = ['author','permlink','parent_author','parent_permlink'] + to_compare = ['author','permlink','parent_author','parent_permlink'] for idx in range(len(reference_data)): for key in to_compare: assert reference_data[idx][key] == test_data[idx][key]